专栏首页漏斗社区代码审计| 从今天起,做一个精致的多米咖!

代码审计| 从今天起,做一个精致的多米咖!

0x00 背景

在看CNVD漏洞库的时候发现有师傅发了某cms前台SQL注入漏洞,通过查阅漏洞描述可知道存在问题的参数是cardpwd,便开始尝试对该版本的cms进行审计。 源码下载地址:https://pan.baidu.com/s/1jIMhDK6 漏洞来源地址:http://www.cnvd.org.cn/flaw/show/CNVD-2017-22079

0x01 审计过程

1.下载好源码后在本地部署,然后使用seay 源代码审计系统加载源码文件,查找关键字cardpwd得到如下信息,cardpwd参数是在member/mypay.php文件中以POST的方式接收使用的。

2.进入到member/mypay.php文件(26行和38行)在接收cardpwd参数的值之前还需要进行登录,并且满足$dm=='mypay'

3.继续跟进$dm并未发现变量被创建的位置,最后在/duomiphp/common.php(52行-55行)中发现接收了GET,POST以及COOKIE中的参数和值,并且创建相应的变量赋予接收到的值,此处可能还存在变量覆盖的问题,本文咱不讨论。

● 到这里我们知道需要访问这个功能需要满足两个条件: (1)注册并登录

(2)在GET,POST或COOKIE中提交dm=mypay

4.注册会员后访问站点的/member/mypay.php文件,http://127.0.0.1/dm132/member/mypay.php 简单输入1,2 进行请求,确定可以提交cardpwd参数。

5.继续阅读/member/mypay.php在43-63行之间是对cardkey,cardpwd的处理,并使用了正则[^0-9a-z@\._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@\.-]{1,} 对数据进行检测,分析并对这个正则进行测试,发现使用/*!50000 xxxx*/便可以绕过。

6.本以为过滤规则是如此简单,经过测试发现还有其他过滤规则,继续往下分析发现/member/mypay.php在63行要执行SQL语句的时候还使用了GetOne的函数,定位到这个函数所在的位置/doumiphp/sql.class.php的277-300行,GetOne大致做了以下的事情,先清理掉字符串最后面的,和;然后拼接上limit 0,1;使查询的结果只返回一行。

正如代码上面所注释的“//执行一个SQL语句,返回前一条记录或仅返回一条记录”

7.拼接后在/doumiphp/sql.class.php在288行执行了SetQuery方法,290行执行了Execute方法,跟进Execute方法,在234行-269行发现了Execute方法的代码块,其中CheckSql是一个关键名称的方法,并且在上方有注释说用于SQL安全检查。

8.跟进CheckSql在/doumiphp/sql.class.php的537行-642行发现CheckSql方法的代码块,上面有提示 //SQL语句过滤程序,由80sec提供,这里作了适当的修改,经过测试这个过滤规则在598行过滤了/*而且是用硬匹配的方法,所以无法绕过,因此第5步的 /*!50000 xxxx*/的payload无法使用。

9.联合查询无法使用的情况下就想到的子查询的方法,经过测试无法绕过628行过滤的正则~\([^)]*?select~s进行子查询,无括号的子查询貌似是不存在的吧~ ?! 此时此刻已经是对这个过滤规则研究了一整天,后面也请教了几位师傅,也没有好的方法进行无括号的子查询,其实官方文档上也说了子查询必须有括号。

10.当没有思路或测试进行不下去的时候,就一定要回头看看一路走来所获得的信息,往往有小惊喜遗留在路上 By Thinking!继续看CNVD中的描述,系统未对变量进行过滤 我突然觉得我下载的是假的源码!!

这个CMS在/member/mypay.php页面提交任意充值卡号,在卡号密码处使用’or’ 1可以实现任意充值,使用报错注入可以获取user() 或version()的数据,但是无法进行子查询。

● 先在后台添加了充值卡。

● 在前台注册并登录后,将cardpwd的值设置为’or’ 1提交,便可以任意充值了,虽然这算一个漏洞,但是在我的观念中这种漏洞不太能说服我。

11.使用灰盒方式先测试下/member/mypay.php的cardpwd参数

被/member/mypay.php在43-63行之间的正则过滤了。

被/doumiphp/sql.class.php的537行-642行的CheckSql方法过滤了。

未进行'的闭合导致SQL语句报错了。

12.到这里发现了一个小细节,多了一个'的导致SQL语句报错了?!,在报错信息中发现了插入的cardpwd的值,而不是先提示被过滤了,所以此处肯定有问题,经过测试是第2种情况。

根据这个现象可以推测两种可能: ❂SQL语句在被过滤前就执行了(×)

❂多了'导致注入语句被绕过(√)

0x02 确定问题位置

1.确定位我使用的方法是在关键位置使用echo 将传入的cardpwd数据在处理过程中打印出来,首先是在使用/*! 50000union */的情况下提示:Safe Alert: Request Error step 2! 找到这个关键字所在的位置,/doumiphp/sql.class.php的635行,刚好在CheckSql方法内。

2.在561-586行有个 //完整的SQL检查之前一直都在关注过滤规则,并没有在意这个代码块,因为这个CMS都是明文传输,密码处可能会有一些关键字符会触发SQL检测的规则,为了避免这种情况,开发人员便写了这个代码块,用于将SQL语句中两个单引号包裹的数据进行替换处理。

3.直接在589行处插入echo $clean;将经过这个代码块的数据打印出来,发现确实将单引号内的字符变成了$s$。

4.在640行处插入echo $db_string;将通过检测的数据打印出来。

开发人员为了避免类似密码处的关键字符被过滤,而设计的方法反而让过滤规则绕过成为了可能。 数据跟踪:cardpwd->$pwd->GetOne()->Execute()->CheckSql()->$clean->$db_string $clean->$db_string 的过程是先经过把数据进行处理(//完整的SQL检查)再赋给$clean,然后把$clean传到各种SQL注入检测规则中,全部通过后返回原始数$db_string,幸运的是在各种过滤规则中没有过滤 `,’,” 号。

因此仅需要利用//完整的SQL检查中的被单引号包裹的字符会被替换为$s$这个功能。

0x03 构造PAYLOAD

要利用单引号将字符包裹且不影响SQL语义,单引号就必需要被转义!

转义单引号的方法:

●SQL注释法:

1./*'*/

2./*!60000'*/

●反引号方法:

1.` ’ `

●双引号方法:

1." ' "

因此可以构造如下PAYLOAD:

利用双引号和反引号:

bypass’or”‘“or extractvalue(1,(select group_concat(0x3a,name,0x3a,password) from duomi_admin`’`))or ‘1

方便阅读将处理后的结果打印出来:

利用两个双引号:

bypass’or”‘“or extractvalue(1,(select group_concat(0x3a,name,0x3a,password) from duomi_admin))or “’”=

方便阅读将处理后的结果打印出来:

0x04 小小总结

其实这个漏洞整个思路还是很清晰对的审计起来也不困难,但是因为一开始将重点放在了过滤规则的绕过上面,导致花费太多精力在分析正则上,所以当过滤规则有些时候强绕绕不过,或许可以看下代码的其他上下文相关信息,这次的较为灵活的利用//完整的SQL检查绕过了全局的SQL安全检测,本篇绕过了全局的检测,凡是使用到了CheckSql()方法的位置都存在这个问题,最后感谢师傅们的各种协助和讨论。

本文分享自微信公众号 - 漏斗社区(newdooneSec),作者:Thinking

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-12-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 您有一份CTF代码审计文件等待查收

    0x01 背景 上周总结了一些文件包含与伪协议结合的利用方法,本周就找一道例题进行演练。题目源自国外某挑战平台,平台上还有许多其他有趣的challenges题目...

    漏斗社区
  • 代码审计|禅道7.3SQL注入复现

    上周的zentaopms漏洞复现你们觉得还OK吗? 斗哥想要的是一个肯定。 如果你们觉得意犹未尽, 本期将进入, 代码审计的小练习。 Zentaopms v7....

    漏斗社区
  • 除了小蜗牛,我蛙还带来了YUNUCMSv1.0.6

    ? 任意文件删除漏洞 0x00 相关环境 源码信息:YUNUCMSv1.0.6 问题文件: \YUNUCMSv1.0.6\statics\ueditor\p...

    漏斗社区
  • 为你的WordPress 主题添加结构化数据/丰富文本摘要,高亮搜索结果(下)

    为了方便写文章与读者阅读,特将本文分为上下两个部分。上一篇请点击这里查阅,这一篇接着上一篇来。特别提醒,要查看添加后的效果,可以使用谷歌的 结构化数据测试工具 ...

    Jeff
  • 关于CentOS6平台上PM2安装失败的解决方案

    因此,安装PM2失败的原因在于未满足环境依赖,即Node.js和npm版本较低,不满足安装PM2的基本要求;而安装Nodejs时,将会自动安装npm,因为我们只...

    用户1456517
  • 基于自然语言识别下的流失用户预警

    在电商运营过程中,会有大量的用户反馈留言,包括吐槽的差评,商品不满的地方等等,在用户运营生态中,这部分用户是最有可能流失也是最影响nps的人群,通过对其评价的语...

    用户1332428
  • 从 0 到 1 走进 Kaggle

    本文结构: kaggle 是什么 如何参赛 解决问题一般步骤 进一步: 如何探索数据 如何构造特征 提交结果 ---- kaggle 是什么? Kaggle ...

    杨熹
  • 从0到1走进 Kaggle

    用户1737318
  • 应用:基于自然语言识别下的流失用户预警

    update: 17.12.20 : 关于IDF处描述,经@余海跃同学提醒,细化了解释内容,感谢! 更新内容参见:基于自然语言识别下的流失用户预警

    sladesal
  • 苹果系统自带滑动返回功能

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

    用户1451823

扫码关注云+社区

领取腾讯云代金券