Saturday, March 31, 2012

launch control to monitor my server

This post integrates the previous post with the series that came just before it on a Ubuntu server running on OS X Lion under VirtualBox. I'm a complete amateur at this (really just using blogger as a scientific notebook), so if you have suggestions I'd be very happy to hear from you.

The idea is that the first thing a black hat will likely do is wipe (or sanitize) the logs, so we should move the data off the server periodically. To do this I take advantage of the ability to ssh into the server from OS X, and do a scp to Lion. After doing this, the script compares the current logfile with previous versions, and only logs the changes. The listing for the script is at the end of the post.

I changed the plist as shown by the diff. The change runs the script every 60 seconds rather than watching a path on OS X.

> diff com.TE.script.plist com.TE.script.old.plist 
14,15d13
<         <key>StartInterval</key>
<         <integer>60</integer>
19a18,21
>         <key>WatchPaths</key>
>         <array>
>         <string>/Volumes/HD/Users/telliott_admin/Desktop/y.txt</string>
>         </array>

To make things easier, I worked on the script from the Desktop until I thought things were OK, then ran this shell script retry.sh (using ./retry.sh):

sudo cp ~/Desktop/watch.py ~/Library/Scripts/watch.py
launchctl unload com.TE.script.plist
launchctl load com.TE.script.plist


The plist contains the key RunAtLoad with a value of true, so reloading the job runs the script.

To test, I just do:

> date
Sat Mar 31 16:10:25 EDT 2012
> curl http://10.0.1.2:8082
^Z
[21]+  Stopped                 curl http://10.0.1.2:8082

Unfortunately, marking the time doesn't help because the server and OS X are out of synch. :)

And then I watch the tmp directory for the appearance of 201126.31.log (that's hour minute second.day), which contains the forensic evidence, 7 repeats of the following entry with intervals of a second or two (reformatted):

Mar 31 16:18:06 U32 kernel: [12503.991135] [UFW BLOCK] IN=eth1 
OUT= MAC=08:00:27:d7:ba:0e:00:26:b0:fa:75:7f:08:00 
SRC=10.0.1.3 DST=10.0.1.2 LEN=48 TOS=0x00 PREC=0x00 TTL=64 ID=50692 DF 
PROTO=TCP SPT=49982 DPT=8082 WINDOW=65535 RES=0x00 SYN URGP=0

I would be very interested to know of other solutions. For example, it might be cleaner to watch the log files on Ubuntu, then email them or something when things change. But I would not want to have Ubuntu able to ssh to OS X. That wouldn't be a good design for a "honeypot."

watch.py

#! /usr/bin/python
import sys, os, subprocess
from time import gmtime, strftime

# you'd want year first to sort properly for real
tm = strftime("%H%M%S.%d", gmtime())
tmpdir = '/Users/telliott_admin/Desktop/tmp/'

# scp the log over to OS X in tmp/uwf.log
scp = 'scp'
src = 'telliott@10.0.1.2:/var/log/ufw.log'
dst = tmpdir + 'uwf.log'
cmd = ' '.join((scp, src, dst))
obj = subprocess.call(cmd,shell=True)
# perhaps this fails (e.g. server is down)
if not obj == 0:
    sys.exit()

# check for no previous entry
src = dst
prev = tmpdir + 'prev.log'
try:
    os.stat(prev) 
except:
    dst = prev
    cmd = ' '.join(('cp', src, dst))
    obj = subprocess.call(cmd,shell=True)
    
    # write to a time-stamped file
    dst = tmpdir + tm + '.log'
    cmd = ' '.join(('cp', src, dst))
    obj = subprocess.call(cmd,shell=True)
    sys.exit()

# load data:  current logfile
FH = open(tmpdir + 'uwf.log','r')
current = FH.read().strip().split('\n')
FH.close()

# load data:  previous logfile
FH = open(tmpdir + 'prev.log','r')
previous = FH.read().strip().split('\n')
FH.close()

# only keep data that is new
t = previous[-1].split()[2]

tL = [e.split()[2] for e in current]
if t in tL:
    i = tL.index(t)
    current = current[i+1:]
    
if not current:
    sys.exit()

print 'logging', len(current), 'items'

# write to a time-stamped file
s = '\n'.join(current)
dst = tmpdir + tm + '.log'
FH = open(dst,'w')
FH.write(s)
FH.close()

cmd = ' '.join(('cp', dst, prev))
obj = subprocess.call(cmd,shell=True)
,