说明 :本篇文章精选了ctfhub中web栏目下的5个文件上传入门题目,包括前端验证、.htaccess、MIME绕过、文件头检查、00截断,训练完以后可大致建立一个文件上传的学习框架
靶场链接 :https://www.ctfhub.com/#/skilltree
Q1 无验证
知识点 :服务器没有任何安全过滤机制。也就是说,后端代码接收到文件后,没有检验文件后缀名、MIME类型、文件头,直接将原文件存到了web目录。
操作:
1.制作木马
将下面这串代码存为shell.php,其中的cmd就是你与木马连接的通信密码。
php
<?php @eval($_POST['cmd']); ?>
2.文件上传
开启靶场以后,直接将shell.php传到网页中。上传成功后会得到一个类似下图的界面,其中最上面的网址http://challenge-3667ff894bb105d0.sandbox.ctfhub.com:10800/是该文件所在的绝对路径,/upload/shell.php表示相对路径,这个信息在下一步建立webshell连接时有用。

3.webshell连接
在kali-linux中启动蚁剑,空白处右键一下然后点击Add(如下图1)。在随后出现的界面里,Shell url填入Step2中获得的文件路径http://challenge-3667ff894bb105d0.sandbox.ctfhub.com:10800/upload/shell.php,Shell pwd填入Step1中的cmd(如下图2)。添加shell连接成功后,回到antsword主界面会发现多了一条链接(如下图3),直接双击该链接进入服务器的文件管理界面(如下图4)




4.获取Flag
在服务器的文件管理界面空白处右键点击进入Open Termianl Here(如图1),进入服务器的终端;在终端里我执行了4个指令(如下图2):第一步是切换到根目录/下查看文件目录,发现没有我想要的flag文件;第二步是切换到/tmp路径下查看文件目录,发现没有我要的flag文件;第三步是切换到最开始的var/www/html路径,发现这里存在一个flag_1981918206.php文件;第四步使用cat指令查看这php文件源码,发现里面有我想要的信息,最终确定flag为:ctfhub{e47f517b703dd925a232eadf}


Q2 前端验证
知识点 :浏览器中设置了一段Javascript代码来检查上传的文件后缀,仅放行.png、.jpg等格式的文件,对于.php这样的格式则会弹窗警告不允许上传该类型文件。
操作:
1.burpsuite配置与浏览器代理配置
打开burpsuite,点击Proxy下的Proxy settings(如下图1),进入下图2所示的配置界面后,确保使用的listener端口为127.0.0.1:8080,


打开firfox浏览器,点击FoxyProxy插件里的options(如下图1)。在Proxies下配置一个代理burp,设置该代理的host为127.0.0.1、port为8080。


2.实战绕过
- 文件准备。将Q1中的shell.png改一下后缀名,改成shell.png。
- 网页准备。然后进入题目给的文件上传网页,点击
选择文件按钮将shell.png加载到网页(此时文件并未上传到服务器,这也千万不能点击submit按钮!!!)

- 拦截开启。进入bupsuite软件,点击按钮
Intercept off,从而开启拦截功能

-
文件上传与请求包观察。回到网页中,点击
submit按钮,发现页面卡住。回到burpsuite中,发现出现一个POST请求(URL为上传文件的这个网页URL)
小提示 :点击submit这一步一定要在上一步开启了拦截以后马上就做,使得burpsuite拦截到的第一个包就是submit提交的包,因为浏览器中不可避免地会有各种其他流量,防止在抓到submit提交的包之前抓到很多其他杂七杂八的流量


-
数据修改。在请求包代码中找到
Content-Disposition:form-data; name="file"; filename="shell.png"这一行。将shell.png改成shell.php。

-
请求放行。回到burpsuite界面中,点击Forward按钮,会发现此时网页恢复正常,并多了一个/upload/shell.php。

3.webshell连接与flag收割
这个部分与Q1中几乎一样,打开蚁剑添加webshell连接,然后在命令行终端找到flag文件并查看源码,得到最后的答案为ctfhub{769c2a62496cb2972dfdd742}


Q3 MIME绕过
知识点 :在HTTP协议里,数据包中有一个Content-Type字段,该字段存放着MIME(Multipurpose Internet Mail Extensions)类型,也就是媒体资源类型。常见的MIME类型如下图1,然而当我们上传php木马时,后端就会将其识别为application/octest-stream或application/x-php。服务器后端非常教条主义,仅检查Content-Type字段而不检查真实的文件名后缀,因此可用burpsuite中途把数据包拦截下来修改Content-Type字段就能实现webshell上传了。

操作:
(这个实验的步骤与Q2大体一样,因此下面的操作叙述遵循从简原则)
- Step1。文件准备。直接使用Q1中最原始的那个
shell.php即可。 - Step2。文件加载。浏览器中开启代理,然后打开靶场将
shell.php加载到网页但不要上传。 - Step3。burpsuite拦截、改包与放行。开启
burpsuite拦截后,马上去网页点击submit按钮,回到burpsuite中对抓到的POST请求包进行修改(将Content-Type字段里的application/x-php改成image/png,然后放行会发现网页上加载出来upload/shell.php(如下图2所示)


- Step4。webshell连接与flag收割。用蚁剑连接上传的webshell,然后进入服务器的文件管理界面,打开命令终端找到flag文件,得到的最终答案为
ctfhub{8f368a5c2224bad3b24a36b4}
Q4 .htaccess
知识点 :后端保安更加严格,抓包改Content-Type也不管用了,服务器后端直接写了一套黑名单,一旦检测到.php文件将直接进行拦截。然而,若服务器运行的是Appache环境,它会认2个配置文件(一个是全局配置文件httpd.conf,另一个是地方配置文件.htaccess),全局配置文件相当于宪法、地方配置文件相当于地方法规,而一旦局部规则与全局规则发生冲突,Appache优先局部规则。此外,若上传的目录中原本就有一个.htaccess文件,新上传的.htaccess文件会直接将原文件覆盖。这两个机制使得.htaccess绕过得以发挥威力。
限制条件 :.htaccess要发挥作用也有限制条件,一是服务器后台必须运行的是Appache环境,二是全局配置文件httpd.conf中的AllowOverride(允许覆盖)是打开的,这样你上传的.htaccess才能生效
操作 :
(经过前面3题的积累,会发现文件上传的许多步骤是公共的,为追求高效本题里我对前面出现过的描述也会尽可能简化以让读者更多关注到新的知识)
- Step1。制作
.htaccess文件。在kali-linux环境中,直接运行下面的这个代码块,其作用是在当前目录下生成一个.htaccess配置文件。这个配置文件的作用是告诉Appache服务器将接收到的.png全部强行交给PHP引擎当作代码去执行。(注意,linux环境中一般会隐藏.htaccess文件,若想它显示可按下快捷键ctr+H)
bash
echo 'AddType application/x-httpd-php .png' > .htaccess
- Step2。上传
.htaccess文件到靶场。 - Step3。上传
shell.php文件到靶场。 - Step4。webshell连接与flag收割。打开蚁剑连接到上传的这个shell.php,然后在服务器的文件配置界面打开命令执行窗口,找到flag文件。最终答案为
ctfhub{b569bb4564149407ca13c19d}


Q5 文件头检查
知识点1 :后端保安这次更加严格了,它开始开箱验货了。拿到文件以后,后端代码会使用类似 exif_imagetype() 这样的函数,直接读取你上传文件的魔数(即文件的开头几个字节),若发现不是JPG/PNG/GIF的魔数将会把文件扔进垃圾桶。此外,后端保安在执行php代码时包容性很强,只会执行被<?php ... ?>包裹的代码,对于外层的各种奇怪字符它若不认识会自动忽略。因此我们可以在制作php文件时在其开头加上友好的魔数从而绕过后端保安的文件头检查。
知识点2 :1.纯文本文件(.txt / .php / .html)是个所见即所得的透明人,打开文件里面显示的第一个字符,计算机在加载该文件的字节流时也会是第一个读取该字符;2.二进制文件(.png / .pdf / .zip / .exe)是个高度加密的结构体,需要专属解码器打开来解读各个部分的数据然后完成信息拼凑。
操作:
- Step1。修改shell.php。文件中的内容如下面的代码块所示。
php
GIF89a
<?php @eval($_POST['cmd']); ?>
- Step2。MIME绕过。火狐浏览器开启代理的状态下打开题目靶场,把shell.php文件加载出来,然后打开burpsuite开启拦截,然后马上点击网页上的
submit按钮,回到burpsuite中将Content-Type从application/x-php改成image/png,然后点击放行发现shell.php被成功上传。 - Step3。webshell连接与flag收割。最终得到的答案是
ctfhub{2d7d32adf81ed3c6d6639d21}
