Tuesday 21 December 2010

Transport layer protocols for stealth and evil

Ever tested some of the more exotic transport protocols?

SCTP is interesting ... multihoming means you can have several ips involved on each side of a connection (association in sctp speak) ... so when you move from wired to wireless your ssh session still is fine. If you find a proper SCTP ssh, of course.

Testing it on Ubuntu LTS, though, using socat for glue... a listening SCTP socket is invisible in netstat -ln. Fun. tcp, udp, raw sockets are visible ... but sctp isn't.

socat SCTP-LISTEN:8080,fork TCP-CONNECT:localhost:22

Nice, stealthy backdoor. Does not show in netstat(8) or ss(8). Combine with socat TCP-LISTEN:2223 SCTP-CONNECT:localhost:8080 on a remote host and we have a completely stealthy tunnel, if the firewall is mildly clue-challenged.

knan@ip:~$ netstat -ln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:4949            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN     
udp        0      0 0.0.0.0:68              0.0.0.0:*                          
udp        0      0 0.0.0.0:36558           0.0.0.0:*                          
udp        0      0 0.0.0.0:5353            0.0.0.0:*                          
udp        0      0 0.0.0.0:631             0.0.0.0:*                          
udp        0      0 0.0.0.0:45561           0.0.0.0:*                          
knan@ip:~$ 

lsof reports a mysterious socket. But it also does that for udev and update-manager, so that's hardly conclusive.

knan@ip:~$ lsof | grep socat | grep sock
socat 24969 knan 3u sock 0,6 0t0 645716 can't identify protocol


The only place I've dug out useful info so far is from procfs.
knan@ip:~$ cat /proc/net/sctp/eps 
 ENDPT     SOCK   STY SST HBKT LPORT   UID INODE LADDRS
ffff8800722cb800 ffff8800342c8480 2   10  16   8080   1001 645716 0.0.0.0 

Hardly easy to read. But it says LADDRS 0.0.0.0, LPORT 8080. Ok.

(BTW: SCTP not being in netstat is a Debian/Ubuntu-specific bug, SuSE/Red Hat have applied patches.)

sctp_darn(1) can do more fun sctp-specific stuff, like setting up multiple local and remote addresses for the association.

Cool enough. But there are other fun transport protocols we can try.

How about DCCP? It's connection-oriented and has congestion control but otherwise is UDP-like.

netsend dccp receive
knan@ip:~$ netstat -ln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:4949            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN     
tcp6       0      0 :::22                   :::*                    LISTEN     
tcp6       0      0 ::1:631                 :::*                    LISTEN     
udp        0      0 0.0.0.0:68              0.0.0.0:*                          
udp        0      0 0.0.0.0:36558           0.0.0.0:*                          
udp        0      0 0.0.0.0:5353            0.0.0.0:*                          
udp        0      0 0.0.0.0:631             0.0.0.0:*                          
udp        0      0 0.0.0.0:45561           0.0.0.0:*
Netstat still says nothing.

The only place in /proc/net you find DCCP mentioned is in /proc/net/protocols. Which says nothing about ongoing connections or listening sockets.

knan@ip:~$ grep -ir DCCP /proc/net/
/proc/net/protocols:DCCP 1400 1 -1 NI 1196 yes dccp_ipv4 y y y y y y y y y y y y n n y y y y n


lsof still says little.
knan@ip:~$ lsof | grep netsend | grep sock
netsend 25376 knan 3u sock 0,6 0t0 658124 can't identify protocol


ss(8) to the rescue! But only when you specifically ask it about DCCP sockets with -d.

knan@ip:~$ ss -ldn
Recv-Q Send-Q                              Local Address:Port                                Peer Address:Port 
0      0                                               *:6666                                           *:*     

The final protocol I want to propose today is UDP-Lite. This is basically a UDP variant with partial checksums, for the case when garbled data is better than no data.

$ netsend udplite receive

As usual, netstat tells us nothing of this uncommon activity.

knan@ip:~$ netstat -ln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:4949            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN     
tcp6       0      0 :::22                   :::*                    LISTEN     
tcp6       0      0 ::1:631                 :::*                    LISTEN     
udp        0      0 0.0.0.0:68              0.0.0.0:*                          
udp        0      0 0.0.0.0:36558           0.0.0.0:*                          
udp        0      0 0.0.0.0:5353            0.0.0.0:*                          
udp        0      0 0.0.0.0:631             0.0.0.0:*                          
udp        0      0 0.0.0.0:45561           0.0.0.0:*                          

This time, though, lsof identifies it!

knan@ip:~$ lsof | grep netsend
netsend 25461 knan 3u IPv4 661633 0t0 UDPLITE *:6666


Which is good, since ss doesn't.

To summarize (for Ubuntu 10.04 LTS):

Protocolnetstat(8)ss(8)lsof(8)/proc/net/*
SCTPNoNoNo/proc/net/sctp/eps
/proc/net/sctp6/eps
DCCPNoYes (-d)NoNo
UDP-LiteNoNoYes/proc/net/udplite
/proc/net/udplite6

Hope this leaves you entertained by the possibilities. Black hats begone!

P.S.
launchpad:netstat+sctp
launchpad:lsof+sctp
launchpad:lsof+dccp

2 comments:

Richard Bejtlich said...

Great post! I just checked FreeBSD 8.x and found netstat has SCTP reporting:

Active SCTP associations (including servers)
Proto Type Local Address Foreign Address (state)
sctp 1to1 10.12.1.4.8080 LISTEN
127.0.0.1.8080

Erik Inge Bolsø said...

Interesting. How about lsof on FreeBSD?