Honeypot / honeyd tutorial part 5, email alerts

So this is the final article in this series of honeypots and honeyd and before I wrap it up I’ve gotta give big shout outs to Neils Provos the creator of honeyd. Neils has done an excellent job with the honeyd program and his book Virtual Honeypots is hands down the best book about honeypots and I highly recommend picking up a copy. While writing some of these tutorials Neils was even kind enough to answer some of my emails.

Up to this point you hopefully have an understanding on how to get honeyd up and running on your preferred hardware while having the ability to run multiple honeypots in either a static or dhcp environment. Now that everything is running smoothly and you’ve successfully tested all connectivity you’ll probably want to start getting alerts from some of the honeypots you’ve setup and deployed. I’ve written a small python script that accomplishes this for me so hopefully my explanation of the setup will get you receiving email alerts as well.

So out of the box honeyd doesn’t natively support getting emails sent to you when your device is port scanned. I really wanted this feature but had to figure out the best way of determining when my honeypot was being scanned. Honeyd has the option of creating a log file so my first idea was to parse this file for items of interest. Below is the command I would use to launch honeyd with the logging option.

honeyd -d -f honeyd.conf -l /tmp/logfile

You should see similar output as below after running the above command.

Honeyd V1.5c Copyright (c) 2002-2007 Niels Provos
honeyd[12073]: started with -d -f honeyd.conf -l /tmp/logfile
Warning: Impossible SI range in Class fingerprint "IBM OS/400 V4R2M0"
Warning: Impossible SI range in Class fingerprint "Microsoft Windows NT 4.0 SP3"
honeyd[12073]: listening promiscuously on eth1: (arp or ip proto 47 or (udp and src port 67 and dst port 68) or (ip )) and not ether src 00:0c:29:11:1e:53
honeyd[12073]: [eth1] trying DHCP
honeyd[12073]: Demoting process privileges to uid 65534, gid 65534
honeyd[12073]: [eth1] got DHCP offer: 192.168.134.147
honeyd[12073]: Updating ARP binding: 00:00:24:54:9e:06 -> 192.168.134.147
honeyd[12073]: arp reply 192.168.134.147 is-at 00:00:24:54:9e:06
honeyd[12073]: Sending ICMP Echo Reply: 192.168.134.147 -> 192.168.134.254
honeyd[12073]: arp_send: who-has 192.168.134.254 tell 192.168.134.147
honeyd[12073]: arp_recv_cb: 192.168.134.254 at 00:50:56:e8:c9:74

So this just created a honeypot with the IP address of 192.168.134.147. From another machine let’s port scan our honeypot, to keep the output simple I’m only going to scan one port.

root@tht:~# nmap -p 135 192.168.134.147

Starting Nmap 5.21 ( http://nmap.org ) at 2012-02-10 19:37 PST
Nmap scan report for 192.168.134.147
Host is up (0.0013s latency).
PORT STATE SERVICE
135/tcp open msrpc
MAC Address: 00:00:24:54:9E:06 (Connect AS)

Nmap done: 1 IP address (1 host up) scanned in 0.14 seconds

So port 135 is open so we know our configuration is working properly. Also honeyd will output information to the terminal letting you know that connections are being made to your honeypot. The information below was appended to the output from when we started honeyd.

1
2
3
4
5
6
7
8
honeyd[12073]: arp reply 192.168.134.147 is-at 00:00:24:54:9e:06
honeyd[12073]: arp reply 192.168.134.147 is-at 00:00:24:54:9e:06
honeyd[12073]: Connection request: tcp (192.168.134.143:49677 - 192.168.134.147:135)
honeyd[12073]: arp_send: who-has 192.168.134.143 tell 192.168.134.147
honeyd[12073]: arp_recv_cb: 192.168.134.143 at 00:0c:29:e3:2a:39
honeyd[12073]: Connection dropped by reset: tcp (192.168.134.143:49677 - 192.168.134.147:135)
honeyd[12073]: arp_recv_cb: 192.168.134.254 at 00:50:56:e8:c9:74
honeyd[12073]: arp_recv_cb: 192.168.134.254 at 00:50:56:e8:c9:74

On line three we see a connection request from 192.168.134.143 to our honeypot at 192.168.134.147 and the “:135” after the IP address is the destination port so from this output we can verify everything is working and we’re getting the correct response from our port scan. You also see on line six that the connection from 192.168.134.143 to 192.168.134.147 was dropped. Now let’s take a look at our log file to see what kind of information about our port scan shows up. We’ll use the tail command in Linux, by default the tail command only shows the last 10 lines of a file although this can be adjusted.

1
2
3
4
5
6
7
8
9
10
11
root@bt:~# tail /tmp/logfile
2012-02-10-22:37:42.9749 udp(17) - 192.168.134.1 61712 224.0.0.252 5355: 60
2012-02-10-22:37:48.0504 udp(17) - 192.168.134.143 44907 192.168.134.2 53: 74
2012-02-10-22:37:48.0751 udp(17) - 192.168.134.2 53 192.168.134.143 44907: 74
2012-02-10-22:37:48.0799 tcp(6) S 192.168.134.143 49677 192.168.134.147 135
2012-02-10-22:37:48.0814 tcp(6) E 192.168.134.143 49677 192.168.134.147 135: 0 0
2012-02-10-22:38:00.0874 udp(17) - 192.168.134.1 57479 224.0.0.252 5355: 55
2012-02-10-22:38:02.9374 udp(17) - 192.168.134.1 64855 224.0.0.252 5355: 55
2012-02-10-22:38:09.9825 udp(17) - 192.168.134.1 57141 224.0.0.252 5355: 57
2012-02-10-22:38:13.2114 udp(17) - 192.168.134.1 60692 224.0.0.252 5355: 56
2012-02-10-22:38:16.0751 udp(17) - 192.168.134.1 57282 224.0.0.252 5355: 56

In the log file we see very similar information on lines 5 and 6 as we did in the standard output of the terminal. Turns out there’s a third location of output that we could tap into. All processes in Linux will probably display some kind of information into one of two system log files. Either the /var/log/messages or the /var/log/syslog file. Different distros of Linux will put this information into different locations but for the backtrack distro I know it goes into /var/log/syslog. Let’s tail this file to see what kind of information it holds.

1
2
3
4
5
6
7
8
9
10
Feb 10 22:36:53 bt honeyd[12073]: arp reply 192.168.134.147 is-at 00:00:24:54:9e:06
Feb 10 22:36:53 bt honeyd[12073]: Sending ICMP Echo Reply: 192.168.134.147 -> 192.168.134.254
Feb 10 22:36:53 bt honeyd[12073]: arp_send: who-has 192.168.134.254 tell 192.168.134.147
Feb 10 22:36:53 bt honeyd[12073]: arp_recv_cb: 192.168.134.254 at 00:50:56:e8:c9:74
Feb 10 22:37:48 bt honeyd[12073]: arp reply 192.168.134.147 is-at 00:00:24:54:9e:06
Feb 10 22:37:48 bt honeyd[12073]: arp reply 192.168.134.147 is-at 00:00:24:54:9e:06
Feb 10 22:37:48 bt honeyd[12073]: Connection request: tcp (192.168.134.143:49677 - 192.168.134.147:135)
Feb 10 22:37:48 bt honeyd[12073]: arp_send: who-has 192.168.134.143 tell 192.168.134.147
Feb 10 22:37:48 bt honeyd[12073]: arp_recv_cb: 192.168.134.143 at 00:0c:29:e3:2a:39
Feb 10 22:37:48 bt honeyd[12073]: Connection dropped by reset: tcp (192.168.134.143:49677 - 192.168.134.147:135)

On lines 7 and 10 we see similar information as we’ve seen in other areas. So when I decided to build an email alert script I had three sources of information I could pull from. I eventually went with combing through /var/log/syslog but I could have easily went a different route. For me /var/log/syslog seem to have more verbosity and better keywords but then again that’s just my opinion. My next step was to write a script that would parse /var/log/syslog then generate an email alert when it saw connections to my honeypot. I wrote my script in Python because I’m most familiar with that language and Python comes installed by default on most Linux distributions so whatever distro you decide to run honeyd on it’s more than likely Python will already be installed on that same operating system.

Before you implement any scripted email solution it’s a good idea to test email functionality with a small email script just to ensure you can properly communicate and receive email alerts. To do this you’ll need to know the name (FQDN) of your SMTP email server. You can usually find them in your email client. For Outlook you can go to File > Account Settings > Account Settings > Email tab > click on Change, there you’ll see the name of your organizations smtp server. Typically it’ll be something simple, if the email of your organization ends in example.com then your smtp server will likely be smtp.example.com. SMTP servers are usually configured to send emails in one of two ways, authenticated or unauthenticated. We’ll look at examples for both. The first example below is a python script of sending authentication credentials along with the request, in this particular I’m sending the alert to my gmail account.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import smtplib
import time

From = 'someuser@gmail.com'
To = 'travisaltman@gmail.com'
Date = time.ctime()
Subject = 'test'
Text = 'test'

Message = ('From: %s\nTo: %s\nDate: %s\nSubject: %s\n%s\n' % (From, To, Date, Subject, Text))
username = 'someuser'
password = 'somepassword'

print ('Connecting to server')
s = smtplib.SMTP ('smtp.gmail.com')
s.starttls()
s.login(username,password)
sendMail = s.sendmail(From, To, Message)
s.quit

if sendMail:
  print ('error')
else:
  print ('great success')

Hopefully some of this script is easy to figure out, the main thing you need to be concerned with is lines 11,12, and 15. Lines 11 and 12 hold the username and password you’ll need to authenticate to your smtp server and line 15 is the name of your smtp server. More than likely your internal smtp server will not require authentication if that’s the case simply remove lines 11,12,16, and 17 from the script above. If you’re not sure first send the test email without authentication and if you get the error message “smtplib.SMTPSenderRefused” then more than likely you’ll need to provide credentials. If everything goes smooth running your test email script then you should see the output below, here I’ve named my script test.py.

root@tht:~# python test.py
Connecting to server
great success

Next you can implement the full email alerting script. Simply copy and paste the script below into your text editor of choice and name the script, I’ve named my alert.py.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import re
import time
import smtplib
import os

try:
  os.remove('/root/outputHoney')
except:
  pass

log = "/var/log/syslog"
output = 'outputHoney'

systemTime = time.ctime()
loggedDate = systemTime[4:10]
loggedYear = systemTime[20:24]
hostFile = '/etc/hostname'
readHostFile = open(hostFile, 'rU').readline();
extractHostName1 = readHostFile.split('"')
hostname = extractHostName1[0].rstrip()

file = open(log, 'rU').readlines();
for line in file:
if re.search(loggedDate, line):
  if re.search("192.168.1.55", line): #This if for any IP(s) you want to exclude
    ignore = ''
  elif re.search("Connection request", line):
    loggedTime = line[7:15]
    timeString = loggedDate + ' ' + loggedYear + ' ' + loggedTime
    timeTuple = time.strptime(timeString, '%b %d %Y %H:%M:%S')
    epochLogTime = int(time.mktime(timeTuple))
    epochSystemTime = int(time.time())
    if epochSystemTime <= epochLogTime+300:
      lineSplit1 = line.split('(')
      lineSplit2 = lineSplit1[1]
      lineSplit3 = lineSplit2.split(':')
      lineSplit4 = lineSplit2.split('-')
      lineSplit5 = lineSplit4[1]
      lineSplit6 = lineSplit5.split(':')
      destinationIP = lineSplit6[0]
      sourceIP = lineSplit3[0]
      srcAndDest = sourceIP + ' connected to ' + destinationIP
      file = open(output, 'w')
      file.writelines(srcAndDest)
      file.close
if os.path.exists('/root/outputHoney'):
  From = hostname+'@example.xxx'
  # To = ['user1@example.xxx','user2@example.xxx']
  To = 'travisaltman@gmail.com'
  Date = time.ctime()
  Subject = 'honeypot alert'
  username = 'someusername'
  password = 'somepassword'
  # IPSconnecting = open(output, 'r').read()
  Text = "A device at " + sourceIP + " is port scanning our honeypot at " \
  + destinationIP + ". This honeypot is being emulated on device " \
  + hostname + "."
  Message = ('From: %s\nTo: %s\nDate: %s\nSubject: %s\n%s\n' % (From, To, Date, Subject, Text))
  s = smtplib.SMTP ('smtp.gmail.com')
  s.starttls()
  s.login(username,password)
  sendMail = s.sendmail(From, To, Message)
  s.quit

I’m not a developer and I always mangle my scripts together so this isn’t the prettiest code. I’ll give you a run down of what this script does, if you have any specific questions please feel free to leave a comment I generally respond to comments fairly quickly. Basically the script combs through /var/log/syslog looking for the string “Connection request”. I’ve also confirmed that this script works just as well combing through /var/log/messages, you’ll have to verify which log your Linux distro is dumping this information. To test the script to make sure it works I would first port scan your honeypot from another device then simply run the python script to see if you get no errors and hopefully you get an email in your inbox, just run the following command after you’ve port scanned your honeypot.

python alert.py

This command should only run for maybe 10 seconds then return you to the command line. If you get any errors then you’ll have to trouble shoot the script, contact me if you need help with that. Just to give you an idea of what the email alert would look like I’ve got a screen shot of an alert I got sent to my gmail address below.

Currently the script only looks for “Connection request” in the last five minutes of log files so you’ll need to combo that up with running the script every five minutes, this can be done with Linux’s crontab. Cron can schedule programs to be run at certain frequencies. To set up alert.py to run every five minutes use the crontab command.

crontab -e

This opens up a text file in the terminal where you enter a specific syntax to tell cron which program you want to run and how often. Enter the text below to tell cron to run alert.py every five minutes.

*/5 * * * * /root/alert.py

Then use control+w to save your work and control+x to quit the text editor. So in the alert.py script the every five minutes comes from line 33 where 300 is seconds which equals five minutes so if you wanted to modify the time you could do it on that line. Another line in the script you may want to change is line 25, here you can add any IP’s that you want to ignore for whatever reason. You’ll definitely want to change line 55 that has the text of the email you’ll be receiving and customize that to your hearts content. Don’t forget to modify smtp server information and also remove or change the authentication piece as needed. Also in the screenshot you’ll notice that the device is “bt” which is short for backtrack. I implemented this feature because you may want to run honeyd on multiple devices throughout your network and you’ll want to know what device is sending you the email. The name of the device is determined in lines 17-20. You may have to modify that code because not all distros of Linux keep their hostname in that location and you may have to parse the text file that holds that hostname in a different manner. There’s more information that I could go into about the script but hopefully I’ve hit the major points if there’s something I missed or if you have any questions or feedback please leave comments.

22 Responses to “Honeypot / honeyd tutorial part 5, email alerts”

  1. Sarah Says:

    Thank you Travis. You tutorials are really helping me with my project. I am still running the email alert script on debian, if something comes up I’ll ask you.

    once again thank you for your help.

  2. travis Says:

    Sarah,

    Glad it helps, I try to be responsive so let me know if I can help.

  3. Sarah Says:

    Hey Travis,

    I understood most of the code you wrote. I am just wondering though why do you use a lot of timeSplits (timeSplit 1 to 6)? I can’t understand that about. If you could be so kind as to explain that part?

    Thank you.

  4. travis Says:

    Sarah,

    I don’t write the best code, I’m sure there’s better ways of accomplishing this task. Basically the main purpose of all those lineSplits is to get the proper word in a sentence. I’m parsing the log files trying to get the source and destination IP address, at the time I wrote the script the lineSplits seemed like a decent way of parsing out the source and destination. Probably not the best way to solve that problem. Hopefully that made sense, if not let me know.

  5. Ethan Says:

    Hey Travis,
    I was wondering if you have done anything with malware analysis on the honeypots?

    I am currently setting up my own system but looking for a good way to analyze and capture malware signatures, but so far nothing good yet.

  6. travis Says:

    Ethan,

    I would not recommend using honeyd for full blown malware analysis. Where honeyd shines is when malware is looking or an IP address, you can then point the malware to the IP address of your honeyd box or if the malware or if your malware reaches out to “random” IP addresses you could tell honeyd to listen for any IP address that the malware connected to. Honeyd is a great tool if you want to redirect traffic from an infected host to your honeyd installation. Now if you want to understand how the malware makes changes to the underlying OS of the infected host then I suggest you the VMWare route and basically let your guest OS become infected with malware and monitor from there. Where honeyd can shine is if you let your windows guest VM become infected and it tries to reach out to an external IP address you can then modify the windows hosts file and point the malware to your honeyd IP address. I never really covered that but that’s just one of the many uses of honeyd. Hopefully I’ve answered your question if not let me know.

  7. Bert Says:

    Travis

    Outstanding job on your Honeyd Tutorial

    I would like to know if Honeyd can be used to do the following.

    Download a Black List of Malicious IP Addresses and Domains.
    Reroute DNS Traffic to the Honeypot
    When a user on our network click on a http link that has Malware, The Honeypot stops the outbound traffic.

    If yes, How would you do this with Honeyd software.

    Thanks

  8. travis Says:

    Bert,

    I don’t think honeyd would be the best solution for what you’re trying to accomplish, an intrusion detection / prevention solution such as snort would probably be a better fit. With a properly placed sensor snort is already going to be seeing the traffic you could configure rules within snort that would stop the traffic. If that doesn’t answer your question let me know.

  9. comfreak Says:

    There is an error in your E-Mailscript:

    Line 24 must have an space at the first place.

  10. Seanny Says:

    Bert,

    I think what you’re looking for is pfSense with the add-on pfBlocker.

  11. Murgan Says:

    Hey Travis,
    Your tutorials for honeyd is so helpful for beginners as me and others.Keep on this great job man.

  12. Jack Says:

    Travis i followed the alert.py script but it showing the following error.Sorry im totally a newbie in python so need some guide

    File “alert.py”, line 24
    if search(loggedDate, line):
    ^
    IndentationError: expected an indented block

  13. travis Says:

    Jack,

    I’ve been terrible about responding. The copy paste from my code should have worked but sometimes the text editor you paste into may not keep the indentations. Python syntax demands that you have proper indentation so please check all your tabs for things like if statements if that doesn’t work let me know and mabye I’ll respond in a decent amount of time.

  14. Neha Says:

    I want to work on honeypots.. basically on decresing the size of honeyd logs. In tutorial 1.. u hav used Backtrack 5.. so is backtrack an OS based on Linux?

  15. travis Says:

    @Neha, yes backtrack is based on Linux so you can use a feature such as logrotate to reduce the size of your logs

  16. Neha Says:

    ok..how does logrotate work.. can u summarise me its functiontiong..
    ur tutorials have been of great help.. well done..
    I wanted to ask that does allocationg static ip’s to different personalities doesn’t work? (I tried to do this.. but it failed.. it is showing only one personality that can be pinged )
    In tut.2 , u hav given MAC addresses to each personality.. please let me know.. Is that the only way?

  17. travis Says:

    @Neha,

    Logrotate simply ensures that your hard drive doesn’t fill up with logs by automatically deleting logs over a certain age. Could be a number of reasons why the static IP’s aren’t working I’d probably have to have access to the system to troubleshoot. I do assign MAC’s to each device I want to emulate so that it is properly segregated. I would always recommend assigning MACs to each device you want to emulate. Hope that helps.

  18. Montaser Says:

    Thank you Travis. You tutorials are really helping me with my project. my project about how to help Security Administrator to generate presice signature by using the information in the log files of honeyed. and I am looking for a good matirials like this to explain the honeyd log files and how to parse it to be saved in dtatabase to display it in web-based manner. please Travis if you have any idea about how to implement that, help me please.
    my email is mnskori@gmail.com
    Thank you

  19. travis Says:

    Montaser,

    Your solution is more involved from what I implemented, I dont have a good recommendation on how to put that info into a database.

  20. Jack Says:

    Hii travis…..
    Your tutorial is great and it is helpful, im facing a problem on the email alert script. there is no response from the script after i run alert.py. its not responding
    i just changed line 49,52,53 to my email. is there any other changes should i do. Thank you 🙂

  21. Faizan Rasool Says:

    Thank you brother

    Your tutorials are just owsome. These tutorials realy helped me .
    I have performed all the steps that you have metioned in your tutorials and my honeypot is running properly…..

  22. OY Says:

    Log Issue …

    Dear All ,
    I have a question and is that i dont understand where my logs are stored… or may be I am using the -l flag in a wrong way .. Can some one help me out .. It will be really appreciated .
    I am using a Raspberry PI , wheezy Raspbian .

    Thanks in advance

Leave a Reply