HCTF 2018 –warmup

image-20210806000759031

f12看到注释source.php,访问

image-20210806001027721

代码审计,判断是文件包含,对file使用了checkFile方法,要让checkFile返回true才行。

看到源码中还要hint.php,访问得到flag在ffffllllaaaagggg里面

前两个if很好绕过,然后会把参数中?前的字符取出来,判断是否在白名单内,如果在就返回true,这样就可以,后面其实不用看了。

mb_substr会将?前的字符截取出来与白名单比较,因此可以构造payload=hint.php?/../../../../../ffffllllaaaagggg

得到flag

image-20210806013115545

tips : 在linux下,文件名中除了不能有/,所有字符都可以;但在windows下,文件名是不能有?等等一些特殊字符的。

因为这题在linux环境下,所以实际用不上checkFile里面urldecode以后的代码,原因就是上面的tips所讲。若题目在win环境下,上面的payload就不能直接用了,需要对?进行二次url编码,也就是hint.php%253f/../../../../../ffffllllaaaagggg,二次编码是因为参数传到php的时候,首先会进行一次解码,这样一来参数给$page值实际为hint.php%3f/../../../../../ffffllllaaaagggg,进而在checkFile里面urldecode时,%3f就能被解码成,就可以成功截取前面的hint.php,而在include中的参数是hint.php%3f/../../../../../ffffllllaaaagggghint.php%3f被解释成文件夹名时,字符都是合法的,因此可以成功包含文件。

NaNNaNNaNNaN-Batman

一个附件,下载下来,打开发现是js代码,但是有很多控制字符,放到浏览器console里面去调试,把末尾的eval改成console.log,执行得到完整的js代码

1

要绕过层层if去执行里面的命令,可以把if都删了,直接运行里面的语句得到flag

1

网鼎杯 2018 –fakebook

打开环境,是类似于一个blog列表展示页面
1
先dirmap+御剑扫描,扫到user.php.bak,flag.php,得到user.php源码
1
从中可以看到get()方法会请求传入blog的url,并将请求结果返回,这里推测可能是用get()将flag.php读出来。继续找利用方式。
在join页面添加一个用户,根据user.php,blog应该填网址,随便填一个网址,显示join成功,返回列表后,点击username进入view.php。
url此时为/view.php?no=1,测试发现存在注入,union select会被waf检测到,用union all select成功绕过,接下来就是常规的注入操作了,测出返回值为4列,利用information_schema库得到user表(这里注入可参考https://voendless.gitee.io/cyxx/2019/06/05/sql%E6%B3%A8%E5%85%A5-informationschema/)。
user表有个data字段,读出来发现里面存放的是序列化信息。同时还存在一个反序列化的报错,所以猜测假如按照正常的业务逻辑,查询某个用户时,返回结果中data字段的值会先被反序列化。
1

data是第四个字段,所以先构造一个payloadview.php?no=-1 union all select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:6;s:4:"blog";s:4:"test";}'

1
发现blog变量成功被读取,但是现在需要读取flag.php,尝试利用file协议读取,构造payload/view.php?no=-1 union all select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:6;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'

1

在contents一栏下面的iframe标签内发现成功读取了flag.php。

感兴趣的话其实可以把view.php等文件源码读出来,这样对该漏洞的原理就更加理解了。下面顺便放出来。

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?php session_start(); ?>
<?php require_once 'db.php'; ?>
<?php require_once 'user.php'; ?>
<?php require_once 'error.php'; ?>
<?php

$db = new DB();

?>
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>User</title>

<?php require_once 'bootstrap.php'; ?>
</head>
<body>
<?php

$no = $_GET['no'];
if ($db->anti_sqli($no))
{
die("no hack ~_~");
}

$res = $db->getUserByNo($no);
$user = unserialize($res['data']);
//print_r($res);

?>
<div class="container">
<table class="table">
<tr>
<th>
username
</th>
<th>
age
</th>
<th>
blog
</th>
</tr>
<tr>
<td>
<?php echo $res['username']; ?>
</td>
<td>
<?php echo $user->age; ?>
</td>
<td>
<?php echo xss($user->blog); ?>
</td>
</tr>
</table>

<hr>
<br><br><br><br><br>
<p>the contents of his/her blog</p>
<hr>
<?php

$response = $user->getBlogContents();
if ($response === 404)
{
echo "404 Not found";
}

else
{
$base64 = base64_encode($response);
echo "<iframe width='100%' height='10em' src='data:text/html;base64,{$base64}'>";
// echo $response;
}

// var_dump($user->getBlogContents());
?>

</div>
</body>
</html>