目录
概念
一种Web应用程序漏洞,允许攻击者上传恶意文件到服务器,从而执行未授权的操作或获得对系统的控制。这种漏洞通常出现在允许用户上传文件的功能中,如头像上传、文档上传等。文件上传漏洞可以被利用来上传包含恶意代码的文件(如脚本文件),这些文件在服务器上执行时会对系统造成各种危害。
webshell
一种通过 Web 服务器执行命令的恶意脚本,通常用来在受害者的服务器上执行恶意操作。WebShell 可以用各种编程语言编写,例如 PHP、ASP、JSP、Perl 等,但最常见的是 PHP WebShell。通常会将这些asp或php后门文件与网站服务器web目录下正常的网页文件混在一起,然后使用浏览器来访问这些后门,得到一个命令执行环境,以达到控制网站服务器的目的。攻击者可以使用 WebShell 在服务器上执行命令、读取或修改文件、连接数据库,甚至获取对整个服务器的控制权。
文件上传的攻击与防御
1.前端限制
document.getElementById('uploadForm').addEventListener('submit', function (event) {
event.preventDefault(); // 阻止表单提交
const fileInput = document.getElementById('fileInput');
const errorMessage = document.getElementById('errorMessage');
const file = fileInput.files[0];
if (!file) {
errorMessage.textContent = 'Please select a file.';
errorMessage.classList.remove('hidden');
return;
}
// 允许的文件类型
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
if (!allowedTypes.includes(file.type)) {
errorMessage.textContent = 'Invalid file type. Only JPG, PNG, and GIF are allowed.';
errorMessage.classList.remove('hidden');
return;
}
// 最大文件大小(以字节为单位),例如:2MB
const maxSize = 2 * 1024 * 1024; // 2MB
if (file.size > maxSize) {
errorMessage.textContent = `File size exceeds the limit of 2MB. Your file size is ${(file.size / 1024 / 1024).toFixed(2)}MB.`;
errorMessage.classList.remove('hidden');
return;
}
errorMessage.classList.add('hidden');
// 如果所有验证都通过,则提交表单或进行其他操作
// 例如:使用 fetch API 上传文件
// let formData = new FormData();
// formData.append('file', file);
// fetch('/upload', { method: 'POST', body: formData })
// .then(response => response.json())
// .then(data => console.log(data))
// .catch(error => console.error(error));
});
原理:
在表单中使用event.preventDefault()调用js函数来检查上传文件的扩展名。当用户在客户端选择文件点击上传的时候,客户端还没有向服务器发送任何消息,就对本地文件进行检测来判断是否是可以上传的类型,这种方式称为前台脚本检测扩展名。
绕过方式:
通过浏览器开发者模式很简单的修改文件后缀名就可以完成绕过检查,或者是讲木马修改后缀名后上传,通过改包工具修改上传(抓包改包)。如果是JS脚本检测,在本地浏览器客户端禁用JS即可。可使用火狐浏览器的NoScript插件、IE中禁用掉JS等方式实现绕过。
这里可以上传一个木马,将其后缀修改为jpg,上传后拦截,用burpsuite将后缀改回php
<?php
@eval($_POST['cmd']);
?>
2.检查扩展名
使用文件被上传到服务端时,服务端会对文件名的扩展名进行检查,不合法则拒绝文件的上传操作
这里就有黑名单和白名单绕过。
黑名单绕过方法:
黑名单的原理是拒绝已知的恶意文件类型或扩展名。但由于黑名单只列出了已知的威胁,攻击者可以通过以下方法绕过黑名单:
(1)混淆文件扩展名:
方法:使用双扩展名或不常见的扩展名组合,如 shell.php.jpg。
原理:服务器可能只检查第一个扩展名 .jpg,而忽略了实际的恶意扩展名 .php。
(2)修改文件头:
方法:修改文件的 MIME 类型,使其看起来像合法文件。
原理:服务器可能通过 MIME 类型判断文件类型,如果仅依赖 MIME 类型,攻击者可以通过伪造 MIME 类型绕过检查。
(3)使用压缩文件:
方法:将恶意文件压缩成 .zip 或 .rar 文件,然后上传。
原理:如果服务器未对压缩文件内容进行扫描和检查,攻击者可以在解压后执行恶意文件。
(4)上传到临时文件夹:
方法:先上传文件到服务器的临时文件夹,然后再通过另一个请求将文件移动到目标目录。
原理:如果服务器在临时文件夹阶段不进行检查,攻击者可以利用这个漏洞。
(5)使用替代扩展名:
方法:利用服务器支持的其他脚本扩展名,如 .phtml, .phar, .php3, .php4, .php5。
原理:服务器可能未将这些替代扩展名列入黑名单,而它们同样能够执行 PHP 代码。
(6)大小写绕过:
方法:代码对.php进行拦截,未对.pHp .phP进行拦截
原理:黑名单过滤的不全面导致
白名单绕过方法:
白名单的原理是只允许已知的合法文件类型或扩展名。但由于白名单只能列出已知的合法类型,攻击者可以通过以下方法绕过白名单:
(1)嵌入恶意代码在合法文件中:
方法:将恶意代码嵌入到合法文件类型中,如将 PHP 代码嵌入到图片的 EXIF 数据中。
原理:服务器可能只检查文件的扩展名和 MIME 类型,而不检查文件的实际内容或元数据。
(2)利用支持脚本的文件类型:
方法:上传支持脚本的文件类型,如 SVG、XML、甚至 PDF,并在这些文件中嵌入恶意脚本。
原理:某些文件类型可以包含和执行脚本,攻击者可以利用这些特性进行攻击。
(3)路径穿越攻击:
方法:通过路径穿越(如 ../),将文件上传到白名单验证之外的目录。
原理:如果服务器在处理文件路径时未正确过滤路径穿越字符,攻击者可以将文件上传到任意位置。
(4)使用多部分文件:
方法:上传包含多个部分的文件,其中合法部分通过白名单检查,而恶意部分在处理时被执行。
原理:服务器在处理多部分文件时,可能只检查一个部分,而忽略其他部分的内容。
(5)混淆文件名:
方法:使用特殊字符或编码(如 Unicode)混淆文件名,使其通过白名单检查。
原理:某些字符编码在不同的系统中处理方式不同,可能导致白名单验证失效。
(6)利用不常见的合法扩展名:
方法:利用服务器支持的其他合法扩展名,如 .phtml, .phar, .php3, .php4, .php5。
原理:这些扩展名可能不在白名单中,但仍能被服务器执行。
(7)利用服务器配置漏洞:
方法:利用服务器配置漏洞,如允许 .htaccess 文件上传,修改服务器配置。
原理:攻击者可以通过上传和修改 .htaccess 文件,改变服务器行为,使其执行恶意代码。
.htaccess解析
Apache HTTP 服务器中的一个配置文件,用于提供目录级别的配置。它允许管理员通过放置该文件在目录中来配置该目录及其子目录的服务器设置。
操作方式
(1)web站点架构为:php+apache , 保证文件上传到本地 , apache开启对.htaccess支持;
(2)黑名单没有过滤.htaccess;
(3)编辑.htaccess文件,写入
//1.这将把目录下的shell.jpg的文件当做可执行的php脚本进行解析并执行。[优先]
<FilesMatch "shell.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
//2.上传后缀为.ccc的文件,让其做为php类型文件进行解析
AddType application/x-httpd-php .ccc
(4)上传一句话木马并以.jpg结尾, 写入
<?php @eval($_POST['pass']);?>
(5)菜刀或蚁剑连接
点绕过:
(1) 双重扩展名
双重扩展名是最常见的点绕过方法之一。例如,文件名为 shell.php.jpg。
原理:某些服务器只检查文件的第一个或最后一个扩展名。如果只检查最后一个扩展名 .jpg,那么 shell.php 仍然会被服务器识别为 PHP 文件并执行。
防御:严格检查所有扩展名,并限制双重扩展名的文件上传。
(2)点文件
在 Unix 系统中,点文件(如 .htaccess)通常是隐藏文件。
方法:上传一个文件名为 .htaccess 的文件,通过修改服务器配置执行恶意代码。
防御:禁止上传或执行特定的隐藏文件,并使用白名单验证文件名。
(3)路径包含点
攻击者可能会在文件路径中包含点,尝试通过路径解析漏洞绕过检查。例如, ./uploads/shell.php。
原理:某些服务器在解析路径时会忽略点或错误处理路径。
防御:使用绝对路径,并严格验证和规范化所有用户输入的路径。
Windows 系统下,文件后缀名最后一个点会被自动去除。
Linux 系统下,文件后缀名最后一个点不会被自动去除。
利用 BurpSuite 工具截断 HTTP 请求,上传文件后缀名加 .
绕过上传。
demo.php.
【demo(点)
php(点)
】 这样在windows可以绕过
Content-Type(MIME)绕过:
,Content-Type属性绕过是攻击者利用服务器对文件的Content-Type(MIME类型)验证不当,从而上传恶意文件的一种技术。
例如,攻击者可以将一个PHP文件的Content-Type设置为image/jpeg,以便服务器认为这是一个合法的图片文件,而实际上上传的是一个可以被执行的PHP脚本。
绕过方法
(1)伪造Content-Type
方法:使用开发者工具或其他手段将上传文件的Content-Type设置为合法的MIME类型(如image/jpeg),而实际上文件内容是恶意代码。
工具:可以使用Burp Suite、Postman或手动修改HTTP请求来伪造Content-Type。
比如:
POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=---------------------------boundary
Content-Length: 12345
-----------------------------boundary
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: image/jpeg
<?php echo shell_exec($_GET['cmd']); ?>
-----------------------------boundary--
(2)使用多部分表单数据
方法:利用多部分表单数据上传文件,并在其中伪造Content-Type。
原理:服务器在处理多部分表单数据时,可能只根据Content-Type判断文件类型,而忽略实际文件内容。
(3)利用文件头部伪装
方法:在文件的头部添加合法文件的签名,使其通过服务器的文件类型检查。
原理:某些服务器或文件处理器可能只检查文件头部字节而忽略其实际内容。
比如:在PHP文件头部添加jpeg文件的签名:
/* JPEG header */
echo "\xFF\xD8\xFF\xE0" . "<?php echo shell_exec($_GET['cmd']); ?>"
(4)
使用各种各样的工具(如burpsuite)强行篡改Header就可以,将Content-Type: application/php改为其他web程序允许的类型
文件头检查文件:
利用的是每一个特定类型的文件都会有不太一样的开头或者标志位。
文件格式 | 文件头 |
JPEG (jpg) | FFD8FF |
GIF (gif) | 47494638 |
ZIP Archive (zip) | 504B0304 |
Adobe Acrobat (pdf) | 255044462D312E |
绕过方法:
给上传脚本加上相应的幻数头字节,比如php引擎会将 <?之前的内容当作html文本,不解释而跳过之,后面的代码仍然能够得到执行比如下面:
/* JPEG header */
echo "\xFF\xD8\xFF" . "<?php echo shell_exec($_GET['cmd']); ?>"
二次渲染:
产生原因:
安全方面考虑,不信任用户输入、上传的任何数据、图片;索引对于用户上传的图片等信息,都需要开发人员对图片文件重新生成!
为什么进行二次渲染?
二次渲染可以过滤掉图片中掺杂的恶意的代码
二次渲染绕过:
(1)修改文件扩展名:
将恶意代码文件的扩展名修改为服务器认为安全的扩展名。例如,将 .php 文件改为 .jpg 或 .png。如果服务器只检查扩展名,而不检查文件内容,这种方法可以绕过服务器的安全检查。
将一个包含PHP代码的文件 malicious.php 重命名为 image.jpg,上传到服务器。如果服务器不检查文件内容,文件会被存储为 image.jpg,但实际包含可执行的PHP代码
(2)双重扩展名:
使用双重扩展名(例如 file.jpg.php)来混淆服务器的文件类型检查。某些服务器在处理文件名时,可能会忽略第二个扩展名,从而错误地认为这是一个图片文件,但实际上是一个PHP脚本。
创建一个文件 exploit.jpg.php,其中包含恶意PHP代码。如果服务器只检查第一个扩展名 jpg,文件会被允许上传,但服务器在处理时仍会将其作为PHP脚本执行。
(3)文件内容混淆:
在文件内容中混淆恶意代码,使其不易被安全扫描工具检测。例如,将恶意代码嵌入图片文件的元数据部分,或使用Base64编码等方式隐藏代码。
将恶意JavaScript代码嵌入到图片文件的EXIF元数据中。当图片在客户端渲染时,JavaScript代码可能会被执行。
(4)特殊字符和编码方式:
利用特殊字符或编码方式,例如 %00 字符(空字节)截断文件名,使得服务器在处理文件名时出现解析错误,从而绕过安全检测。
上传一个文件名为 example%00.jpg 的文件,服务器可能会将其识别为图片文件 example,但实际包含的内容可能会被解析并执行。
(5)文件内部脚本:
在允许上传HTML或文本文件的情况下,将恶意JavaScript或其他脚本代码嵌入文件中。如果这些文件在客户端被直接渲染,会导致恶意代码执行
参考: