代码审计------第一百零六天
PHP原生开发篇&文件安全&上传监控&功能定位&关键搜索&1day挖掘
PHP审计 - 原生开发-文件上传&RCE
-
第一个案例是emlog的两个文件上传漏洞,在emlog pro 2.2.0版本存在文件上传漏洞,路径为
/admin/plugin.php和/content/templates:


-
安装完成之后用PS打开文件,找到对应目录,先来看第一个
/admin/plugin.php,然后PHP找文件安全漏洞一般关注如下函数:
php
# 文件全局变量
$_FILES
# 文件移动/保存阶段函数
move_uploaded_file($tmp, $dest) # $dest 是否拼接了用户可控的文件名/路径
file_put_contents($file, $data) # $file 和 $data 是否用户可控
fwrite($handle, $data) # 写入内容是否包含用户输入
copy($src, $dst) # 目标路径是否可控
rename($old, $new) # 目标路径是否可控
file_get_contents($file) # 是否用于读取后写入新文件(二次处理)


-
可以看到这里它在上传压缩包的时候没有任何过滤,并且解压操作也没有任何过滤,只是规定了压缩包中要有一个与压缩包名字相同的php文件,这就导致了我们可以在压缩包中包含一些恶意文件后门,解压之后上传到特定的目录
-
因此我们可以准备如下恶意压缩包,其实这里不清楚结构的话可以直接找他的示例插件压缩包,然后加恶意代码即可:


-
然后找到他的前端功能点,看看能不能上传利用:


-
成功上传,然后我们可以看到后台目录结构中也确实有我们的后门代码,并且前端也成功解析:


-
那此时就可以直接连接了,复现完成:

-
第二个位置位于
/content/templates目录,但是这个目录下面是没有代码的:

-
其实这里和plugins一样,他应该也有一个上传template的功能点,位置位于
/admin/template.php:

-
和上面的一模一样,没有任何过滤,那我们也可以模仿这个default制作同样的压缩包上传:


-
也是成功连接,复现完成:

-
所以这两个点的逻辑是完全一样的,只是触发的位置不同
PHP审计 - 原生开发-文件删除
-
第二个案例依旧是emlog,在v6.0.0版本删除模板出存在任意文件删除漏洞:

-
同样我们根据提示来到
/admin/template.php找到删除功能,然后看他的逻辑,或者我们可以搜索如下关键词:
php
unlink() # 删除文件的核心函数
rmdir() # 删除目录
file_exists() + unlink() # 先检查后删除的常见组合
glob() + unlink() # 批量删除场景
array_map('unlink', ...) # 回调方式删除
-
这里简单看看他的逻辑就是接收tplName参数,然后路径拼接后执行删除操作,也没做任何过滤:


-
所以直接前端找到功能点,删除时抓包,然后修改参数为任意文件,比如这里我们把
/admin/plugin.php给删掉:


-
也是成功删掉了,所以这里还是一个问题就是他没有过滤
../../这种路径遍历的字符
PHP审计 - 原生开发-文件上传&文件包含
-
第三个案例是通达OA,在通达OA11.2版本存在文件包含和文件上传漏洞:

-
这里安装好之后,可以到它的
/webroot目录中看到源码,但是这种商业软件一般都会将源码加密,所以这里需要解密:

-
这里都还算好的,提示了是什么Zend加密,我们就直接在网上尝试找解密工具即可,然后将其解密:


-
这里存在漏洞的地方在
/ispirit/im/upload.php,我们把所有的if-else折起来之后会发现它的逻辑就是:
php
1. POST提交$P参数跳过身份验证
2. $DEST_UID参数不为0
3. 需要上传文件
-
这部分可以使用AI辅助分析,上传文件的核心就在这里:

-
这里看不懂也没关系,我们直接在前端找到对应的功能点上传一个文件然后抓包就应该看得差不多了,但是这个功能点我本地好像还访问不了:

-
这时候我们就换种思路,直接本地搭一个表单然后上传文件即可,它的表单参数我们刚刚已经说了:
php
<html>
<body>
<form action="http://<IP>/ispirit/im/upload.php" method="post" enctype="multipart/form-data">
<input type="text" name="P" value=1 />
<input type="text" name="UPLOAD_MODE" value=1 />
<input type="text" name="DEST_UID" value=1 />
<input type="file" name="ATTACHMENT" />
<input type="submit" />
</body>
</html>
-
然后随便上传文件就行了,比如我们这里上传一个普通文件(会限制上传文件的类型):

-
但是这里有个问题就是上传的文件不是放到这个源码的路径下,而是放到了
webroot的上级目录:


-
这里如果不好分析它的文件放到了哪,可以用一个文件监控脚本去看,但是目前直接用AI也能代替
-
也就是说,我们通过Web去访问根本访问不到,所以比较鸡肋,我们需要结合另外一个文件包含漏洞才能发挥它的效果
-
那文件包含漏洞的关键函数有:
php
include($file); // 包含并执行文件,失败返回警告继续执行
include_once($file); // 同上,但只包含一次
require($file); // 包含并执行文件,失败产生致命错误终止
require_once($file); // 同上,但只包含一次
-
这里我们就直接全局搜索有没有上述函数包含变量的代码了:

-
这里它的位置在gateway.php里,结合它的代码这里触发的逻辑为:
php
1. 参数P为空
2. 传入json字段,key为url,value为url地址
3. $url包含general/或ispirit/或module/字段

- 也就是说,我们这里就直接构造如下json就可以配合之前的文件上传漏洞造成RCE了:
json
{
"url": "http://<IP>/general/../../attach/im/2604/xxxx.txt"
}
-
这里它直接包含后会以php的形式去执行代码,所以上传的时候就直接上传txt或者图片马的形式就行:


-
这里我就是做个简单的示范,验证这个漏洞是存在的,所以这个就是文件上传和文件包含的一个结合
-
如果要进行后门连接,可以直接让包含的文件创建一个新的后门文件到Web页面,然后再连接