Altm4nz's blog

WEB划水选手

Upload-labs

环境搭建

做题记录

基于源码分析的做题记录。
每一关上传一个可执行phpinfo()的文件在upload目录下即视为成功。

pass-1

查看源码发现是前端校验,定义了checkFile()函数对选择的文件拓展名校验。
方法一 上传后缀为jpg的文件,然后用burp抓包修改后缀。
方法二 直接在前端页面修改

删除 checkFile() 函数。

pass-2

查看源码

1
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif'))

是对content-type的校验,上传抓包修改即可

即可成功上传

pass-3

查看源码

1
2
3
4
5
6
7
8
9
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array('.asp','.aspx','.php','.jsp');
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空

黑名单绕过,不许上传黑名单中的后缀名。并且生成的文件名随机。
尝试上传php5文件,成功解析执行。

pass-4

1
2
3
4
5
6
7
8
9
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array(".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");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空

黑名单加强了,各种可能被解析的后缀都不能用了。
通过上传.htaccess文件改变解析规则。

1
AddType application/x-httpd-php .abc

之后上传后缀为.abc的文件,apache会将.abc后缀当做php来解析。

pass-5

1
2
3
4
5
6
7
8
9
10
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array(".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");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空

这一关过滤了.htaccess后缀。思考了半天,发现比第四关少了一行代码

1
$file_ext = strtolower($file_ext); //转换为小写

那么用大小写绕过即可。
上传文件名为1.pHP。

pass-6

继续与第五关对比,少一句

1
$file_ext = trim($file_ext); //首尾去空

后缀名后面加上一个空格进行绕过。
ps:此题利用windows特性,存储文件时会去除最后的空格,在linux环境下没有成功。

pass-7

对比

1
$file_name = deldot($file_name);//删除文件名末尾的点

上传 1.php.

pass-8

少了一个

1
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA

参考文章:https://www.owasp.org/index.php/Windows_::DATA_alternate_data_stream
ps 此关只能在windows环境下。

pass-9

有pass7知道1.php.可以被服务器解释为php。
上传 1.php.%20.
经过

1
$file_name = deldot($file_name);//删除文件名末尾的点

操作后会变成1.php.%20
检测后缀名为.%20,成功绕过。
![](./upload-labs/屏幕快照 2019-06-25 下午7.00.49.png?r=76)

pass-10

关键代码

1
$file_name = str_ireplace($deny_ext,"", $file_name);

将黑名单替换为空,很好处理,双写绕过即可。
1.pphphp经过处理后变成 1.php
![](./upload-labs/屏幕快照 2019-06-25 下午7.03.44.png)

pass-11

关键代码

1
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

文件路径是可控的
但是后面拼接了随机文件名,

1
move_uploaded_file($temp_file,$img_path)

我们知道mov_uploaded_file可以用%00截断路径。
所以构造路径