这是 酒仙桥六号部队 的第 146 篇文章。
背景
本文是前段时间做过的测试,这次本文全篇使用本地搭建环境来复现,如有觉得不合理的地方,可能是本地复现的时候未完全还原真实环境,主要是记录当时在做这个渗透测试的思路以及踩过的坑。
常规找不到漏洞
打开网站,是一个商场交易系统,而且应该还是做外贸或者对国外的一个商场网站。
商场网站,如果不是多商家版的,那功能应该就只有首页、列表、详情、购物车、订单等,功能不会太多,既然如此,那就先不管程序漏洞了,先来扫一波,看看有哪些文件吧。
扫描出来后,发现robots.txt是空的,其他各类文件也没有什么有价值的信息,主要是比较关心的后台地址和一些备份文件什么的。既然从这方面并没有什么突破,在其他各个地方也进行了各种常规测试均未成功,这里就不复述了,但是在偶然看到该网站的版权信息后,那么思路就来了,代码审计有没有?
Semcms 3.9而且是PHP版本的,现在互联网上检索一下,有没有现成的漏洞可以利用。
通过各种搜索只能看到3.8版本存在漏洞,而3.9都没有检索到。
官网最新版本也才3.9,哎,看来只能自己动手进行代码审计了。
程序框架梳理
通过官网下载程序后在本地搭建运行,先看看程序目录。
该程序在安装完成后会自动删除install目录下的全部安装文件,并且会随机命名后台的地址,我这里后台地址就被改为了H7gTyz_Admin,这里也就解释了为啥刚刚扫目录的时候并没有发现后台路径,该CMS在安装的时候就避免了此类情况。先从入口处看起,先捋一下整个程序的运行程序,打开index.php
首先引入了一个web_inc.php的文件然后又引入了Function.php文件,最后引入了一个default.php文件,index.php文件里面就只有这三个文件引入,先看看web_inc.php文件内容是什么。
引入了db_conn.php和contorl.php文件,然后通过数据库查询,获取到的一些网站信息,例如:网站名称、网站的URL等等。db_conn.php文件应该是数据库连接文件,那么这个contorl.php文件是什么呢?继续追踪。
可以看到contorl.php文件里面都是一些定义好的方法,第一个就是防SQL注入的方法,而且这里的防止SQL注入只针对了$_GET,也就是说如果是POST请求则有可能并没有进行SQL注入,这里可以待会重点关注下。看完这个之后又看下Index.php文件引入的第二个文件Function.php。
Function.php文件也是一些方法定义,还有就是针对一些参数的过滤,比如GET请求的ID和page还有POST请求的search等,这里也可以关注下,看看是否可以绕过。接着回到index.php看下default.php文件内容。
Default.php文件应该就是一个前端页面,进行渲染用的,这里先不管了,可是看到这里整个CMS的入口已经看完了,但是并没有看到URL跳转是怎么处理的,只看到默认页的一个跳转,其他例如列表详情等并没有,结合线上环境查看下其他页面的URL。
看到列表页的URL是product.php,返回到网站根目录查看。
根目录下并没有product.php文件,但是根目录下有.htaccess文件,查看下该文件内容。
.htaccess文件将product.php文件给重定向到Templete目录下了,查看下。
该CMS采用的是前后端混编的方式编写的,所以HTML里面也有PHP代码,到这里就基本把整个CMS的架构逻辑捋明白了,接下来就是看可能存在漏洞的功能,进行代码分析。
失败的代码审计
由于前面再梳理程序架构的时候,看到防SQL注入处,仅是针对GET请求的数据进行了防护,而POST防护并没有,所以这里先看看整个程序哪里是使用的POST提交。通过查看搜索处是通过POST提交的数据,而且搜索处存在SQL注入的概率很大,所以先看下搜索处,是否存在SQL注入。
先抓包看下参数是如何传递的。
根据.htaccess文件定义的规则,文件直接被定为到了Templete\default\Include\search.php,查看该文件。
和index.php一样引入了web_inc.php和Function.php文件,web_inc.php文件网站基本信息的定义,而下面的$search这个变量应该就是Function.php里进行定义的,所以这里重点看Function.php文件。
根据刚才搜索的时候提交的代码情况,search参数是有提交的,这里就先代入verify_str进行了判断,根据前面的代码分析,这个应该是做参数过滤的,追踪查看。
针对select等特定的单词及符号进行了过滤,但是这里的参数过滤很明显不是很严谨,比如使用ascii码的方式就能绕过,返回查看test_input的内容。
先使用str_replace函数替换掉%符号,然后使用trim去掉两端多余的空格等,再使用stripslashes删除反斜杠,最后再使用htmlspecialchars给转为HTML实体,看到这里其实就感觉可能没多少成功的可能了,接着往下看,后面是如何过滤的。
将_给替换成了\_,%给替换成了\%,接着往下走回到search.php文件了。
追踪查看searchprolist方法,查看搜索处的查询方法。
先将搜索条件按照空格进行分割,然后拼装SQL语句,再直接代入到SQL语句中执行,也就说空格也是不能使用的。到目前为止可以发现,特定的单词和符号不能使用,所有的数据会被实体化输出,会被去反斜杠,%会被percent替换,前后两端的空格回车等会被清除,最后会用空格来进行SQL语句分割拼接,在此处测试良久依旧未能成功,如果有哪位大佬知道什么payload能绕过的,还请教教我啊。
再次审计找到SQL注入
虽然经历了上面的失败,但是现在我们对该CMS的架构也算是比较熟悉了,对接下来的渗透也应该有所帮助。刚刚在看到最后拼接SQL语句的时候发现有个languageID参数。
追踪看下这个参数是否可控。
根据反向追踪,可以看到,这个变量是从web_inc.php或者Function.php文件中定义的,追踪查看。
在web_inc.php文件中发现该参数是可以通过POST提交的,虽然也有过滤,但是远没有刚刚搜索处的复杂,而且在下面直接就代入数据库查询了。根据前面分析过滤函数,这里直接使用ascii的方式进行注入,payload如:1 and ascii(substr(database(),1,1))^115
当数据库第一位的ascii码等于115的时候,返回的title等内容就为空,以此方法就可以通过枚举出数据库信息。
长度短的这个就是正确的值了,以此方法就可以遍历读取到想要的数据库信息了,这里就不进行逐一演示了,最后拿到网站的账户密码。
没有Shell的渗透是不完整的
本来应该尝试使用SQL注入进行写入WebShell的,可是当做到这一步的时候,感觉比较麻烦,所以在拿到网站账户密码后,又开始对后台地址进行了拆解,没想到最后居然被猜到了,后台路径为admin_Admin。
这里大胆猜测下,是不是因为该CMS会随机生成后台管理路径,导致管理员也记不住,所以将路径给改成了admin_Admin了?感觉大概率是如此的。进入后台之后,先看看后台的样子。
进入后台之后看到有一个SQL执行,以为这里能直接执行SQL语句拿SHELL的,当满心欢喜点开后。
这是啥?没有任何执行SQL语句的地方,感觉就是一个恢复数据库的功能,这里也先不用管了,接着看上传。参数设置上有上传LOGO的地方,试试。
随意选择图片,点击submit后,抓包。
修改内容为一句话,文件名改为1.php。
提示请检查上传文件类型,查看源代码,看下这里究竟是如何进行的限制。
获取最后一个点之后的扩展名,然后进行白名单校验,这里通过各种截断上传、解析漏洞、寻找文件包含漏洞等方法,都未利用成功。最后因为一些别的原因就并未再针对该系统进行测试了,到此呢,通过代码审计拿到一个SQL注入,并且成功进入后台,只不过并没拿到WebShell,所以我把这次渗透称之为不完整的。
结语
本文主要是还是通过黑盒测试未发现明显问题后,就下载源代码进行审计,通过审计结果来构造Payload,因为有些程序会有一些过滤,所以常规直接的构造payload难度会大一些,如果能通过代码审计,这样构造payload也方便很多,速度上也会快一点,当然很可能是我太菜了,啥也不是。
如果你是一个长期主义者,欢迎加入我的知识星球,我们一起往前走,每日都会更新,精细化运营,微信识别二维码付费即可加入,如不满意,72 小时内可在 App 内无条件自助退款