文件上传/包含学习
前言
本文记录对文件上传和文件包含漏洞的练习
正文
文件上传
原理:上传文件的时,如果未对上传的文件进行严格的验证和过滤,就容易造成文件上传漏洞,上传脚本等。导致网站甚至整个服务器被控制,恶意的脚本文件又称为WebShell,WebShell具有强大的功能,如查看服务器目录、执行系统命令等,十分危险。
利用方式:先寻找上传点,比如头像处,只要能找到上传点就有机会
靶场训练:upload靶场
1关
前端 js 验证
直接上传php文件发现 限制了文件后缀
抓包试试
开启代理后点击上传还是在前台显示弹窗,说明这是前台的 js 限制
查看源代码,的确如此
直接F12 修改 js ,将php设为允许(不成功,无法修改)
或者将php文件改为允许的后缀名,抓包后在修改回php即可绕过前端的验证
随后使用文件所在路径 http://127.0.0.1/upload-labs-master/upload/3.php 用蚁剑连接即可
2关
仅判断content-type,修改content-type绕过,修改为image/jpeg、image/png、image/gif任何一个都可以。
MIME类型限制
直接上传.php文件显示格式不允许,抓包后发现 MIME 类型为 application/octet-stream 尝试把它改成 image/jpeg ,放包,成功
3关
黑名单 不允许上传.asp,.aspx,.php,.jsp后缀文件
尝试绕过大小写绕过 pHp,失败。尝试替代品但是又能以php的形式解析的 php3 ,php5,phtml
成功,连接格式 GBK– base64(不是php后缀无法使用蚁剑连接)
4关
黑名单 禁止(”.php”,”.php5”,”.php4”,”.php3”,”.php2”,”.php1”,”.html”,”.htm”,”.phtml”,”.pht”,”.pHp”,”.pHp5”,”.pHp4”,”.pHp3”,”.pHp2”,”.pHp1”,”.Html”,”.Htm”,”.pHtml”,”.jsp”,”.jspa”,”.jspx”,”.jsw”,”.jsv”,”.jspf”,”.jtml”,”.jSp”,”.jSpx”,”.jSpa”,”.jSw”,”.jSv”,”.jSpf”,”.jHtml”,”.asp”,”.aspx”,”.asa”,”.asax”,”.ascx”,”.ashx”,”.asmx”,”.cer”,”.aSp”,”.aSpx”,”.aSa”,”.aSax”,”.aScx”,”.aShx”,”.aSmx”,”.cEr”,”.sWf”,”.swf”,”.ini”)
可以上传 .htaccess
.htaccess文件,全称是Hypertext Access(超文本入口)。提供了针对目录改变配置的方法, 即在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。
上传一个.htaccess文件,在里面写入
1 | SetHandler application/x-httpd-php |
这样所有文件都会解析为php。然后我们再上传图片马,就可以成功解析了
5关
黑名单 禁止(”.php”,”.php5”,”.php4”,”.php3”,”.php2”,”.html”,”.htm”,”.phtml”,”.pht”,”.pHp”,”.pHp5”,”.pHp4”,”.pHp3”,”.pHp2”,”.Html”,”.Htm”,”.pHtml”,”.jsp”,”.jspa”,”.jspx”,”.jsw”,”.jsv”,”.jspf”,”.jtml”,”.jSp”,”.jSpx”,”.jSpa”,”.jSw”,”.jSv”,”.jSpf”,”.jHtml”,”.asp”,”.aspx”,”.asa”,”.asax”,”.ascx”,”.ashx”,”.asmx”,”.cer”,”.aSp”,”.aSpx”,”.aSa”,”.aSax”,”.aScx”,”.aShx”,”.aSmx”,”.cEr”,”.sWf”,”.swf”,”.htaccess”)
但是没有大小写转换。抓包,改文件名为 .PHp 大小写绕过
6关
黑名单 禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf|.htaccess后缀文件!
但是 $file_ext = trim($file_ext); //首尾去空
,我们可以在a.php前或后加一个或多个空格绕过
7关
黑名单 禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf后缀文件!
但是$file_name = deldot($file_name);//删除文件名末尾的点
,所以我们可以在 .php后缀名后加 . 进行绕过
**8关 **
黑名单 禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf后缀文件!
但是$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
,所以我们可以在 .php后缀名处加上 ::$DATA 变成 .php::$DATA 绕过
**9关 **
黑名单 禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf|.htaccess后缀文件
但是$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
,路径拼接的是处理后的文件名,于是构造info.php. . (点+空格+点),经过处理后,文件名变成info.php.,即可绕过
10关
只允许上传.jpg|.png|.gif后缀的文件!
1 | $file_name = trim($_FILES['upload_file']['name']); |
绕过,大小写失败,双写绕过成功
11关
白名单 $_GET传参save_path
会从文件名中去除.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf|.htaccess字符!
$img_path直接拼接,因此可以利用**%00截断**绕过。
1 | strrpos() 定义和用法 |
在请求头 sava_path=../upload/a.php%00 截断,上传
12关
白名单 $_POST传参save_path
还是利用00截断,但这次需要在二进制中进行修改,因为post不会像get对%00进行自动解码
添加一个1.php+(任意名称)
2b代表二进制这里的2b对应的就是**+**号,将2b改成00,即可成功截断,1.php也可成功上传利用
13关
本pass上传路径可控
图片马
验证上传文件类型的方法是:通过判断上传文件的前两个字节来判断的,所以直接上传图片马即可绕过.jpg和.png检查,制作方法
copy 1.jpg /b + info.php /a shell.jpg
1.jpg是一个图片,info.php写入一句话木马的文件,shell.jpg复制后的文件
使用文件包含漏洞,读取上传的文件
可以写一个include.php:
1 |
|
上传文件后查看返回包,获取文件绝对路径
访问:http://127.0.0.1/upload-labs-master/upload/include.php?page=upload/a.jpg
解析
14关
这里使用getimagesize获取文件类型
1 | getimagesize() 函数将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型和一个可以用于普通 HTML 文件中 IMG 标记中的 height/width 文本字符串。 |
利用图片马就可进行绕过,和上一关一样
15关
利用exif_imagetype(),判断文件类型,Pass-13的方法即可绕过
16关
使用imagecreatefromjpeg()来判断文件类别,已可以使用 Pass-13 的方法。
原理:将一个正常显示的图片,上传到服务器。寻找图片被渲染后与原始图片部分对比仍然相同的数据块部分,将Webshell代码插在该部分,然后上传。具体实现需要自己编写Python程序,人工尝试基本是不可能构造出能绕过渲染函数的图片webshell的
17关文件异常
18关
像Pass-13一样可以上传图片马
19关文件异常
文件包含
通过PHP
函数引入文件时,传入的文件名没有经过合理的验证,从而操作了预想之外的文件,导致意外的文件泄漏甚至恶意代码注入。
以下服务器位于 Linux 下
1关
源码
1 |
|
data协议:
1 | data://text/plain,xxxx(要执行的php代码) |
1 | data协议 php5.2.0起,数据流封装器开始有效 |
使用 data 协议查询文件
data://text/plain;base64,PD9waHAgc3lzdGVtKCJscyIpPz4=
之后尝试使用 data 协议执行 cat 命令,失败了。改用 php:// 协议的 filter 类型
?file=php://filter/read=convert.base64-encode/resource=flag.php
,结果进行 base64 解码,出 flag
2关
1 | $file = str_replace("php", "???", $file); |
所以我们使用 data 协议的时候进行 base64 一下
1 | ?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCJscyIpPz4= //查询 |
3关
1 | 源码: |
使用日志 getshell ,文件包含日志 ?file=/var/log/nginx/access.log
,抓这个包,然后将User-Agent 改成一句话木马,放包。
蚁剑 连接http://xxx?file=/var/log/nginx/access.log
,输入密码连接,找到flag
4关
1 | 源码 |
解法和3关一样
5关
5~9过滤严重,都要利用 session 文件,利用session.upload_progress进行文件包含
此特性在 PHP5.4版本 及 以上 可用
1 | 源码 |
我们看到,题目过滤了.
,只能找一个不带.
路径的文件,所以选择了 session 会话文件
介绍:
session是以文件的形式保存的
php.ini中有个配置项–session.save_path= “”;这个里面填写的路径,将会使session文件保存在该路径下。
session文件的命名格式是:sess_[PHPSESSID的值]。每一个文件,里面保存了一个会话的数据。其实只要使用代码$_SESSION[‘user_id’] = $value;就会促发php的session机制,结果往对应的session文件中写入一个值。
利用前要弄明白下面几个点:
1 | 1.session文件默认路径 |
使用这个脚本,基本都可以利用
1 | # -*- coding: utf-8 -*- |
6关
1 | 源码 |
7关
1 |
|
8关
1 | if(isset($_GET['file'])){ |
9关(无法加载)
1 | define('还要秀?', dirname(__FILE__)); |
10关
1 | if(isset($_GET['file'])){ |
11关
1 | if(isset($_GET['file'])){ |
没有过滤 :
,使用 data 。?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmwwZy5waHAnKTsgPz4
这是直接 cat fl0g.php 而在执行 ls 的时候失败了,因为不能出现等号和加号,所以构造的一句话木马还是有技巧的
1 | "tac fl*"); system( |
有许多命令都可以查看文件,不同的命令有不同的优点,可以针对不同的需要分别选择命令以提高效率:
cat 由第一行开始显示内容,并将所有内容输出
tac 从最后一行倒序显示内容,并将所有内容输出
more 根据窗口大小,一页一页的现实文件内容
less 和more类似,但其优点可以往前翻页,而且进行可以搜索字符
head 只显示头几行
tail 只显示最后几行
nl 类似于cat -n,显示时输出行号
12关
页面是一个电影视频混剪,无法加载
13关
1 |
|