关于齐博cms代码审计的思考
之前看到了齐博cms报错注入漏洞,就想是否可以使用同样的路径发现sql注入,在思考尝试中有了这篇文章,最终发现了sql注入,但版本仅限于4.1<mysql≤5,也就是说2008年mysql出现5.1后,这个洞就用不了了,比较鸡肋,但思考的过程值得记一下。
路径
之前的齐博cms报错注入使用了以下两个函数:
query函数中有这么一行:
可以让$query=False,然后执行报错语句,$showerr代码自己定义=1,那就不需要我们管了。
我首先查看了还有文件的调用路径包含这两个函数,结果在:/do/search.php 这里找到,为了调用其中的内容,我们可以写为:type=keyword&keyword=sql语句
开始调试
这是一个搜索页面,之前学习PHP代码审计的时候,师傅给的例子就是ESPCMS的搜索框sql注入,所以觉得存在sql注入的可能性挺大的。
现在开始构造注入语句:
1 |
|
发现我们传入的闭合’
单引号被注释了,发现是针对符号%的过滤:
1 |
|
发现我们注释符号--
后面的空格被吞掉了,那就在%20后面随意加个,改成:--%20p
上面调试过程中发现有这么一行:
那么我们就可以使用宽字节%df进行绕过(这里是个大坑,但此时还没意识到),进入到query函数发现我们成功让sql语句闭合:
1 |
|
把语句放到phpmyadmin中看看是否能返回我们想要的结果,这里构造的sql语句是使用updatexml报出后台管理员用户名,发现我们的sql语句是没有问题的。
那我们不是离胜利非常接近了?(并不,接着往下看)
定位:
奇怪的地方来了,这个resource id是什么?$query不应该返回False才对嘛?
查了一下mysql_query()得到以下两个结果:看来我们的情况是有红线的这边。
来源:https://www.php.net/manual/en/function.mysql-query.php
来源:https://blog.csdn.net/weixin_30896511/article/details/95709013
因为我们的$method是空,所以只能运行mysql_query(),看来报错注入的方法行不通了,接着往下看看:
发现有mysql_fetch_array()那我们正常注入是不是可以呢?立马试一下:
1 |
|
这是怎么回事,怎么$array是空呢?
检查发现我们构造的sql语句没问题
然后自己用mysql_connect() mysql_select_db() mysql_query() mysql_fetch_array()
这些函数,尽量贴近齐博cms的原本代码,连一下齐博cms的数据库,看看是否可以正常返回:
发现没有问题。那么就排除了mysql_fetch_array()
的问题,只把产生问题的地方定位在query()函数这里:
排查:
接下来我们把自己写的,没有问题的那些代码放到query()里面执行,结果发现居然也没有Array,然后我们开始改造sql语句,看看正常sql语句能否执行:
1 |
|
结果出来了,除了原本的其他改造sql语句全部能执行,这就说明是我们的宽字节闭合出问题了,再确认一下:
1 |
|
发现执行正常,为什么我们看到dbcharset=gbk,使用宽字节闭合时会出错呢?在query()中有连接数据库的函数connect(),跟进看一下发生了什么(之前调试都会跳过它,以为只是进行数据库连接,并没有其他用处),结果发现了下面的代码。
赶紧看一下我们的数据库版本,发现是5.5,所以说,宽字节闭合sql语句发生了错误,再看看mysql5.1版本是什么时候发行的,发现是2008年,哎。
大疑问
那为什么我们模拟齐博cms源代码,也没有设定连接时必须是gbk,为什么执行时没有出错呢?
现在把重点放到这个代码上:
1 |
|
这里是空的,也就是并没有定义MySQL应该支持的sql语法,对数据的校验等等,具体什么设置,可以参考;https://segmentfault.com/a/1190000005936172
小解答:
那么这是怎么回事呢?有一种可能就是我们模拟时默认编码是utf8,mysql字符集也是utf8,所以没有问题,如果不设置mysql接收gbk,那么连接时齐博cms发送的是gbk,但是mysql只接收utf8,所以出错了。
通过这句话,我们就可以设置mysql接收gbk了
1 |
|
怎么把这句话放到我们的sql语句中呢?如果可以执行多行sql语句,那不就是堆叠注入了嘛?但是没有mysqli_multi_query(),所以无法实现。
最后
这些是目前的一些想法,还有很多的不足,师傅们请多指教。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!