Web通用漏洞--文件上传

概述

文件上传安全指的是攻击者通过利用上传实现后门的写入连接后门进行权限控制的安全问题,对于如何确保这类安全问题,一般会从原生态功能中的文件内容,文件后缀,文件类型等方面判断,但是漏洞可能不仅在本身的代码验证逻辑中出现安全问题,也会在语言版本,语言函数,中间件,引用的第三方编辑器等存在缺陷地方配合利用。另外文件上传也有多个存储逻辑,不同的文件存储方案也会给攻击者带来不一样的挑战!

靶场upload-labs-docker

js验证

采用前端代码进行文件后缀验证



绕过方法

  1. 删除前端代码

    通过查看前端代码,发现上传form表单有个javascirpt事件,即检测文件后缀白名单,删除即可

  2. 在浏览器禁用javascript
  3. 将文件后缀修改为允许上传的后缀,通过前端校验后抓包修改文件后缀

修改解析规则



上传.htaccess文件添加配置解析规则,将png文件后缀进行php解析

AddType application/x-httpd-php .png

上传写有php代码的png文件,访问

文件类型绕过



源码

    <?php
header("Content-type: text/html;charset=utf-8");
error_reporting(0);
//设置上传目录
define("UPLOAD_PATH", dirname(__FILE__) . "/upload/");
define("UPLOAD_URL_PATH", str_replace($_SERVER['DOCUMENT_ROOT'], "", UPLOAD_PATH));
if (!file_exists(UPLOAD_PATH)) {
mkdir(UPLOAD_PATH, 0755);
}
$is_upload = false;
if (!empty($_POST['submit'])) {
if (!in_array($_FILES['file']['type'], ["image/jpeg", "image/png", "image/gif", "image/jpg"])) {
echo "<script>black();</script>";
} else {
$name = basename($_FILES['file']['name']);
if (move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_PATH . $name)) {
$is_upload = true;
} else {
echo "<script>alert('上传失败')</script>";
}
}
}
?>

代码中通过查看type白名单进行过滤

通过抓包将数据包中的content-type进行修改即可上传成功

文件头检测



源码

 <?php
header("Content-type: text/html;charset=utf-8");
error_reporting(0);
//设置上传目录
define("UPLOAD_PATH", dirname(__FILE__) . "/upload/");
define("UPLOAD_URL_PATH", str_replace($_SERVER['DOCUMENT_ROOT'], "", UPLOAD_PATH));
if (!file_exists(UPLOAD_PATH)) {
mkdir(UPLOAD_PATH, 0755);
}
$is_upload = false;
if (!empty($_POST['submit'])) {
if (!$_FILES['file']['size']) {
echo "<script>error();</script>";
} else {
$file = fopen($_FILES['file']['tmp_name'], "rb");
$bin = fread($file, 4);
fclose($file);
if (!in_array($_FILES['file']['type'], ["image/jpeg", "image/jpg", "image/png", "image/gif"])) {
echo "<script>black();</script>";
} else if (!in_array(bin2hex($bin), ["89504E47", "FFD8FFE0", "47494638"])) {
echo "<script>black();</script>";
} else {
$name = basename($_FILES['file']['name']);
if (move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_PATH . $name)) {
$is_upload = true;
} else {
echo "<script>error();</script>";
}
}
}
}
?>

源码中对上传文件的类型和文件头都进行了检测

if (!in_array($_FILES['file']['type'], ["image/jpeg", "image/jpg", "image/png", "image/gif"]))
if (!in_array(bin2hex($bin), ["89504E47", "FFD8FFE0", "47494638"]))

那么将我们上传的文件头添加符合上传规则文件头并且修改数据包中的content-type类型即可成功上传



黑名单验证



题目中源码采用了黑名单验证的方式,将黑名单中的后缀进行替换为空,但是并没有进行循环验证处理,因此可以采用多重后缀名嵌套进行上传。

文件后缀大小写敏感



在linux系统中文件名大小写敏感,题目中源码只对小写后缀名进行过滤,可以采用大写文件名后缀进行上传。

零零截断(GET)



零零截断即在系统进行文件接受时,会错误得把%00当作结束符进行接受保存,从而不对%00后面的字符进行保存。%00使url进行解码后的结果其实是为空字节。

 <?php
header("Content-type: text/html;charset=utf-8");
error_reporting(0);
//设置上传目录
define("UPLOAD_PATH", dirname(__FILE__) . "/upload/");
define("UPLOAD_URL_PATH", str_replace($_SERVER['DOCUMENT_ROOT'], "", UPLOAD_PATH));
if (!file_exists(UPLOAD_PATH)) {
mkdir(UPLOAD_PATH, 0755);
}
$is_upload = false;
if (!empty($_POST['submit'])) {
$name = basename($_FILES['file']['name']);
$info = pathinfo($name);
$ext = $info['extension'];
$whitelist = array("jpg", "jpeg", "png", "gif");
if (in_array($ext, $whitelist)) { $filename = rand(10, 99) . date("YmdHis") . "." . $ext;
$des = $_GET['road'] . "/" . $filename; if (move_uploaded_file($_FILES['file']['tmp_name'], $des)) {
$is_upload = true;
} else {
echo "<script>black();</script>";
}
} else {
echo "文件类型不匹配";
}
}
?>

在文件进行保存的时候,文件路径与文件名相连接,路径中带有%00,于是将文件保存为2.php



关于php版本是否符合,在网站的返回数据包中可以查看

零零截断(POST)



POST型在进行零零截断的时候需要将文件路径写在传送数据的位置,由于GET型在写入%00时,系统会自动将地址栏的%00进行解码,但是POST不会,因此在进行上传过程中需要将%00进行解码发送。

配置绕过

在网站管理员进行网站配置过程中没有严格进行配置网站,导致php3,php5等文件后缀名文件也进行php解析。

<?php
header("Content-type: text/html;charset=utf-8");
error_reporting(0);
//设置上传目录
define("UPLOAD_PATH", dirname(__FILE__) . "/upload/");
define("UPLOAD_URL_PATH", str_replace($_SERVER['DOCUMENT_ROOT'], "", UPLOAD_PATH));
if (!file_exists(UPLOAD_PATH)) {
mkdir(UPLOAD_PATH, 0755);
}
$is_upload = false;
if (!empty($_POST['submit'])) {
$name = basename($_FILES['file']['name']);
$ext = pathinfo($name)['extension'];
$blacklist = array("asp","aspx","php","jsp","htaccess"); if (!in_array($ext, $blacklist)) {
if (move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_PATH . $name)) {
$is_upload = true;
} else {
echo "<script>error();</script>";
}
} else {
echo "<script>black();</script>";
}
}
?>

源码中采取了白名单验证后缀名,如何后缀名为php,asp等将不能通过验证

条件竞争

条件竞争是利用一种错误的逻辑进行的文件上传,所以可以将上传的文件中写入访问即创建的代码,再对该文件进行不断上传,同时不断访问该文件,只要访问到了该文件,便会创建一个后门文件出来。

 <?php
header("Content-type: text/html;charset=utf-8");
error_reporting(0);
//设置上传目录
define("UPLOAD_PATH", dirname(__FILE__) . "/upload/");
define("UPLOAD_URL_PATH", str_replace($_SERVER['DOCUMENT_ROOT'], "", UPLOAD_PATH));
if (!file_exists(UPLOAD_PATH)) {
mkdir(UPLOAD_PATH, 0755);
}
$is_upload = false;
if (!empty($_POST['submit'])) {
$name = basename($_FILES['file']['name']);
$ext = pathinfo($name)['extension'];
$upload_file = UPLOAD_PATH . '/' . $name;
$whitelist = array('jpg','png','gif','jpeg'); if (move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_PATH . $name)) {
if(in_array($ext,$whitelist)){
$rename_file = rand(10, 99).date("YmdHis").".".$ext;
$img_path = UPLOAD_PATH . '/'. $rename_file;
rename($upload_file, $img_path);
$is_upload = true;
}else{
echo "<script>black();</script>";
unlink($upload_file);
}
}
}
?>

源码中先将文件进行存储,再进行判断文件是否合法。

首先抓取上传文件的数据包



发送至intruder模块进行空值爆破,无限制得上传该文件



再抓取访问该文件得数据包,依旧进行空值爆破



当访问数据包出现不同长度的返回包时,大概率时已经成功创建了,连接后门验证结果即可



连接成功

二次渲染

在进行文件上传过程中,很多网站会对上传后的图片进行二次渲染以适应web显示界面等。



在对绕过二次渲染的图片马中,gif文件最为简单



先将图片进行上传,然后将上传过后的图片进行下载,与源文件进行对比,在没有修改的部分插入代码即可。



经过对比灰色部分就是没有发生变化的部分,在灰色部分插入代码即可



重新上传,再次下载查看payload是否存在

使用网站本身的包含漏洞进行验证

move_uploaded_file缺陷



在保存文件名后面加上/.便可以上传成功

代码审计

不会!

文件解析方案

  1. 执行权限(有可能绕过)

    文件上传后,存储文件的文件夹无执行权限

  2. 解码还原(不能绕过)

    文件在上传过程中,源码通过函数将文件中的数据提取出来并进行编码,存储入数据库中。在使用文件时,调用数据编码进行解码还原。

文件存储方案

  1. 分站存储(不能绕过)

    网站与存储上传文件属于不同站点、不同服务器,在网站服务器进行上传,传输至存储文件服务器,一般会设置执行权限。
  2. 对象存储(不能绕过)

    OSS对象云存储,只能存储文件,并不能执行。具有key泄露的风险。

以上内容仅作学习,如有错误或瑕疵,欢迎批评指正,感谢阅读。

Web通用漏洞--文件上传的更多相关文章

  1. 基于 java 【Web安全】文件上传漏洞及目录遍历攻击

    前言:web安全之文件上传漏洞,顺带讲一下目录遍历攻击.本文基于 java 写了一个示例. 原理 在上网的过程中,我们经常会将一些如图片.压缩包之类的文件上传到远端服务器进行保存.文件上传攻击指的是恶 ...

  2. JAVA Web 之 struts2文件上传下载演示(二)(转)

    JAVA Web 之 struts2文件上传下载演示(二) 一.文件上传演示 详细查看本人的另一篇博客 http://titanseason.iteye.com/blog/1489397 二.文件下载 ...

  3. JAVA Web 之 struts2文件上传下载演示(一)(转)

    JAVA Web 之 struts2文件上传下载演示(一) 一.文件上传演示 1.需要的jar包 大多数的jar包都是struts里面的,大家把jar包直接复制到WebContent/WEB-INF/ ...

  4. WEB安全:文件上传漏洞

    文件上传漏洞过程 用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力. 一般的情况有: 上传文件WEB脚本语言,服务器的WEB容器解释并执行了用户上传的脚本,导致代码执行: ...

  5. web安全之文件上传漏洞攻击与防范方法

    一. 文件上传漏洞与WebShell的关系 文件上传漏洞是指网络攻击者上传了一个可执行的文件到服务器并执行.这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等.这种攻击方式是最为直接和有效 ...

  6. Web安全-之文件上传漏洞场景

    1   上传漏洞危害介绍 上传是Web中最常见的功能,如果上传功能存在设计.编码缺陷,就容易形成上传漏洞,从而成为致命的安全问题,攻击者可以通过上传脚本木马,实现查看/篡改/删除源码和任意涂鸦网页,可 ...

  7. WEB安全性测试之文件上传漏洞

    1.漏洞描述:文件上传漏洞,是指可以利用WEB上传一些特定的文件包含特定代码如(<?php phpnfo;?> 可以用于读取服务器配置信息.上传成功后可以点击) 上传漏洞是指用户上传了一个 ...

  8. web安全之文件上传漏洞

    成因: 当文件上传时,若服务端脚本语言未对上传的文件进行严格验证和过滤,若恶意用户上传恶意的 脚本文件时,就有可能控制整个网站甚至是服务器,这就是文件上传漏洞. 权限: 1. 后台权限:登陆了后台,可 ...

  9. WEB漏洞——文件上传

    有关文件上传的知识 为什么文件上传存在漏洞 上传文件时,如果服务端代码未对客户端上传的文件进行严格的验证和过滤就容易造成可以上传任意文件的情況,包括上传脚本文件(asp.aspx.php.jsp等格式 ...

  10. 24:WEB漏洞-文件上传之WAF绕过及安全修复

    本课重点 案例1:上传数据包参数对应修改测试 案例2:safedog+云服务器+uploadlabs测试 案例3:safedog+云服务器+uploadlabs_fuzz测试 案例4:文件上传安全修复 ...

随机推荐

  1. json和字典dict的区别

    json和字典dict的区别? 银河有希子关注 2021.07.03 11:13:00字数 987阅读 173 作者:Gakki json和字典dict的区别? 字典写法:dict1 = {'Alic ...

  2. operation not supported on selected printer

    operation not supported on selected printer 版本原因 解决办法, 每次打印前先选择一次打印机属性,弹窗点确认还是取消都行,最后返回再点打印即可

  3. SQL生成序号的四种方式

    排名函数是SQL SERVER2005新增的函数.排名函数总共有四种,分别是:row_number.rank. dense_rank .ntile. row_number:顺序生成序号. rank:相 ...

  4. 顶级生物信息学 RSS 订阅源

    早在 2018 年的时候我在"生信草堂"的公众号上写过一篇关于 RSS 的文章<使用 RSS 打造你的科研资讯头条>,介绍了关于 RSS 的一些内容和如何使用 inor ...

  5. 在 Linux 上给用户赋予指定目录的读写权限

    在 Linux 上指定目录的读写权限赋予用户,有两种方法可以实现这个目标:第一种是使用 ACL (访问控制列表),第二种是创建用户组来管理文件权限,下面会一一介绍.为了完成这个教程,我们将使用以下设置 ...

  6. 【RS】多光谱波段和全色波段的区别

    <p><strong>1.全色波段(Panchromatic Band)</strong></p> 全色图像是单通道的(即单波段灰色影像),其中全色是指 ...

  7. 【Python&GIS】矢量数据投影转换(WGS84转地方坐标系)

         又是掉头发的一天,今天的任务是将WGS84坐标系的点转成地方坐标系,并判断点是否在某个面内,找了半天的资料什么四参数.七参数啥的太复杂了.这里使用Python的ogr, osr库内置的坐标转 ...

  8. Kubernetes(k8s)使用ingress发布服务

    目录 一.系统环境 二.前言 三.Kubernetes ingress简介 四.Ingress vs NodePort vs LoadBalancer 五.安装部署Nginx Ingress Cont ...

  9. STL-set(ACM)

    1.set只能insert().erase(),没有push()等操作 2.插入的元素自动排序按从小到大的顺序排 3.不会插入相同的元素,已经插入了6,之后就不会再插入了 4.时间复杂度为 O(log ...

  10. @SuppressWarnings注解的使用

    Java编译器在编译代码时,会产生一些安全警告信息.如果被@SuppressWarnings注解标记的元素,就可以告诉编译器抑制指定的警告. 先看看@SuppressWarnings注解在Java S ...