Julia Evans

Spying on ssh with strace

In the shower this morning I was thinking about strace and ltrace and how they let you inspect the system calls a running process is making. I’ve played a bit with strace on this blog before (see Understanding how killall works using strace), but it’s clear to me that there are tons of uses for it I haven’t explored yet.

Then I thought “Hey! If you can look at the system calls with strace and the library calls with ltrace, can you spy on people’s ssh passwords?!”

It turns out that you can! I was going to do original research, but as with most things one thinks up in the shower, it turns out someone’s already done this before. So I googled it and I found this blog post explaining how to spy on ssh. The instructions here are just taken from there :)

The reason this is possible is that strace doesn’t just tell you which system calls a given program is running. It also tells you what the arguments are! So if a program ever calls a function with a password the odds are pretty good that you can find out the password this way.

To do this you need to already be root, so it’s not a vulnerability or anything. This just means that if your machine is already compromised, it’s really, really, compromised. Here’s how it works:

I have a running ssh server on my machine, so I sshd to my laptop:

$ ssh [email protected]

sshd forks and creates a couple of new processes to handle the incoming ssh connection. I can find them using ps:

[email protected] /tmp> ps aux | grep sshd
root      1242  0.0  0.0  50036   908 ?        Ss   Jan21   0:00 /usr/sbin/sshd -D
root      9412  0.0  0.0 101536  4104 ?        Ss   11:29   0:00 sshd: unknown [priv]
sshd      9413  0.0  0.0  51468  1356 ?        S    11:29   0:00 sshd: unknown [net] 

Then I can use strace to spy on what the child process is doing. It passes the password to the main sshd process, and that’s where we win!

I attach strace to the child process like this:

$ sudo strace -p 9412 2> strace_out

and then go back to my ssh login and type in my password (‘magicpassword’).

When I look in the strace_out that gets created, I can see the password!

read(6, "\v\0\0\0\rmagicpassword", 18)  = 18
socket(PF_FILE, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 4
connect(4, {sa_family=AF_FILE, path="/dev/log"}, 110) = 0
sendto(4, "<38>Feb 17 11:32:35 pam_fingerpr"..., 68, MSG_NOSIGNAL, NULL, 0) = 68
sendto(4, "<38>Feb 17 11:32:35 pam_fingerpr"..., 121, MSG_NOSIGNAL, NULL, 0) = 121

This is pretty nuts! When I think of the damage you can do as root, I usually think of things like reading sensitive files. And when I wrote a rootkit, I learned that you can do all kinds of crazy things by inserting a malicious module into the kernel. (like hiding files and processes and making every song on your computer be by Rick Astley)

But you can also spy on running processes and learn basically anything you want around them! So if the NSA has root on your server, it can easily find out everyone’s password who logs in via SSH. Whoa.