upload-labs靶机包含漏洞类型分类:

mind-map.png

如何判断上传漏洞类型:

sum_up

0x01.pass-01(客户端js检查)

源码

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;
}
}

代码分析

第一关通过分析源码 “var allow_ext = “.jpg|.png|.gif”;”可以得出则是对后缀名进行白名单的判断这里只要是客户端js的检测

通关方法

  1. 浏览器禁用javaScript

  2. F12直接删除 onsubmit中的 return checkFile() image-20220811153027135

    3.将 webshell 文件后缀名改为允许上传的后缀,然后用 burpsuite 拦截后修改 文件后缀名image.png

0x02-pass-02(服务器白名单之MIME绕过)

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$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.'文件夹不存在,请手工创建!';
}
}

代码分析

“isset”:用于检测变量是否已设置并且非 NULL

if (isset($_POST['submit']))就是指有没有点击上传

file_exists(UPLOAD_PATH)UPLOAD_PATH是对上传路径的规定,这句代码的意思就判断这个上传路径的文件是否存在

if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_files']['type'] == 'image/gif'))判断文件类型是否为image/jpeg或者image/png或者image/gif

$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']规定文件路径为UPLPAD_PATH./加上文件名

move_uploaded_file($temp_file, $img_path)将文件移动到文件上传的路径中

这里 if (($_FILES[‘upload_file’][‘type’] == ‘image/jpeg’) || ($_FILES[‘upload_file’][‘type’] == ‘image/png’) || ($_FILES[‘upload_files’][‘type’] == ‘image/gif’)) 判断文件类型是否为image/jpeg或者image/png或者image/gif

通关方法

上传一句话测试

image.png

使用burpsuite抓包之后修改Content-Type: image/jpeg

image.png

0x03-pass-03(服务端黑名单之特殊解析后缀)

源码

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('.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 . '文件夹不存在,请手工创建!';
}
}

代码分析

$deny_ext = array('.asp','.aspx','.php','.jsp');规定拒绝的后缀名

$file_name = trim($_FILES['upload_file']['name']);trim就是去除空格如果文件名中有空格就去除(这里的文件名就是抓包中的file_name)

$file_ext = strrchr($file_name, '.');strrch就是分割的意思将第一个参数按第二个参数进行分割输出后面的值

这里 if(!in_array($file_ext, $deny_ext))判断你上面获取的file_ext在不在deny_ext(禁止上传后缀名中)不在的话就在继续执行下面上传代码

通关方法

php可以通过php5,php3,phtml 等进行上传(前提在apache的配置文件中将php3,5的注释去掉)所以这里可以直接将后缀名改为php3、php5、phtml,从而绕过黑名单中的后缀上传并同时可以达到执行php代码的要求 。

找到第403行,即下图所示行中添加需要解析的类型格式

1
AddType application/x-httpd-php .php .php3 .phtml

image.png

ps:今天在这里卡了好久好久,用的xp.cn下载的phpstudy8.1搭建的upload-labs靶场,然后这个php3和phtml5解析一直不成功,也配置上面的解析类型格式了,但是就是无法解析,后面又下载了phpstudy2016和phpstudy2018,但是还是没有折腾好,后面查了半天原因,最后发现是phpstudy8.1默认下载的是phpnts阉割版本,缺少了php5apache2_4.dll,导致加上了解析类型也解析不成功,因为功能被阉割了,压根不支持这个解析了.后面换成phpstudy2016,php改成了php-5.4.45完整版,就能正常解析php3和phtml了

image-20220811171650037

image.png

0x04-pass-04(服务器黑名单之htaccess解析)

源码

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",".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 . '文件夹不存在,请手工创建!';
}
}

代码分析

**$deny_ext=array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".pHp1",".Html",".Htm",".pHtml","**

相对第三关黑名单的数量增多其余代码没有变化

引入知识点:

.htaccess基础知识重点内容

htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置(前提要在apache下),为apache的平台做伪静态的转换,实现文件解析自定义

.htaccess文件(或者”分布式配置文件”),全称是Hypertext Access(超文本入口)。提供了针对目录改变配置的方法,即在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。

作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。

启用.htaccess,需要修改httpd.conf,启用AllowOverride,并可以用AllowOverride限制特定命令的使用。如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令来改变。例如,需要使用.config ,则可以在服务器配置文件中按以下方法配置:AccessFileName .config

在apache的配置文件httpd.config,检查mod_write模块是否开启,还有AllowOverride All
检查mod_write模块
查找 rewrite_module ,去掉#即为启动
如果没有找到,就找到 LoadModule 模块在最后加上
LoadModule rewrite_module modules/mod_rewrite.so

//注意重启apache,让apache服务器支持.htaccess,修改httpd.conf文件
Options FollowSymLinks AllowOverride None 改为 Options FollowSymLinks AllowOverride All

image-20220811193030580

通关方法

先上传一个.htaccess文件,内容如下

1
2
3
<FilesMatch "shell.jpg">  
SetHandler application/x-httpd-php
</FilesMatch>

image.png

再上传一个图片马,内容如下:

1
2
3
<?php
phpinfo();
?>

访问上传的图片马,成功被解析

image.png

0x05-pass-05(服务端黑名单 之.user.ini)

源码

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 . '文件夹不存在,请手工创建!';
}
}

代码分析

没有被限制的后缀名有 .php7 以及 .ini

11.png

12.png

通关方法

创建一个 .user.ini 文件上传

内容为 auto_prepend_file=shell.jpg

意思是所有的php文件都自动包含shell.jpg文件。.user.ini相当于一个用户自定义的php.ini

接着上传.jpg文件,内容为<?php @($_POST['1']);?>注意win下用post,linux为get

win使用get需要cmd=system用法

此处有两个选择,等待五分钟300秒,或者进入配置文件php.ini修改为10,需要重启等待10秒,

然后在用蚁剑访问将文件名改为readme.php

不过我复现失败了

image-20220811195839125

0x06-pass-06(服务端黑名单之大小写绕过)

源码

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_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;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '此文件类型不允许上传!';
}
} else {
$msg = 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_ext = strtolower($file_ext); 来转换为小写
所以直接后缀名携程大小写即可

在这里插入图片描述

在这里插入图片描述

image-20220811202301483

0x07-pass-07(服务端黑名单之空格绕过)

源码

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 . '文件夹不存在,请手工创建!';
}
}

代码分析

代码大致同上题,但是缺少首尾去空的一行代码

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

通关方法

上传一个小马,在文件名后面添加一个空格就可以绕过了,因为黑名单中并没有.php (注意这里php后面是有空格的)的声明,上传后存储文件后又会自动去除空格

img

0x08-pass-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 . '文件夹不存在,请手工创建!';
}
}

代码分析

跟上题类似,只是这里少了删除文件末尾点的代码

$file_name = deldot($file_name);

通关方法

上传一个小马,只要在文件名后面加一个.就可以绕过了

image.png

image.png

0x09-pass-09(服务端黑名单之::$DATA绕过)

源码

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_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$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 = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}

代码分析

跟上题类似,少了对字符串::$DATA的绕过

$file_ext = str_ireplace('::$DATA', '', $file_ext);

通关方法

Windows 下 NTFS 文件系统的一个特性, NTFS 文件系统的存储数据流的一个属性 DATA 时,就是请求 webshell.php 本身的数据

::$DATA是windows下对于php文件的一种定义,如果在文件名之后加上::$DATA就会不对后缀名进行检测保持::$DATA之前的文件名`

image.png

访问的时候记得删掉::$data

image-20220811204824398

删掉就能访问成功了

image-20220811204854171

0x10-pass-10(服务端黑名单之双写绕过)

源码

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",".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 . '文件夹不存在,请手工创建!';
}
}

代码分析

这里涉及到一个循环的问题
当这里涉及到比如deldot对末尾点的过滤式代码中只进行了一次过滤那我们就可以考虑加2个点之后被过滤掉一个空格从“.php. .”变为了“ php.”这里就任然可以绕过黑名单进行上交并执行php文件内容

通关方法

把小马的后缀名改成.php. . 结尾俩.中间有个空格,被过滤掉一个空格之后文件名变成shell.php. 可以访问成功

image.png

0x11-pass-11(黑名单之双后缀名绕过)

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$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","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini");

$file_name = trim($_FILES['upload_file']['name']);
$file_name = str_ireplace($deny_ext,"", $file_name);
$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 = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}

代码分析

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

如果有发现有禁止的后缀名就把他换为空处理,那么这里就可以通过双写后缀名进行绕过了

通关方法

shell.php改成 shell.pphphp 这中间的随便写,是上面禁止名单里的后缀名都可以,上传的时候会自动过滤掉这部分,然后就能拼合成php的后缀了.需要注意的是文件名不要是禁止名单的后缀

image.png

0x12-pass-12(白名单之GET%00截断绕过)

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
if(in_array($file_ext,$ext_arr)){
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
}
}

代码分析

$file_ext=substr($_FILES['upload_file'['name'],strrpos($_FILES['upload_file']['name'],".")+1);

里的含义是验证命名里有没有多个点,并进行循环验证,然后将文件名于白名单中的规定后缀进行对比如果有就进行上传反之上传失败

通关方法

需要两个条件是:

1.服务器php版本小于5.3.4,因为在5.3.4开始已经修复0字符。

2.magic_quotes_gpc为off状态,作用是判断解析用户提示的数据,如:postget,cookie过来的数据加转义字符’\‘,输入数据中要包含双引号,反斜线\NULL时候都会被加上反斜线。和addslanshes()函数一个意思。在php.ini配置文件中设置。

注意:魔术引号在php的5.3.0之前默认开启,在5.3.0到5.4.0默认关闭,且在5.4.0起被废除。

当做完上面的白名单验证和定义上传路径之后,上传文件去指定位置。

$_FILES['myFile']['name']文件上传时候本身的名字,用户定义的名字

$_FILES['myFile']['tmp_name'] 文件被上传后在服务端储存的临时文件名,一般是系统默认

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

get方式传入了save_path变量后面拼接随机数+合法后缀名

当输入路径为?save_path=../upload/1.php%00
这是系统生成的路径为../upload/1.php%00/5020220514234059.gif
%00的作用是截断所以最终保存路径就为:…/upload/1.php

image.png

这个我复现失败了,我的php版本是5.4.45

0x13-pass-12(白名单之POST%00绕过)

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
if(in_array($file_ext,$ext_arr)){
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
} else {
$msg = "上传失败";
}
} else {
$msg = "只允许上传.jpg|.png|.gif类型文件!";
}
}

代码分析

这一关白名单,文件上传路径拼接生成,而且使用了post发送的数据进行拼接,我们可以控制post数据进行0x00截断绕过白名单

跟上面一样,只不过换成了post请求

通关方法

补充:POST不会对里面的数据自动解码,需要在Hex中修改。

上传php文件,用burp抓包

将路径 ../upload/ 添加上传的文件加上+ ../upload/asd.php+

在../upload/ 路径下加上asd.php+ +号是为了方便后面修改Hex

10.png

+号的Hex是2b,这里我们要把它改为00,如下图

10.png

然后就可以放包了,注意连接蚂蚁剑时将php后面的删掉。

10.png

依旧复现失败

0x14-pass-14(文件头检测+文件包含漏洞)

源码

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
28
29
30
31
32
33
34
35
36
37
38
39
40
function getReailFileType($filename){
$file = fopen($filename, "rb");
$bin = fread($file, 2); //只读2字节
fclose($file);
$strInfo = @unpack("C2chars", $bin);
$typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
$fileType = '';
switch($typeCode){
case 255216:
$fileType = 'jpg';
break;
case 13780:
$fileType = 'png';
break;
case 7173:
$fileType = 'gif';
break;
default:
$fileType = 'unknown';
}
return $fileType;
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_type = getReailFileType($temp_file);

if($file_type == 'unknown'){
$msg = "文件未知,上传失败!";
}else{
$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
} else {
$msg = "上传出错!";
}
}
}

代码分析

补充知识:

1.Png图片文件包括8字节:89 50 4E 47 0D 0A 1A 0A。即为 .PNG

2.Jpg图片文件包括2字节:FF D8

3.Gif图片文件包括6字节:47 49 46 38 39|37 61 。即为 GIF89(7)a

4.Bmp图片文件包括2字节:42 4D。即为 BM

图片马制作

  • 木马病毒隐藏在正常程序中的一段具有特殊功能的恶意代码,是具备破坏和删除文件、发送密码、记录键盘和攻击Dos等特殊功能的后门程序
  • 原理:把一句话木马,通过二进制的方式追加到图片文件末尾,将木马文件和图片合并为另一个图片文件,合并后的图片包含一句话木马而且不影响图片显示,但用记事本等文本编辑器打开,能看到图片末尾的恶意代码。然后将图片上传到网站中,利用网站的漏洞,通常是文件包含漏洞,让网站把上传的图片当成脚本代码解析,从而达到运行恶意代码控制网站服务器的目的。
    简单来说就是以文件上传漏洞为基本条件,将可执行的条件写入图片中去,再利用文件包含漏洞来执行图片中存在的一句话木马,从而获取目标服务器的权限。

Windows

  • 第一步:找一个图片
  • 第二步:一句话木马文件
    在这里插入图片描述
  • 第三步:win+Rcmd,输入copy 图片文件名/b+一句话木马文件名/a 制作的图片马文件名
  • 第四步:记事本打开验证一句话木马是否写入成功
    注意点:图片文件和木马文件需放在一个路径下

制作图片马命令:copy 图片文件名称/b+脚本文件名称/a 新生成的文件名称,例如:

copy 222.jpg/b+111.php/a 333.jpg

在这里插入图片描述
用记事本打开验证一句话木马是否写入
在这里插入图片描述
ctrl+F查找一句话木马,写入成功

Linux

将木马文件追加到图片文件后面的方法:

cat test1.asp >> test2.jpg
将两个文件合并成第三个文件的方法:

cat test1.asp test2.jpg >> test3.jpg
在这里插入图片描述
查找一句话木马,写入成功
在这里插入图片描述

通关方法

右键图片获取上传的路径和图片马的文件名,然后用文件包含漏洞include.php?file=访问该文件,在蚁剑上连接成功

127.0.0.1/upload1/include.php?file=./upload/3720220811140725.png

image-20220811221006201

0x0-pass-0()

源码

1

代码分析

通关方法

0x0-pass-0()

源码

1

代码分析

通关方法

0x0-pass-0()

源码

1

代码分析

通关方法

0x0-pass-0()

源码

1

代码分析

通关方法

0x0-pass-0()

源码

1

代码分析

通关方法

0x0-pass-0()

源码

1

代码分析

通关方法

0x0-pass-0()

源码

1

代码分析

通关方法

0x0-pass-0()

源码

1

代码分析

通关方法

0x0-pass-0()

源码

1

代码分析

通关方法

0x0-pass-0()

源码

1

代码分析

通关方法

0x0-pass-0()

源码

1

代码分析

通关方法

0x0-pass-0()

源码

1

代码分析

通关方法