espcms代码审计(二次urldecode注入分析)

这里提到的漏洞是二次urldecode注入

这里用到的还是espcms,不过版本应该跟之前的有所不同,在网上找到的espcms源代码都是已经修补了这个漏洞的,我们对比分析吧

先放上漏洞位置代码,也就是interface/search.php里面的in_taglist()函数

贴上该函数部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function in_taglist() {
        parent::start_pagetemplate();
        include_once admin_ROOT . 'public/class_pagebotton.php';
  
        $page = $this->fun->accept('page', 'G');
        $page = isset($page) ? intval($page) : 1;
        $lng = (admin_LNG == 'big5') ? $this->CON['is_lancode'] : admin_LNG;
        $tagkey = urldecode($this->fun->accept('tagkey', 'R'));
  
        $db_where = ' WHERE lng=\'' . $lng . '\' AND isclass=1';
        if (empty($tagkey)) {
            $linkURL = $_SERVER['HTTP_REFERER'];
            $this->callmessage($this->lng['search_err'], $linkURL, $this->lng['gobackbotton']);
        }
        if (!empty($tagkey)) {
            $db_where.=" AND FIND_IN_SET('$tagkey',tags)";
        }

  可以看到,这里有一处:

1
$tagkey = urldecode($this->fun->accept('tagkey', 'R'));

  这里对于我们输入的tagkey参数进行了urldecode解码,但是当我们将参数提交到WebServer时,WebServer会自动解码一次,也就是我们在网址里面输入1%27的时候就会被解码成为1'

  但是在这里的代码处对于我们的输入又进行了一次urldecode,所以当我们输入1%25%27的时候,被WebServer自动解码成为了1%27,因为%25自动解码对应的就是%

  这样%27已经通过了防注入的函数,从而在urldecode之后成功解码变成了1'

  

1
2
3
if (!empty($tagkey)) {
            $db_where.=" AND FIND_IN_SET('$tagkey',tags)";
        }

  这里又可以看到,对于我们输入的$tagkey,如果判断其不为空了之后就拼接到SQL语句中,从而产生了注入

而我找到的该版本的espcms之后,发现应该是使用了升级包,原漏洞位置改为了

 

 即

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function in_taglist() {
        parent::start_pagetemplate();
        include_once admin_ROOT . 'public/class_pagebotton.php';
        $page = $this->fun->accept('page', 'G');
        $page = isset($page) ? intval($page) : 1;
        $lng = (admin_LNG == 'big5') ? $this->CON['is_lancode'] : admin_LNG;
        $tagkey = addslashes(urldecode($this->fun->accept('tagkey', 'R')));
        $tagkey = $this->fun->inputcodetrim($tagkey);
        $db_where = ' WHERE lng=\'' . $lng . '\' AND isclass=1';
        if (empty($tagkey)) {
            $this->callmessage($this->lng['search_err'], admin_URL, $this->lng['gobackbotton']);
        }
        if (!empty($tagkey)) {
            $db_where.=" AND FIND_IN_SET('$tagkey',tags)";
        }

  可以看到原来的urldecode位置外面多了一次addslashes函数进行sql注入的过滤,所以原来的方法就不再可行

二次urldecode注入在一些CTF赛题里面也会遇到,学习挖掘漏洞的思路。

 

参考链接:

https://k4ge.fun/2019/09/17/ESPCMS%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1/

https://gitee.com/luozong05/espcms?_from=gitee_search

https://blog.csdn.net/qq_35420342/article/details/79846432


__EOF__

本文作者春告鳥
本文链接https://www.cnblogs.com/Cl0ud/p/12358830.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   春告鳥  阅读(827)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示