skeeto / endlessh

SSH tarpit that slowly sends an endless banner
The Unlicense
7.29k stars 280 forks source link

Spoof OpenSSH fingerprint when scanned with Nmap #12

Closed phra closed 5 years ago

phra commented 5 years ago

Hi,

it would be nice if the service will be recognized as a regular OpenSSH server when scanned with Nmap.

At the moment, the output is:

nmap -T4 -sS -sV --reason -v -p 2222 --send-ip localhost                                                                     0|14:38:42
Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-25 14:38 CET
NSE: Loaded 43 scripts for scanning.
Initiating SYN Stealth Scan at 14:38
Scanning localhost (127.0.0.1) [1 port]
Discovered open port 2222/tcp on 127.0.0.1
Completed SYN Stealth Scan at 14:38, 0.03s elapsed (1 total ports)
Initiating Service scan at 14:38
Scanning 1 service on localhost (127.0.0.1)
Completed Service scan at 14:41, 151.12s elapsed (1 service on 1 host)
NSE: Script scanning 127.0.0.1.
Initiating NSE at 14:41
Completed NSE at 14:41, 0.01s elapsed
Initiating NSE at 14:41
Completed NSE at 14:41, 1.02s elapsed
Nmap scan report for localhost (127.0.0.1)
Host is up, received localhost-response (0.000045s latency).
Other addresses for localhost (not scanned): ::1

PORT     STATE SERVICE       REASON         VERSION
2222/tcp open  EtherNetIP-1? syn-ack ttl 64
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port2222-TCP:V=7.70%I=7%D=3/25%Time=5C98D9EF%P=x86_64-pc-linux-gnu%r(NU
SF:LL,6,"\+EwB\r\n")%r(GenericLines,6,"\+EwB\r\n")%r(GetRequest,E,"zb-mT\?
SF:&\)\.\?A2\r\n")%r(RTSPRequest,10,"k}6\*IZ/\\7SXZ!@\r\n")%r(DNSVersionBi
SF:ndReqTCP,7,"@nkHd\r\n")%r(Help,1D,"-\(asQy!#,r\\IalJ,dWp9i>Zc-Ou\r\n")%
SF:r(TLSSessionReq,12,"RX9yPFnKv3\^MJypE\r\n")%r(FourOhFourRequest,20,"c-\
SF:.>jnD;Gb\[dj53B=\^y6Gy`H>xn}\)`\r\n")%r(SIPOptions,C,"m3aM;w#FB\$\r\n")
SF:%r(TerminalServer,8,"\.z\*en~\r\n")%r(NotesRPC,10,"LN}w\|,\^KUc,LB}\r\n
SF:")%r(WMSRequest,C,"!H4Py\(Yc!U\r\n")%r(giop,1D,"rw!k\x20@2#2pt\+>qC2\.5
SF:c;nq-fM2w\r\n");

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 152.59 seconds
           Raw packets sent: 1 (44B) | Rcvd: 2 (88B)

A simple test shows that sending an initial banner with a default OpenSSH response does the trick:

echo 'SSH-2.0-OpenSSH_7.9p1 Debian-9' | nc -lvvp 2222

This will result in the following Nmap output:

nmap -T4 -sS -sV --reason -v -p 2222 --send-ip localhost                                                                     0|14:41:21
Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-25 14:48 CET
NSE: Loaded 43 scripts for scanning.
Initiating SYN Stealth Scan at 14:48
Scanning localhost (127.0.0.1) [1 port]
Discovered open port 2222/tcp on 127.0.0.1
Completed SYN Stealth Scan at 14:48, 0.03s elapsed (1 total ports)
Initiating Service scan at 14:48
Scanning 1 service on localhost (127.0.0.1)
Completed Service scan at 14:48, 0.00s elapsed (1 service on 1 host)
NSE: Script scanning 127.0.0.1.
Initiating NSE at 14:48
Completed NSE at 14:48, 0.00s elapsed
Initiating NSE at 14:48
Completed NSE at 14:48, 0.00s elapsed
Nmap scan report for localhost (127.0.0.1)
Host is up, received localhost-response (0.000036s latency).
Other addresses for localhost (not scanned): ::1

PORT     STATE SERVICE REASON         VERSION
2222/tcp open  ssh     syn-ack ttl 64 OpenSSH 7.9p1 Debian 9 (protocol 2.0)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 0.41 seconds
           Raw packets sent: 1 (44B) | Rcvd: 2 (88B)
skeeto commented 5 years ago

As noted in my article:

Endlessh: an SSH Tarpit https://nullprogram.com/blog/2019/03/22/

The "SSH-" version string marks the end of the protocol version exchange, and so no "other lines of data" can follow. Endlessh is exploiting those extra lines. To satisfy nmap's probe, it would need to implement more of the SSH protocol and establish the tarpit at a later point instead. I don't really want to take it that far.

Technically nmap is being a bit too rigid by expecting the version string to be the first line, but that decision is by far the most practical. That's how real servers behave, and strictly following the protocol would get it stuck in such tarpits. The scan isn't intended to be 100% precise anyway.

Attackers looking to brute force password attempts have to tolerate at least some "other lines of data" because, otherwise, adding a single extra line would be enough to keep them out.

phra commented 5 years ago

Yes, I confirm the cited behavior. I tried to fuzz the cipher list but without success:

$ time ssh localhost -p2222
Bad packet length 1397966893.
ssh_dispatch_run_fatal: Connection to ::1 port 2222: message authentication code incorrect

real    9m35.597s
user    0m0.009s
sys     0m0.001s