The World Smallest Honeypot

I think honeypots are a very elegant way of detecting attackers by either offering them a fake vulnerable service, or by triggering the attackers interest.

After looking at Kippo logs and doing my OSCP I learned that in almost every attack the attacker will at least read a file. An attacker will always look around for files they can either use for further network exploitation or files that are useful in other ways. That’s why I thought it would be fun to see if there is a quick way to figure out if a file has been access within a certain time frame. Some of you might have already seen the solution I came up with earlier today on Twitter – I thought I do a quite writeup on what this one-liner actually does, and how you could use it.

A simple honeypot

As far as I know, the world smallest honeypot:

while sleep .5;do if [[ `echo \`date +%s\`-\`stat -c %X secretFile\`|bc` -le 5 ]];then echo 'Alert';fi;done;

Lets format that a bit shall we? (I added comments next/above every line explaining what is happening)

# Infinite loop. The result of the command 'sleep .5' is used. 
# This will alway's be true, unless sleep is broken...
while sleep .5;
  # Get 'now' in Epoch, subtract last 'access time' (Epoch) of our honeyfile
  # Continue into IF if the difference is less or equal to 5 
  if [[ `echo \`date +%s\` - \`stat -c %X secretFile\` | bc` -le 5 ]]; 
    # What to do if our honeyfile has been touched in the last 5 seconds?
    echo 'Alert';

Before I continue I think it’s important that you are aware of a small detail on how this script works.

Please don’t change the ‘access time’….

On a Linux file system (unless the noatime mount flag is specified) for every file the ‘access time’ is stored. This value indicates when the file was last ‘accessed’ (doh). But for (I think) mainly performance reasons this value is not updated all the time. The best piece of documentation I could find on how the ‘access time’ is processed was here:

On this page the ‘MS_RELATIME’ argument is the most relevant: When a file on this filesystem is accessed, update the file's last access time (atime) only if the current value of atime is less than or equal to the file's last modification time (mtime) or last status change time (ctime). This option is useful for programs, such as mutt(1), that need to know when a file has been read since it was last modified. Since Linux 2.6.30, the kernel defaults to the behavior provided by this flag (unless MS_NOATIME was specified), and the MS_STRICTATIME flag is required to obtain traditional semantics. In addition, since Linux 2.6.30, the file's last access time is always updated if it is more than 1 day old.

It might look like this value ‘access time’ is updated at quite “unpredictable” moments but I still believe you should be able to rely on it.

The reason I’m pointing this out is that I think it is important to know that the ‘access time’ value will not always be updated. You won’t be able to use the ‘access time’ data to maintain a log on when a file was read. You are able to monitor if the file was access by anyone on the condition that the file wasn’t accessed in the 24 hours before. This should be quite reliable since this file shouldn’t be touched by anyone anyway.

Additions and Adjustments

If you don’t feel comfortable using ‘atime’ you can still use the same command but with a different and more reliable timestamp value. For example, you can monitor mtime (modification time) of the files /etc/passwd or /etc/shadow. If one of these files changes you know user(s) have been added, deleted or modified. You can do the same with other system critical files.

  • Comparing an MD5 hash of these files to a known value taken before is in this case probably recommended since atime and mtime are values that can be controlled by the owner of the file and ‘root’.

To improve the quality of the script you should add your own “alarm bells” in the ‘IF’ statement. You can add ‘mail’ commands or other actions you want to take when the file was read/modified.

  • Do remember that it is all bash, figuring out what is happening is quite easy for an attacker. An easy way to prevent this is to move these commands into a binary. I think it is less likely an attacker will figure out what a binary is doing before looking at “juicy” files.

This is a very simple detection technique and a decent attacker will figure this out quite quickly. None the less, defenders need to be able to catch the kiddies every once in a while to right? Anyway, thats is for today. Sorry for the sort and messy post today. I’m working on a few other posts but they are all a bit more work than this one. Also, brother needs to work ;)

Cheers, Ruben (@rubenthijssen).