文件上传漏洞(File upload vulnerabilities)
-
什么是文件上传漏洞?
What are file upload vulnerabilities?文件上传漏洞是指 Web 服务器允许用户将文件上传到其文件系统,而无需充分验证其名称、类型、内容或大小等内容。如果不能正确执行这些限制,则可能意味着即使是基本的图像上传功能也可能被用来上传任意和可能危险的文件。这甚至可能包括启用远程代码执行的服务器端脚本文件。
File upload vulnerabilities are when a web server allows users to upload files to its filesystem without sufficiently validating things like their name, type, contents, or size. Failing to properly enforce restrictions on these could mean that even a basic image upload function can be used to upload arbitrary and potentially dangerous files instead. This could even include server-side script files that enable remote code execution.在某些情况下,上传文件的行为本身就足以造成损害。其他攻击可能涉及对文件的后续 HTTP 请求,通常是为了触发服务器执行该文件。
In some cases, the act of uploading the file is in itself enough to cause damage. Other attacks may involve a follow-up HTTP request for the file, typically to trigger its execution by the server.文件上传漏洞会带来什么影响?
What is the impact of file upload vulnerabilities?文件上传漏洞的影响通常取决于两个关键因素:
The impact of file upload vulnerabilities generally depends on two key factors:- 网站未能正确验证文件的哪个方面,无论是其大小、类型、内容等。(Which aspect of the file the website fails to validate properly, whether that be its size, type, contents, and so on.)
- 成功上传文件后,将对文件施加哪些限制。(What restrictions are imposed on the file once it has been successfully uploaded.)
在最坏的情况下,文件的类型未得到正确验证,并且服务器配置允许某些类型的文件(如 .php和.jsp )作为代码执行。在这种情况下,攻击者可能会上传一个服务器端代码文件,该文件充当 Web Shell,从而有效地授予他们对服务器的完全控制权。
(In the worst case scenario, the file's type isn't validated properly, and the server configuration allows certain types of file (such as .php and .jsp) to be executed as code. In this case, an attacker could potentially upload a server-side code file that functions as a web shell, effectively granting them full control over the server.)如果文件名未正确验证,攻击者可能仅通过上传同名文件来覆盖关键文件。如果服务器也容易受到目录遍历的攻击,这可能意味着攻击者甚至能够将文件上传到意想不到的位置。
If the filename isn't validated properly, this could allow an attacker to overwrite critical files simply by uploading a file with the same name. If the server is also vulnerable to directory traversal, this could mean attackers are even able to upload files to unanticipated locations.如果未能确保文件大小在预期的阈值范围内,还可能启用某种形式的拒绝服务 (DoS) 攻击,攻击者会填充可用的磁盘空间。
Failing to make sure that the size of the file falls within expected thresholds could also enable a form of denial-of-service (DoS) attack, whereby the attacker fills the available disk space.文件上传漏洞是如何出现的?
How do file upload vulnerabilities arise?鉴于相当明显的危险,野外的网站很少对允许用户上传的文件没有任何限制。更常见的是,开发人员实施了他们认为是稳健的验证,这些验证要么存在固有缺陷,要么很容易绕过。
(Given the fairly obvious dangers, it's rare for websites in the wild to have no restrictions whatsoever on which files users are allowed to upload. More commonly, developers implement what they believe to be robust validation that is either inherently flawed or can be easily bypassed.)例如,他们可能试图将危险文件类型列入黑名单,但在检查文件扩展名时未能考虑解析差异。与任何黑名单一样,也很容易意外地遗漏可能仍然危险的更晦涩的文件类型。
(For example, they may attempt to blacklist dangerous file types, but fail to account for parsing discrepancies when checking the file extensions. As with any blacklist, it's also easy to accidentally omit more obscure file types that may still be dangerous.)在其他情况下,该网站可能会尝试通过验证攻击者可以使用 Burp Proxy 或 Repeater 等工具轻松操纵的属性来检查文件类型。
(In other cases, the website may attempt to check the file type by verifying properties that can be easily manipulated by an attacker using tools like Burp Proxy or Repeater.)最终,即使是强大的验证措施也可能在构成网站的主机和目录网络中不一致地应用,从而导致可以利用的差异。
(Ultimately, even robust validation measures may be applied inconsistently across the network of hosts and directories that form the website, resulting in discrepancies that can be exploited.)Web 服务器如何处理对静态文件的请求?
How do web servers handle requests for static files?在我们了解如何利用文件上传漏洞之前,您必须对服务器如何处理静态文件的请求有基本的了解。
Before we look at how to exploit file upload vulnerabilities, it's important that you have a basic understanding of how servers handle requests for static files.
从历史上看,网站几乎完全由静态文件组成,这些文件将在用户请求时提供给用户。因此,每个请求的路径都可以与服务器文件系统上的目录和文件层次结构 1:1 映射。如今,网站的动态性越来越强,请求的路径通常与文件系统根本没有直接关系。尽管如此,Web 服务器仍然会处理对一些静态文件的请求,包括样式表、图像等。
Historically, websites consisted almost entirely of static files that would be served to users when requested. As a result, the path of each request could be mapped 1:1 with the hierarchy of directories and files on the server's filesystem. Nowadays, websites are increasingly dynamic and the path of a request often has no direct relationship to the filesystem at all. Nevertheless, web servers still deal with requests for some static files, including stylesheets, images, and so on.处理这些静态文件的过程在很大程度上仍然是相同的。在某些时候,服务器会分析请求中的路径以识别文件扩展名。然后,它使用它来确定所请求文件的类型,通常是将其与扩展名和 MIME 类型之间的预配置映射列表进行比较。接下来会发生什么取决于文件类型和服务器的配置。
The process for handling these static files is still largely the same. At some point, the server parses the path in the request to identify the file extension. It then uses this to determine the type of the file being requested, typically by comparing it to a list of preconfigured mappings between extensions and MIME types. What happens next depends on the file type and the server's configuration.- 如果此文件类型是不可执行的,例如图像或静态 HTML 页面,则服务器可能只是在 HTTP 响应中将文件的内容发送到客户端。(If this file type is non-executable, such as an image or a static HTML page, the server may just send the file's contents to the client in an HTTP response.)
- 如果文件类型是可执行的,例如PHP文件,并且服务器配置为执行此类型的文件,则在运行脚本之前,它将根据HTTP请求中的标头和参数分配变量。然后,可以将生成的输出以 HTTP 响应的形式发送到客户端。(If the file type is executable, such as a PHP file, and the server is configured to execute files of this type, it will assign variables based on the headers and parameters in the HTTP request before running the script. The resulting output may then be sent to the client in an HTTP response.)
- 如果文件类型是可执行的,但服务器未配置为执行此类型的文件,则它通常会以错误进行响应。但是,在某些情况下,文件的内容仍可能以纯文本形式提供给客户端。这种错误配置有时可能会被利用来泄露源代码和其他敏感信息。您可以在我们的信息披露学习材料中看到一个示例。(If the file type is executable, but the server is not configured to execute files of this type, it will generally respond with an error. However, in some cases, the contents of the file may still be served to the client as plain text. Such misconfigurations can occasionally be exploited to leak source code and other sensitive information. You can see an example of this in our information disclosure learning materials.)
Tip Content-Type 响应标头可以提供有关服务器认为已提供的文件类型的线索。如果应用程序代码未显式设置此标头,则它通常包含文件扩展名/MIME 类型映射的结果。 The Content-Type response header may provide clues as to what kind of file the server thinks it has served. If this header hasn't been explicitly set by the application code, it normally contains the result of the file extension/MIME type mapping.
现在,您已经熟悉了关键概念,让我们看看如何潜在地利用这些类型的漏洞。
Now that you're familiar with the key concepts, let's look at how you can potentially exploit these kinds of vulnerabilities. -
利用不受限制的文件上传来部署 Web Shell
Exploiting unrestricted file uploads to deploy a web shell从安全角度来看,最坏的情况是网站允许您上传服务器端脚本,例如 PHP、Java 或 Python 文件,并且还配置为将它们作为代码执行。这使得在服务器上创建自己的 Web shell 变得微不足道。
From a security perspective, the worst possible scenario is when a website allows you to upload server-side scripts, such as PHP, Java, or Python files, and is also configured to execute them as code. This makes it trivial to create your own web shell on the server.Web shell Web Shell 是一种恶意脚本,攻击者只需将 HTTP 请求发送到正确的端点,就可以在远程 Web 服务器上执行任意命令。 A web shell is a malicious script that enables an attacker to execute arbitrary commands on a remote web server simply by sending HTTP requests to the right endpoint.
如果您能够成功上传 Web Shell,则您实际上对服务器拥有完全控制权。这意味着您可以读取和写入任意文件,泄露敏感数据,甚至使用服务器对内部基础设施和网络外部的其他服务器进行攻击。例如,以下 PHP 单行代码可用于从服务器的文件系统中读取任意文件:
If you're able to successfully upload a web shell, you effectively have full control over the server. This means you can read and write arbitrary files, exfiltrate sensitive data, even use the server to pivot attacks against both internal infrastructure and other servers outside the network. For example, the following PHP one-liner could be used to read arbitrary files from the server's filesystem:<?php echo file_get_contents('/path/to/target/file'); ?>
上传后,发送对此恶意文件的请求将在响应中返回目标文件的内容。
Once uploaded, sending a request for this malicious file will return the target file's contents in the response.一个更通用的 Web Shell 可能看起来像这样:
A more versatile web shell may look something like this:<?php echo system($_GET['command']); ?>
此脚本使您能够通过查询参数传递任意系统命令,如下所示:
This script enables you to pass an arbitrary system command via a query parameter as follows:GET /example/exploit.php?command=id HTTP/1.1
Lab: Remote code execution via web shell upload
This lab contains a vulnerable image upload function. It doesn't perform any validation on the files users upload before storing them on the server's filesystem.
To solve the lab, upload a basic PHP web shell and use it to exfiltrate the contents of the file /home/carlos/secret. Submit this secret using the button provided in the lab banner.
You can log in to your own account using the following credentials: wiener:peter
实验步骤:
编写记事本修改后缀
上传php文档
修改报文头
GET /files/avatars/exploit.php HTTP/1.1
-
利用有缺陷的文件上传验证
Exploiting flawed validation of file uploads在野外,您不太可能找到一个没有像我们在上一个实验室中看到的那样无法抵御文件上传攻击的网站。但是,仅仅因为防御措施已经到位,并不意味着它们是强大的。有时,您仍然可以利用这些机制中的缺陷来获取用于远程代码执行的 Web shell。
In the wild, it's unlikely that you'll find a website that has no protection against file upload attacks like we saw in the previous lab. But just because defenses are in place, that doesn't mean that they're robust. You can sometimes still exploit flaws in these mechanisms to obtain a web shell for remote code execution.有缺陷的文件类型验证
Flawed file type validation提交 HTML 表单时,浏览器通常会在POST请求中发送提供的数据,其内容类型为application/x-www-form-url-encoded。这对于发送简单的文本(例如您的姓名或地址)非常有用。但是,它不适合发送大量二进制数据,例如整个图像文件或 PDF 文档。在这种情况下,multipart/form-data内容类型是首选。
When submitting HTML forms, the browser typically sends the provided data in a POST request with the content type application/x-www-form-url-encoded. This is fine for sending simple text like your name or address. However, it isn't suitable for sending large amounts of binary data, such as an entire image file or a PDF document. In this case, the content type multipart/form-data is preferred.考虑一个表单,其中包含用于上传图像、提供图像描述和输入用户名的字段。提交此类表单可能会导致请求如下所示:
Consider a form containing fields for uploading an image, providing a description of it, and entering your username. Submitting such a form might result in a request that looks something like this:POST /images HTTP/1.1 Host: normal-website.com Content-Length: 12345 Content-Type: multipart/form-data; boundary=---------------------------012345678901234567890123456 ---------------------------012345678901234567890123456 Content-Disposition: form-data; name="image"; filename="example.jpg" Content-Type: image/jpeg [...binary content of example.jpg...] ---------------------------012345678901234567890123456 Content-Disposition: form-data; name="description" This is an interesting description of my image. ---------------------------012345678901234567890123456 Content-Disposition: form-data; name="username" wiener ---------------------------012345678901234567890123456--
如您所见,对于表单的每个输入,消息正文被拆分为单独的部分。每个部分都包含一个Content-Disposition标题,该标题提供有关其相关的输入字段的一些基本信息。这些单独的部分也可能包含它们自己的Content-Type标头,该标头告诉服务器使用此输入提交的数据的 MIME 类型。
As you can see, the message body is split into separate parts for each of the form's inputs. Each part contains a Content-Disposition header, which provides some basic information about the input field it relates to. These individual parts may also contain their own Content-Type header, which tells the server the MIME type of the data that was submitted using this input.网站可能尝试验证文件上传的一种方法是检查此特定于输入的Content-Type标头是否与预期的 MIME 类型匹配。例如,如果服务器只需要图像文件,则它可能只允许像image/jpeg和image/png 这样的类型。当服务器隐式信任此标头的值时,可能会出现问题。如果没有执行进一步的验证来检查文件的内容是否真的与假定的 MIME 类型匹配,则可以使用 Burp Repeater 等工具轻松绕过此防御。
One way that websites may attempt to validate file uploads is to check that this input-specific Content-Type header matches an expected MIME type. If the server is only expecting image files, for example, it may only allow types like image/jpeg and image/png. Problems can arise when the value of this header is implicitly trusted by the server. If no further validation is performed to check whether the contents of the file actually match the supposed MIME type, this defense can be easily bypassed using tools like Burp Repeater.实验步骤
修改报文类型image/jpeg
文件上传成功
修改请求
-
防止在用户可访问的目录中执行文件
Preventing file execution in user-accessible directories虽然首先防止上传危险文件类型显然更好,但第二道防线是阻止服务器执行任何从网络中溜走的脚本。
While it's clearly better to prevent dangerous file types being uploaded in the first place, the second line of defense is to stop the server from executing any scripts that do slip through the net.作为预防措施,服务器通常只运行其 MIME 类型已明确配置为执行的脚本。否则,它们可能只是返回某种错误消息,或者在某些情况下,以纯文本形式提供文件的内容:
As a precaution, servers generally only run scripts whose MIME type they have been explicitly configured to execute. Otherwise, they may just return some kind of error message or, in some cases, serve the contents of the file as plain text instead:GET /static/exploit.php?command=id HTTP/1.1 Host: normal-website.com HTTP/1.1 200 OK Content-Type: text/plain Content-Length: 39 <?php echo system($_GET['command']); ?>
这种行为本身可能很有趣,因为它可能提供了一种泄露源代码的方法,但它使任何创建 Web shell 的尝试无效。
This behavior is potentially interesting in its own right, as it may provide a way to leak source code, but it nullifies any attempt to create a web shell.这种配置在目录之间通常有所不同。用户提供的文件上传到的目录可能比文件系统上的其他位置具有更严格的控制,而这些位置被认为是最终用户无法触及的。如果您能找到一种方法将脚本上传到不应包含用户提供的文件的不同目录,那么服务器可能会执行您的脚本。
This kind of configuration often differs between directories. A directory to which user-supplied files are uploaded will likely have much stricter controls than other locations on the filesystem that are assumed to be out of reach for end users. If you can find a way to upload a script to a different directory that's not supposed to contain user-supplied files, the server may execute your script after all.Tip Web 服务器通常在 multipart/form-data 请求中使用 filename 字段来确定应保存文件的名称和位置。 Web servers often use the filename field in multipart/form-data requests to determine the name and location where the file should be saved.
您还应该注意,即使您可以将所有请求发送到同一域名,但这通常指向某种类型的反向代理服务器,例如负载均衡器。您的请求通常会由后台的其他服务器处理,这些服务器的配置也可能有所不同。
You should also note that even though you may send all of your requests to the same domain name, this often points to a reverse proxy server of some kind, such as a load balancer. Your requests will often be handled by additional servers behind the scenes, which may also be configured differently.Lab: Web shell upload via path traversal
This lab contains a vulnerable image upload function. The server is configured to prevent execution of user-supplied files, but this restriction can be bypassed by exploiting a secondary vulnerability.
To solve the lab, upload a basic PHP web shell and use it to exfiltrate the contents of the file /home/carlos/secret. Submit this secret using the button provided in the lab banner.
You can log in to your own account using the following credentials: wiener:peter
实验步骤:
先上传文件
随后请求出现如下报文
HTTP/2 200 OK Date: Fri, 16 Aug 2024 06:39:14 GMT Server: Apache/2.4.41 (Ubuntu) Last-Modified: Fri, 16 Aug 2024 06:28:56 GMT Etag: "37-61fc712e706df" Accept-Ranges: bytes X-Frame-Options: SAMEORIGIN Content-Length: 55 <?php echo file_get_contents('/home/carlos/secret'); ?>
表明搜寻不到这个文件
打开lab,尝试通过路径遍历上传文件,发现路径遍历序列(../)被过滤了
尝试对路径遍历序列进行url编码,发现上传成功- . 的URL编码 %2E
- / 的URL编码 %2F
因为上传的是../,读取上传的文件,注意路径是上一级目录
-
危险文件类型的黑名单不足
Insufficient blacklisting of dangerous file types防止用户上传恶意脚本的更明显的方法之一是将可能危险的文件扩展名(如.php )列入黑名单。列入黑名单的做法本身就存在缺陷,因为很难明确阻止可用于执行代码的每个可能的文件扩展名。有时,可以使用鲜为人知的替代文件扩展名(例如.php5 、.shtm 等)来绕过此类黑名单,这些扩展名可能仍是可执行的。
One of the more obvious ways of preventing users from uploading malicious scripts is to blacklist potentially dangerous file extensions like .php. The practice of blacklisting is inherently flawed as it's difficult to explicitly block every possible file extension that could be used to execute code. Such blacklists can sometimes be bypassed by using lesser known, alternative file extensions that may still be executable, such as .php5, .shtml, and so on.覆盖服务器配置
Overriding the server configuration正如我们在上一节中所讨论的,服务器通常不会执行文件,除非它们已被配置为这样做。例如,在Apache服务器执行客户端请求的PHP文件之前,开发人员可能必须将以下指令添加到他们的文件中:/etc/apache2/apache2.conf
As we discussed in the previous section, servers typically won't execute files unless they have been configured to do so. For example, before an Apache server will execute PHP files requested by a client, developers might have to add the following directives to their /etc/apache2/apache2.conf file:LoadModule php_module /usr/lib/apache2/modules/libphp.so AddType application/x-httpd-php .php
许多服务器还允许开发人员在各个目录中创建特殊配置文件,以便覆盖或添加到一个或多个全局设置中。例如,Apache 服务器将从一个名为.htaccess(如果存在)的文件加载特定于目录的配置。
Many servers also allow developers to create special configuration files within individual directories in order to override or add to one or more of the global settings. Apache servers, for example, will load a directory-specific configuration from a file called .htaccess if one is present.同样,开发人员可以使用web.config文件在 IIS 服务器上进行特定于目录的配置。这可能包括如下指令,在本例中,这些指令允许向用户提供 JSON 文件:
Similarly, developers can make directory-specific configuration on IIS servers using a web.config file. This might include directives such as the following, which in this case allows JSON files to be served to users:<staticContent> <mimeMap fileExtension=".json" mimeType="application/json" /> </staticContent>
Web 服务器使用这些类型的配置文件(如果存在),但通常不允许使用 HTTP 请求访问它们。但是,您偶尔可能会发现服务器无法阻止您上传自己的恶意配置文件。在这种情况下,即使您需要的文件扩展名被列入黑名单,您也可能能够欺骗服务器将任意的自定义文件扩展名映射到可执行的 MIME 类型。
Web servers use these kinds of configuration files when present, but you're not normally allowed to access them using HTTP requests. However, you may occasionally find servers that fail to stop you from uploading your own malicious configuration file. In this case, even if the file extension you need is blacklisted, you may be able to trick the server into mapping an arbitrary, custom file extension to an executable MIME type.web应用对用户上传的文件的扩展名做了限制,但是使用的是黑名单机制,这种情况下,我们可以尝试用以下几种方式进行绕过
- 使用不常见的后缀名:php5,pht,phpt,phtml,php3,php4,php5,php6
- 使用大小写:.pHp
- 重写服务器配置文件:apache的.htaccess或者IIS的web.config
- 使用多扩展名,譬如example.php.jpg,这种方式依赖于服务器如何解析文件,如果服务器从前往后解析,并且解析到第一个扩展名就停止解析,则该文件会被当作example.php存储
- 添加尾随字符,有些组件可能会过滤或忽视文件名末尾的空格或小数点,譬如example.php.或example.php (末尾有一个空格)
- 尝试使用url编码,譬如:example%2ephp
- 再文件扩展名前添加分号或者url编码的空字符,譬如:example.php;jpg或example.php%00.jpg
- 使用多字节Unicode字符,譬如Unicode字符序列:xC0 xAE,xC4 xAE,xC0 x2E再utf-8编码下可能转化为x2E,然后转化为ASCII字符使用
该lab使用的是apache的web容器,不解析php5后缀的文件,我们可以分两步走,第一次先上传.htaccess文件
-
Lab: Web shell upload via extension blacklist bypass
This lab contains a vulnerable image upload function. Certain file extensions are blacklisted, but this defense can be bypassed due to a fundamental flaw in the configuration of this blacklist.
To solve the lab, upload a basic PHP web shell, then use it to exfiltrate the contents of the file /home/carlos/secret. Submit this secret using the button provided in the lab banner.
You can log in to your own account using the following credentials: wiener:peter
Hint You need to upload two different files to solve this lab.
实验步骤:
实现的功能就是:所有上传的.shell文件都会被当作php文件执行
# 修改名称 .htaccess # 修改 Content-Type text/plain # 修改内容 AddType application/x-httpd-php .shell
接着上传一个后缀名为shell的文件,完成实验室任务
# 修改名称 code.shell # 修改 Content-Type image、png # 修改内容 <?php echo file_get_contents('/home/carlos/secret'); ?>
用GET语句获取即可
-
混淆文件扩展名
Obfuscating file extensions即使是最详尽的黑名单也可以使用经典的混淆技术绕过。假设验证代码区分大小写,无法识别 exploit.pHp 实际上是一个.php文件。如果随后将文件扩展名映射到 MIME 类型的代码不区分大小写,则这种差异允许您偷偷获取恶意 PHP 文件通过验证,这些验证最终可能由服务器执行。
Even the most exhaustive blacklists can potentially be bypassed using classic obfuscation techniques. Let's say the validation code is case sensitive and fails to recognize that exploit.pHp is in fact a .php file. If the code that subsequently maps the file extension to a MIME type is not case sensitive, this discrepancy allows you to sneak malicious PHP files past validation that may eventually be executed by the server.您还可以使用以下技术获得类似的结果:
You can also achieve similar results using the following techniques:提供多个扩展。根据用于解析文件名的算法,以下文件可能会被解释为 PHP 文件或 JPG 图像: exploit.php.jpg
Provide multiple extensions. Depending on the algorithm used to parse the filename, the following file may be interpreted as either a PHP file or JPG image: exploit.php.jpg
添加尾随字符。某些组件会去除或忽略尾随的空格、点等:exploit.php。
Add trailing characters. Some components will strip or ignore trailing whitespaces, dots, and suchlike: exploit.php.
尝试对点、正斜杠和反斜杠使用 URL 编码(或双 URL 编码)。如果该值在验证文件扩展名时未解码,但稍后在服务器端解码,则这也允许您上传否则会被阻止的恶意文件:exploit%2Ephp
Try using the URL encoding (or double URL encoding) for dots, forward slashes, and backward slashes. If the value isn't decoded when validating the file extension, but is later decoded server-side, this can also allow you to upload malicious files that would otherwise be blocked: exploit%2Ephp在文件扩展名前添加分号或 URL 编码的空字节字符。例如,如果验证是用高级语言(如 PHP 或 Java)编写的,但服务器使用 C/C++ 中的较低级别函数处理文件,则这可能会导致被视为文件名末尾的内容出现差异:exploit.asp;。JPG 或 exploit.asp%00.jpg
Add semicolons or URL-encoded null byte characters before the file extension. If validation is written in a high-level language like PHP or Java, but the server processes the file using lower-level functions in C/C++, for example, this can cause discrepancies in what is treated as the end of the filename: exploit.asp;.jpg or exploit.asp%00.jpg尝试使用多字节 Unicode 字符,这些字符可能会在 unicode 转换或规范化后转换为 null 字节和点。如果文件名解析为 UTF-8 字符串,则 xC0 x2E、xC4 xAE 或 xC0 xAE 等序列可能会转换为 x2E,但在路径中使用之前会转换为 ASCII 字符。
Try using multibyte unicode characters, which may be converted to null bytes and dots after unicode conversion or normalization. Sequences like xC0 x2E, xC4 xAE or xC0 xAE may be translated to x2E if the filename parsed as a UTF-8 string, but then converted to ASCII characters before being used in a path.其他防御措施包括剥离或替换危险的扩展名,以防止文件被执行。如果不以递归方式应用此转换,则可以以这样一种方式放置被禁止的字符串,即删除它仍会留下有效的文件扩展名。例如,考虑从以下文件名中删除.php时会发生什么情况:
Other defenses involve stripping or replacing dangerous extensions to prevent the file from being executed. If this transformation isn't applied recursively, you can position the prohibited string in such a way that removing it still leaves behind a valid file extension. For example, consider what happens if you strip .php from the following filename:exploit.p.phphp
这只是混淆文件扩展名的众多方法中的一小部分。
This is just a small selection of the many ways it's possible to obfuscate file extensions. -
Lab: Web shell upload via obfuscated file extension
This lab contains a vulnerable image upload function. Certain file extensions are blacklisted, but this defense can be bypassed using a classic obfuscation technique.
To solve the lab, upload a basic PHP web shell, then use it to exfiltrate the contents of the file /home/carlos/secret. Submit this secret using the button provided in the lab banner.
You can log in to your own account using the following credentials: wiener:peter
实验步骤
先正常上传php文件
该lab的目的还是对黑名单的绕过,使用多扩展名和空字符隔断来达成目的
-
文件内容的验证存在缺陷
Flawed validation of the file's contents更安全的服务器不会隐式信任请求中指定的Content-Type内容,而是尝试验证文件的内容是否确实与预期内容匹配。
Instead of implicitly trusting the Content-Type specified in a request, more secure servers try to verify that the contents of the file actually match what is expected.在图像上传功能的情况下,服务器可能会尝试验证图像的某些固有属性,例如其尺寸。例如,如果您尝试上传 PHP 脚本,它根本不会有任何维度。因此,服务器可以推断出它不可能是图像,并相应地拒绝上传。
In the case of an image upload function, the server might try to verify certain intrinsic properties of an image, such as its dimensions. If you try uploading a PHP script, for example, it won't have any dimensions at all. Therefore, the server can deduce that it can't possibly be an image, and reject the upload accordingly.同样,某些文件类型的页眉或页脚可能始终包含特定的字节序列。这些可以像指纹或签名一样使用,以确定内容是否与预期的类型匹配。例如,JPEG 文件始终以字节 FF D8 FF开头。
Similarly, certain file types may always contain a specific sequence of bytes in their header or footer. These can be used like a fingerprint or signature to determine whether the contents match the expected type. For example, JPEG files always begin with the bytes FF D8 FF.这是一种更可靠的验证文件类型的方法,但即使这样也不是万无一失的。使用特殊工具(例如 ExifTool),在其元数据中创建包含恶意代码的多语言 JPEG 文件可能很简单。
This is a much more robust way of validating the file type, but even this isn't foolproof. Using special tools, such as ExifTool, it can be trivial to create a polyglot JPEG file containing malicious code within its metadata.