Tuesday, 29 July 2014

Transport layer for stealth and evil, 2014 edition

A few years ago, I tested some obscure transport protocols on Ubuntu 10.04 and whether you could find processes listening for them on your system. Answer was - it depends.

Fast forward a few years, RHEL7 and CentOS 7 appears. Long-deprecated netstat is gone from the default install.

So let's repeat the tests for weird backdoors.

SCTP

yum install socat
socat SCTP-LISTEN:8080 TCP-CONNECT:22

ss(8) is the official replacement for netstat(8).

So what does ss see?

# ss -anp | grep socat
#

Nothing. netstat used to see this on Red Hat-derived distros, so a slight regression you might say. But ss didn't see it in 2010 either.

Lsof has improved, though, and identifies it correctly this time.
 # lsof | grep socat
socat 10790 root 3u sock 30501 0t0 SCTP ENDPT:ffff88003b23df00 0.0.0.0[8080]
#

DCCP

Well, first we need to get netsend up and running. Basically yum install gcc, and get the source from the ubuntu package. The original berlios upstream seems to be gone.

# netsend dccp receive

This sets up a listener at dccp port 6666.

# ss -anp | grep netsend
tcp LISTEN 0 0 *:6666 users:((netsend,11050,3))
#

Um, yes, it shows up ... but looks like a TCP socket? WTF?

telnet localhost 6666
gives connection refused as expected. This will definitely confuse somebody.

# ss -anpd
LISTEN 0 0 *:6666
users:((netsend,11050,3))

So with the -d option (for dccp) it shows sane data.

What about lsof then?
# lsof | grep netsend
netsend 11050 root 3u sock 0,6 0t0 33020 protocol: DCCP

Well, better than before. It at least identifies the protocol, if not the details.

UDP-Lite

This massively popular protocol then?

# netsend udplite receive

Sets up a listener at port 6666, again.

# ss -anp | grep netsend
#

Blank, as in 2010. And there's no udplite option.

lsof then?

# lsof | grep netsend
netsend 17664 root 3u IPv4 38944 0t0 UDPLITE *:6666
#

Yeah, no problem, identifies it perfectly.

Conclusion

Hiding a backdoor in plain sight with an uncommon protocol is still viable, though local firewalls will mitigate. ss(8) still doesn't give you all the info it ideally should, probably because of some missing plumbing. lsof(8) is still a useful swiss army knife slowly getting more tools.

Monday, 13 January 2014

a bit of selinux for noobs

So, once again, you've added an initscript that works fine in test to a prod server. It fails. And you get permission denied to write to a directory - but waitaminute, the process starts as root?

The obvious suspect: selinux. Turning it off is the stupid way out and not an option.

[root@gnuff ~]# grep denied /var/log/audit/audit.log
type=AVC msg=audit(1389617233.067:1073936): avc:  denied  { write } for  pid=34988 comm="tcpdump" name="ts" dev=dm-2 ino=1572884 scontext=unconfined_u:system_r:netutils_t:s0 tcontext=system_u:object_r:var_t:s0 tclass=dir

So tcpdump isn't allowed to write to a var_t directory. Fair enough, really. What is it allowed to write to, from a confined user?

sesearch to the rescue! (yum install setools-console)

[root@gnuff ~]# sesearch -T -s netutils_t
Found 3 semantic te rules:
   type_transition netutils_t tmp_t : file netutils_tmp_t;
   type_transition netutils_t tmp_t : dir netutils_tmp_t;
   type_transition netutils_t abrt_helper_exec_t : process abrt_helper_t;

This searches for allowed type transitions from the netutils_t context. Aha!

[root@gnuff ~]# chcon -t netutils_tmp_t /var/cache/ts

And restart ... and voila! No more permission denied.

[root@gnuff ~]# semanage fcontext -a -t netutils_tmp_t /var/cache/ts

makes it permanent. (yum install policycoreutils-python if you have no semanage)

Better do it via puppet, of course. (selinux_fcontext)

PS. The strictly correct option is rather:
 [root@gnuff ~]# sesearch -A -s netutils_t | grep dir | grep write
   allow netutils_t netutils_tmp_t : dir { ioctl read write create getattr setattr lock unlink link rename add_name remove_name reparent search rmdir open } ;
   allow netutils_t dirsrv_var_run_t : sock_file { write getattr append open } ;
   allow netutils_t tmp_t : dir { ioctl read write getattr lock add_name remove_name search open } ;

which searches for allow rules. But the type transition rule search gets far fewer hits and is worth a try as a first approximation when doing a sysadmin fix-it-fast search. Few apps transition to a type they can't read/write.

([root@gnuff ~]# sesearch -A -s netutils_t | wc -l
365
)