题目描述

暂无

Solution

打开页面,观察源码:

1.png

这里是考察 PHP 反序列化。PHP 反序列化漏洞有几个我们需要重点关注的函数:

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

对于一个序列化后的字符串O:6:"people":2:{s:4:"name";s:6:"f1r3k0";s:3:"age";i:18;}而言,它遵循下列这个模式:

  1. O:<class_name_length>:"<class_name>":<number_of_properties>:{<properties>}

而各个部分的意思如下:

  1. O:Object 对象;
  2. 6:类的名字,长度为 6;
  3. people:类的名字;
  4. 2:属性个数;
  5. {...}:各个属性;
  6. s:字符串;
  7. i:整数

本题中我们需要绕过的地方是__wakeup()函数。如果序列化后的字符串中表示属性个数的数字与真实属性个数不一致,那么__wakeup()函数就不会执行。

我们在 Kali 编写一段 PHP 代码:

  1. <?php
  2. class xctf
  3. {
  4. public $flag = '111';
  5. }
  6. $new_obj = new xctf();
  7. $serde_str = serialize($new_obj);
  8. $serde_str = str_replace(":1:", ":2:", $serde_str);
  9. print_r($serde_str);

1、我们先实例化一个对象;

2、然后把这个对象序列化成字符串;

3、把关于属性的字段给替换掉,原来是O:4:"xctf":1:{s:4:"flag";s:3:"111";},代表只有 1 个属性,现在把它替换成 2 个属性;

然后我们执行该脚本:

2.png

把这个字符串按照题目要求,用 GET 请求传参?code给送到服务器:

3.png