My Ultimate Network Monitor/Enumeration Tool – Putting It All Together

Finally, all the parts come together. Look at my previous posts for all the pieces to building the LilDevil network monitor and enumeration tool.

The LilDevil

So this tool I created sits on a Raspberry Pi. Its purpose is to monitor and enumerate all devices currently connected to a network. In this case, it sits on my Guest network. Tomato Shibby is running on my router and I used its web interface to setup the network, along with limiting access. For all guests jointing this network, they are warned by the router’s splash page that tools such as this will be running. Its a free network and they really can’t expect anything different going on. In this case, its not malicious, but it is good practice to be wary of guest networks.

To be less suspicious, the hostname of the Raspberry Pi is RainbowDash šŸ˜‰ This amuses me so much, the perfect disguise! If I saw a device named LilDevil running on a guest network I would be totally alarmed. I also themed the Pi accordingly, see the below screenshot. The coloring isn’t perfect, I blame VNC.

RainbowDash

The Pi runs a Django Restful server that stores mmap scan information about detected machines on the network. The Python 2.7 scripts for this are here. I had to make a few versions in order for things to work on Django 1.6.

In views.py, change

encoded = json.loads(request.raw_post_data)

to

encoded = json.loads(request.body)

Also, I had to make some changes in dirtBag.py, in order to get the ping sweep to work appropriate.

Change MIN and MAX to an integer instead of a string.

MIN="0"
MAX="12"

to

MIN=0
MAX=12

Here is a copy of the new main function.

def main():
    global results
    while 1:
        new = ""
        for x in range(MIN,MAX):
            new = new + commands.getoutput("ping -c 1 -t 1 "+PREFIX+"."+str(x) + " | grep 'from'") #Ping sweep the network to find connected devices
        tmp = re.findall(PREFIX+".(d+)", str(new)) #Pull out IP addresses from the ping results
        if tmp != results:
            for ip in tmp:
                if ip not in results:
                    gotcha = commands.getoutput('nmap -v -A -Pn '+PREFIX+'.'+ip)
                    sendDevice(gotcha)
            for r in results:
                if r not in tmp:
                    removeDevice(PREFIX+'.'+r)
            results = tmp

The information is up to date on all devices currently connected. It may be nice in the future to include a log of all scans but for now, I’m really only interested in connected machines.

Data is then displayed in a visible GUI. The below screenshot shows the tool windows along with the GUI. Currently, no devices were connected to the network.

Screen Shot 2014-01-17 at 9.27.49 PM

 

Ahhh it detected a device… in this case, itself.

Screen Shot 2014-01-19 at 7.58.55 PM

There you have it! A portable network enumeration tool. There are so many versions of this everywhere, but this is just something I coded up for fun. I plan to add to the Pi later for kicks.

IMPROVEMENTS: Detecting New Network Devices with Python and Tkinter

So I wasn’t too happy with theĀ kludginess of the network monitoring tool that I posted about earlier this week. It lagged and really wasn’t an ideal tool. I decided to redesign the entire model.

New Model

The new tool still utilizes Python 2.7 and consists of three parts:

  • Ping/Enumeration Script
  • RESTful Django Script
  • Tkinter Reporting GUI Script

Here is how they connect. The Ping/Enumeration Script, pings all devices given within a network range. Whenever it finds a new device, it runs a NMAP scan on the device then formulates a request to the server to notify it of the device scan results. The script will also notify the server when a device disconnects from the network (this was an issue with the old version).

The Django server manages a sqlite database containing scan results on all devices currently connected to the network. It will remove or add a device record based on the ping script’s RESTful HTTP request. The server can also return a list of all devices detected. This list is used by the GUI script.

The GUI script maintains a Tkinter dialog window that will circulate through all network connected device scan results. It first sends a GET request to the Django server asking for a JSON list of all connected devices. The script will then display each record found in the JSON. Each device record will appear in the GUI window for 20 seconds. After it has made the rounds through each item, it will make another call to the server for a fresh JSON to iterate through.

The Ping/Enumeration Script is basically the same as what I discussed earlier. The difference is, after data is collected, it is sent to the Django server in a POST request.


import commands, re, json, urllib2, binascii
PREFIX = "192.168.1" #Network prefix
MIN = "0" #Starting network address, eg 192.168.1.0
MAX = "12" #Closing network address, e.g. 192.168.1.55
results = []

def escapeMe(message): #Escape characters (using ASCII value) not allowed in JSON
    new = ""
    for num in range(len(message)):
        char_code = ord(message[num])
        if char_code < 32 or char_code == 39 or             char_code == 34 or char_code == 92:
            new = new + "%" + binascii.hexlify(message[num])
        else:
            new = new + message[num]
    return new

def sendDevice(gotcha): #Send the device report to the server as a POST
    try:
        url = "http://127.0.0.1:3707/new/" #Server address
        gotcha = escapeMe(gotcha)
        values = json.dumps({'device' : str(gotcha)})
        req = urllib2.Request(url)
        req.add_header('Content-Type', 'application/json')
        rsp = urllib2.urlopen(req, values)
        code = rsp.getcode()
    except Exception, e:
        print e

def removeDevice(ip): #Send request to remove device
    try:
        ip = ip.replace('.','-')
        url = "http://127.0.0.1:3707/remove/"+ip+"/"
        rsp = urllib2.urlopen(url)
        code = rsp.getcode()
    except Exception, e:
        print e

def main():
    global results
    while 1:
        new = commands.getoutput('for i in {'+MIN+'..'+MAX+'}; do ping -c 1 -t 1 '+PREFIX+'.$i | grep "from"; done') #Ping sweep the network to find connected devices
        tmp = re.findall(PREFIX+"\.(\d+)", str(new)) #Pull out IP addresses from the ping results
        if tmp != results:
            for ip in tmp:
                if ip not in results:
                    gotcha = commands.getoutput('nmap -v -A -Pn '+PREFIX+'.'+ip) #nmap new devices found on the network
                    sendDevice(gotcha) #send device record to server
            for r in results:
                if r not in tmp:
                    removeDevice(PREFIX+'.'+r) #remove device if it wasn't found in the latest ping
            results = tmp

if __name__ == "__main__":
    main()

Django is an awesome Python Web Application Framework that I absolutely adore (not the movie šŸ™‚ ). It is known as the web framework for perfectionists with deadlines. Most of my web projects utilize Django.

Django

It comes with its own lightweight server to host its applications, so its perfect for any development environment. For the sake of this project, I’m using its server, all script/server functionality is limited to the host machine running the tool. Everything is internal. Django also handles the RESTful routing and database modeling. It uses the model view controller (MVC) structure. Here is a great tutorial on how to create your own Django app, definitely worth looking into!

The following is the break down of code I wrote for the Django server (running version 1.3).


####################models.py####################
from django.db import models

class Devices(models.Model):
    device = models.TextField()

####################ADD to urls.py####################
url(r'^new/$', 'lilDevil.views.new', name='new'),
url(r'^listDevices/$', 'lilDevil.views.listDevices', name='listDevices'),
url(r'^remove/(?P*ip*.+)/$', 'lilDevil.views.remove', name='remove'), #REPLACE * with greater/less sign containing brackets

####################views.py####################
from django.http import HttpResponse
from lilDevil.models import Devices
import json

def remove(request, ip):
    try:
        ip = ip.replace('-','.')
        devicelist = Devices.objects.all()
        for d in devicelist:
            if ip in d.device:
                d.delete()
        return HttpResponse(status = 200)
    except Exception, e:
        return HttpResponse(e)

def new(request):
    try:
        encoded = json.loads(request.raw_post_data)
        new = Devices(device=encoded["device"])
        new.save()
        return HttpResponse(status = 200)
    except Exception, e:
        return HttpResponse(e)

def listDevices(request):
    try:
        json_string = '{"devices": ['
        devicelist = Devices.objects.all()
        first = True
        for d in devicelist:
            if first:
                first = False
            else:
                json_string = json_string + ', '
            json_string = json_string + '{"device": "'+str(d.device)+'"}'

        json_string = json_string + ']}'
        return HttpResponse(json_string)
    except Exception, e:
        print HttpResponse(e)
        return

Finally, the GUI script. Very similar to the one in the old post. Again, I just added the ability to request device data from the server.


from Tkinter import *
import time, urllib2, urllib, json
class flipGUI(Tk):
    def __init__(self,*args, **kwargs): #Setup the GUI and make it pretty
        Tk.__init__(self, *args, **kwargs)
        self.label1 = Label(self, width= 65, justify=CENTER, padx=5, pady=5, text="Guests") #Text label
        self.label2 = Label(self, text="") #Photo label
        self.label2.grid(row=0, column=1, sticky=W+E+N+S, padx=5, pady=5)
        self.label1.grid(row=0, column=0)
        self.flipping()

    def flipping(self): #Flip through NMAP scans of detected devices
        t = self.label1.cget("text")
        t = self.label2.cget("image")
        data = getData()
        found = json.loads(data)
        photo = PhotoImage(file="picture.gif")
        if found['devices']:
            for f in found['devices']: #Loop through all but the last item
                fixed = f['device'].replace('%0a', '\n') #return to ASCII value from earlier escaped hex
                self.label1.config(text=fixed)
                self.label1.update()
                self.label2.config(image=photo)
                self.label2.update()
                time.sleep(20)
        else:
            self.label1.config(text="No connected devices")
            self.label1.update()
            time.sleep(20)
        self.after(1, self.flipping())

def getData(): #Get a list of devices from server
    url = "http://127.0.0.1:3707/listDevices/" #server address
    response = urllib2.urlopen(url)
    code = response.getcode()
    if int(code) == 200:
        return response.read()
    else:
        return

if __name__ == "__main__":
    try:
        while 1:
            app = flipGUI()
            app.mainloop()
    except Exception, e:
        print e

Final Note: Make sure to delete/clear out database or old results will carry over! I did this in an init.d script that calls the service.

Put it all together and you have a much more stable tool. I renamed it from the Hindenburg to the Lil Devil.

The Lil Devil
The Lil Devil

Detecting New Network Devices with Python and Tkinter

UPDATE: I made a better version of this tool with server implementation here.

Today I felt like building a python 2.7 script that would enumerate a network along with alert me to the presence of a new device.

I limited my project to functions in the standard library.

So something lightweight and okay fast is a ping sweep. From an early post I included the Linux command for a sweep. I used this command along with the python commands to execute the ping sweep along with storing the results in a variable.

new = commands.getoutput('for i in {'+MIN+'..'+MAX+'}; do ping -c 1 -t 1 '+PREFIX+'.$i | grep "from"; done')

Following, I used some regular expressions to pull out the IP addresses detected in a given prefix range.

tmp = re.findall(PREFIX+"\.(\d+)", str(new)) #Pull out IP addresses from the ping results

Put that in a loop with some comparison data and you have a script that prints an alert whenever a new device is detected.

import commands, re
PREFIX = "192.168.1" #Network prefix
MIN = "0" #Starting network address, eg 192.168.1.0
MAX = "12" #Closing network address, e.g. 192.168.1.55
results = []
while 1:
new = commands.getoutput('for i in {'+MIN+'..'+MAX+'}; do ping -c 1 -t 1 '+PREFIX+'.$i | grep "from"; done') #Ping sweep the network to find connected devices
tmp = re.findall(PREFIX+"\.(\d+)", str(new)) #Pull out IP addresses from the ping results
if tmp != results:
for t in tmp:
if t not in results:
print "New device at" + PREFIX + "." + str(t)
results = tmp

There are a few short comings in the code but that’s the basic idea.

Now take this further, I hooked it up to a GUI with enumeration information! The new beastly application constantly flips through NMAP scan results of devices found connected to the network and displays the results in a GUI.Ā I even placed a picture in the GUI. I call this app, the Hindenburg, its kind of hacked together.

The Hindenburg!
The Hindenburg!
from Tkinter import *
import time, commands, re
PREFIX = "192.168.1" #Network prefix
MIN = "0" #Starting network address, eg 192.168.1.0
MAX = "12" #Closing network address, eg 192.168.1.12
class flipGUI(Tk):
def __init__(self,*args, **kwargs): #Setup the GUI and make it pretty
Tk.__init__(self, *args, **kwargs)
self.label1 = Label(self, width= 65, justify=CENTER, padx=5, pady=5, text="Guests") #Text label
self.label2 = Label(self, text="Guests") #Photo label
self.label2.grid(row=0, column=1, sticky=W+E+N+S, padx=5, pady=5)
self.label1.grid(row=0, column=0)
self.flipping()
Ā Ā Ā Ā def flipping(self): #Flip through NMAP scans of detected devices
t = self.label1.cget(“text”)
t = self.label2.cget(“image”)
found = scanNetwork()
photo = PhotoImage(file=”picture.gif”)
for f in found[:-1]: #Loop through all but the last item
self.label1.config(text=f)
self.label1.update()
self.label2.config(image=photo)
self.label2.update()
time.sleep(15)
self.label1.config(text=found[-1]) #the last item doesn’t require the sleep, it takes enough time to run the scans
self.label1.update()
self.label2.config(image=photo)
self.label2.update()
self.after(1, flipping())

def scanNetwork():
found = []
new = commands.getoutput(‘for i in {‘+MIN+’..’+MAX+’}; do ping -c 1 -t 1 ‘+PREFIX+’.$i | grep “from”; done’) #Ping sweep the network to find connected devices
tmp = re.findall(PREFIX+”\.(\d+)”, str(new)) #Pull out IP addresses from the ping results
for ip in tmp: #Loop through each found IP
found.append(commands.getoutput(‘nmap -v -A -Pn ‘+PREFIX+’.’+ip))
return found

app = flipGUI()
app.mainloop()

It’s ideal for an environment where it can just sit on the screen without much of any type of activity going on. If you are enumerating the entire network, there will be a lag… it happens.

Autorun Bypass

ā€œCash machines raided with infected USB sticksā€ (BBC News).

I guess Iā€™ve never focused long enough on an ATM machine to even consider USB ports. Just seems like a silly thing to put on one. They are hidden but we see how well that prevented hackers from cutting holes in the machine coverings. It took some time to finally catch these thieves despite them targeting the same machine several timesā€¦ why? There are surveillance cameras. I guess itā€™s not suspicious to have a person attend to an ATM machine over the course of time it takes to cut a hole in the machine, upload malware from a USB and then patch the hole up again. Oh and in addition, the intruder needed to phone the head honcho in order to validate varying sequence controls. The gang had their own system of checks and balances. Back to the point, to me, anything longer than 2-3 minutes at an ATM is suspicious but I’m really not that patient.

I wonder how did the thieves test the malware they used to infect the ATM? Their software brought up a secret interface on the machine listing all forms of stored currency. The mastermind must have had quite the knowledge on ATMs. When I code up something, I have to test it like crazy in the environment. I guess if he discovered USB access, he could easily use an I/O device to enumerate the environment.

Disclaimer: Just because I discuss such matters does not mean I endorse or participate in such activity. It is important to understand weaknesses in order to know how to secure a device.

This got me thinking… what options are there to enumerate a system through I/O… There’s a lot of options. I guess it would be easy to get a USB and set a malicious script to automatically run on startup. To do this, create an autorun.inf script:

[AutoRun]
SHELLEXECUTE=<EXE TO RUN>

Problems with this, since Windows 7, Microsoft has automatically disabled autorun for USB devices… dang it.

No worries, introducing the Teensy!

Teensy, $20 on Adafruit

This fun deviceĀ emulatesĀ a keyboard or mouse I/O device and bypasses normal USB restrictions and isĀ compatible with most platforms including Windows, OS X and Linux. Metasploit even includes payload creation for the device. A good tutorial on how to accomplish this can be found here.

Metasploit

The tutorial shows how to open a line of communication or meterpreter session between a listening device and the teensy victim. Ownage! With this available, someone could pull down environmental variables such as:

  • OS version –Ā sysinfo
  • User accounts – getuid
  • Hashes – hashdump
  • Network info – ipconfig
  • Running processes – ps
  • For extra fun, you can access and take a picture from the webcam with webcam_list and webcam_snap
  • Cover your tracks by clearing out the logs –Ā clearev

With this information, one couldĀ enumerate the environment enough to understand its weaknesses and what further scripts/tools/steps can be used to hack the device.

End lessen, be aware of USB devices and easy port access. Have some legal fun!

Hard Drive Encryption

On a totally different encryption tangent, I need to encrypt my hard drives. Kind of ashamed that they arenā€™t encrypted already… I studied the field of cyber-security. However, for a basic home server it didnā€™t seem as pertinent to encrypt my drives.

Iā€™m not going crazy or anything with confidential data. However, something really cool with hard drive encryption is that in most cases (strong password utilized, best practices, etc.), if the user is not logged into the computer at the time of seizure, it can be close to impossible (at the moment of writing this) for forensics to decrypt the data. True, there are tools that are part of the FTK toolkitĀ like PRTK that can be used to attempt to decrypt your hard drive. Now correct me if Iā€™m wrong, but if your password is over 12 characters long and includes different characters, numbers, symbols and all that jazz, the decryption attempt will take forever! The investigators are likely to be long gone before anything is returned (the cracking system would also have to be amazing and last just as long).

There are primarily two types of encryption, hardware and software encryption. I prefer the idea of hardware encryption, it encrypts data at the lowest level and tends to be more secure. If someone has access to your environment with a software encryption scheme there is a greater likelihood they will be able to obtain the key through brute force. A simple reference site for an explanation of encryption and the differences can be found here.Ā One uses the computers resources to encrypt while the other relies on the hardware to encrypt data on its own dedicated processor. There really isnā€™t much difference between performance, problem is not all hard drives come with a dedicated processor for encryption.

My environment consists of three 4 TB hard drives in a RAID5 array that are currently partitioned into two drives. One drive contains Windows 8 and the other is for storage.

The hard drives I'm currently using.
The hard drives I’m currently using.

So my options, hardware or software encrypt. Iā€™ve already been using the drives for quite some time, I donā€™t really want to lose the data already stored on the devices. There are some issues I foresee with hardware encryption and a RAID system. Is it even possible with RAID? I have to concern myself with how encryption will affect the stripping and mirroring of data. It all depends on the drive and in my case, its easy, my hard drives don’t even include the capability to hardware encrypt so on to software encryption.

For software encryption, BitLockerĀ and TrueCryptĀ are two free solutions that I am familiar with and could consider using. I could also look at converting my entire system into a NAS (FreeBSD and FreeNAS can setup a software based RAID and they include encryption capabilities) butā€¦ Iā€™ll save that for another day.

BitLocker is already made available on Windows 8 Enterprise and Ultimate, but is it better than TrueCrypt? According to Tomshardware.com, both encryption tools are almost identical in performance. Bottom line,Ā Microsoftā€™s BitLocker apparently has a few advantages via Intelā€™s new AES extensions. Despite this, TrueCrypt gives is compatible with non-Windows environments and it allows users to create “secret” partitions. These partitions are totally hidden and are only accessible from the TrueCrypt passphrase screen.

Mmm I think I’ll explore both options. BitLocker is quite easy to setup. From the start screen, type in BitLocker and there it is!

Finding BitLocker

Select to turn on BitLocker and follow the wizard instructions. It’ll take a couple restarts to get things going followed by a long, long wait.

BitLocker

Easy Sauce!

TrueCrypt is slightly different. The install demonstrated was performed on a MacBook Pro with Mavericks installed.

I couldn’t encrypt the working hard drive because it was in use, kind of defeats the purpose of what I was attempting however, I was able to create a hidden/secret partition. So I’m just going with that.

After starting up TrueCrypt, select to “Create Volume.”

TrueCrypt Main Menu

Follow the wizard directions to “Create an encrypted file container.”

Encrypted File Container

Following, select “Hidden TrueCrypt volume.”

Hidden Drive

Select a file location for the TrueCrypt volume. This volume will appear as a file which can then be mounted by the TrueCrypt software. Once mounted, it can be accessed just like another filesystem with directory trees, files, etc.

Choose whatever encryption algorithm works for your environment, testing is always a good idea.

Outer Volume Encryption Options

The Outer Volume Format window is slightly peculiar, you just mouse around the window a lot to create a random key sequence.

Outer Volume Format

After selecting, “Format,” the outer volume for the hidden/secret partition will be created. This volume contains the hidden and can act as a decoy.Ā The wizard continues with the hidden volume creation.

Screen Shot 2014-01-02 at 6.57.22 PM

It’s basically identical to the earlier, outer volume process.

Now to access the two volumes, open TrueCrypt and mount the file you created. You can either enter in the password for the hidden or decoy volume depending on which on you want to access.

TrueCrypt Password Prompt

So why this outer volume/hidden volume setup?Ā Say, somehow, someone knew you had the TrueCrypt volume and they were forcing you to provide the password. Well, thank goodness you have a decoy! They’ll think they’re getting the goods when really you are only supplying them with decoy files, while the hidden ones lay secretly nestled inside the decoy undetected.

Wow, what a long post but there you have it, the joys of encryption!

Decrypting Files by Sound? Part 1

I found this paper recently that discuss how an RSA encryption key can be enumerated by sound. It was written by Adi Shamir, the co-inventor of the RSA algorithm (the ā€˜Sā€™ in RSA), so the paper seems to be a little more legit than just someoneā€™s paranoia. Basically, the idea is based off of the noises a computer makes when utilizing different levels of power. These noises consist of high-pitched tones that can be detected by the right equipment. Each task performed by a computer requires varying amounts of resources and power therefore a new unique set of tones for a process. So it seems possible that the noises resulting from a machine decrypting a key could be picked up and used to for enumeration.

This is definitely something I would love to test out! However, as of now I donā€™t have the right equipment but I donā€™t want to give up on the project yet. Instead, Iā€™ll make baby steps. Encrypt something with RSA.

To be continuedā€¦

Backtrack Metagoofil

This tool will use google to search a domain for given file types and extract the metadata to a viewable HTML file. It is part of the footprinting stages of penetration testing.

Command Use:

  1. cd /pentest/enumeration/google/metagoofil
  2. ./metagoofil.py ā€“d <domain to search> -f <file type or all> -o <output html file name> -t <location to download files>

Backtrack theHarvester

This tool is used to gather e-mail accounts, usernames, hostnames, subdomains from public sources such as google, bing and Linkedin. In penetration testing, this is part of performing enumeration or footprinting a network

Supported sources are:

  • Google ā€“ emails, subdomain and hostnames
  • Google profiles ā€“ locate employee names connected with the domain
  • Bing search ā€“ emails, subdomain, hostnames and virtual hosts
  • Linkedin ā€“ locate employee names connected with the domain
  • Exalead – emails, subdomain and hostnames

Ā Command Use:

  1. cd /pentest/enumeration/theharvestor
  2. ./theHarvester.py ā€“d <target site> -l <max number ofĀ  returned results> ā€“b <source of gathering, ex: google>