| || |
As a security researcher, penetration tester, and all around network security guy, Kismet has always had a special place in my heart when it comes to network security testing tools. When I'm on-site, doing an internal penetration test or network security audit, it is not uncommon to see Kismet running on my laptop. Sometimes it is simply out of general curiosity to see "what's out there", it might also be to determine if a "rogue access point" is operating, or I might be looking for a way to build a "covert channel" (ie - back door) out of the network. It's also possible that I'm just bored, and want to see what is flowing through the air.
I've been a Kismet user for a long time, and it is one of the many "tools" in my "tool box". If you're not familiar with Kismet, check out http://www.kismetwireless.net.
Kismet is basically a passive wireless network/device discovery tool. When Kismet is properly configured, you simply fire it up and it will tell you what wireless devices are in your area (802.11b/a/g/n/DECT).
You might recall that back in August 2010, Google got into a little bit of trouble using this utility. Basically, those goofy looking Google "streetview" cars that take pictures of streets were doing a little more than that. Using Kismet and GPS data, they were collecting information about wireless networks, along with packet payload data, which led them into trouble.
As a "security" guy, I tend to 'ride the fence' of exploitation versus protection. As much fun as it is to discover exploitable services on a network (legally!), it is also important to understand and realize how to "protect" the network.
Recently, while playing with Kismet, I began to ponder "Wireless Intrusion Detection Systems". I recalled that the Kismet web site said the following:
Note the bold on "intrusion detection system". This led me to my latest exercise. That is, building a "Wireless IDS" (Intrusion Detection System) using "off the shelf" supplies. There's already a commercial market for wireless IDS systems. I'm not terribly interested in those, and I decided to explore the "Do It Yourself" avenue, so the software needed to be open source. Kismet was my first natural choice for this project.
All roads led back to Kismet
I did, however, decide to research other possible projects that might be more focused on wireless IDS. My criterium, of course, was that the project be "open source". To my surprise, there's really not much being done in the open source world that deals with wireless IDS. For example, I found the project widz.
"widz" looked interesting, but the problem is that this project hasn't been updated in quite some time (Feb. 2003). I also ran into "Snort Wireless" project references. This project appeared to be defunct. After some thought, I decided to stick with the well known, good old, Kismet. My thoughts where that I'd want something that has a code base that is actively being developed. Dragorn, the author of Kismet, has been doing this for quite some time and is still actively developing Kismet.
GoalsThe primary idea for this "Proof of Concept" (PoC) system is that it has the potential of being used "out in the field". That is, in real world senarios.
I had several ideas about how I wanted to do this. The first involved using something like a WRT54G Linux based wireless access point. There were a couple of problems with this solution. First, I would need the system to act like a wireless "Access Point" (AP) and monitor wireless frequencies for layer 2 attacks. That means that the system would need a minimum of two internal radios. Second, I would also need enough horse power to do packet inspection among other things. My thoughts were that a small Linux based router would probably be under-powered for the task. I had also thought about a stand-alone machine that would "join" a network and passively monitor for layer 2 attacks. A little bit of research showed that this probably wouldn't work terribly well.
What I finally decided on doing was to take a PC, load Linux on it and turn it into a wireless AP. This way, I have the CPU power for packet analysis, with plenty of storage and RAM to load the software I might need. This offered a lot of flexibility, and it was ultimately the way I decided to go.
Another design concept which was critically important was for all data (alerts) to be dumped in a unified, single console for viewing. A system that uses several pieces of software that dumps data to various places wasn't an option. My PoC design had to have a single place where I could view all security related events. These events could be from Kismet, packet inspection software (Snort), or syslog (Sagan).
(Figure 1. Still in the box Atheros "long range" wireless cards")
Loading the Atheros 5xxx drivers
The first, most logical step, was to make the Linux based PC into an AP. Keep in mind, I actually have two EnGenuis PCI wireless cards in the system. One will be used to build our AP, and the other for detection of layer 2 attacks (rogue access points, spoofed AP's, etc). Before we can get to that point, we need to load the appropriate drivers for these cards. On my soon-to-be wireless IDS system, a 'lspci' showed:
The kernel I'll be using on my Linux based IDS/IPS system is the Gentoo 2.6.35-r2 hardened ebuild. We typically build our field IDS/IPS systems with harden kernels, so I decided it would be best to do the same with my PoC system. This means that pax/grsec is enabled and working. The idea is that this is a 'security' device, so any assistance in thwarting attacks can help.
The 2.6.35-r2 kernel has "Atheros 5xxx wireless card support", and this is what we'll be using. Below are the device/wireless kernel configurations I used.
You'll probably want to install the wireless tools. This will give you commands like 'iwconfig', which may be needed for debugging. On my Gentoo based system, I simply typed:
Check your distribution for the wireless tools. They'll likely be avaliable. Once your kernel has been compiled, you can load the Atheros 5k drivers by typing:
Check 'dmesg' for any errors. Make sure the module sees both wireless cards. Your 'dmesg' should look something like this, if completed successfully:
Buiding the AP
For the AP, we'll be using 'hostap'. The idea is to use one of our two wireless cards and switch it from a 'client' [Managed] mode, to 'AP' [Master] mode. This turns the computer into a wireless router. The card I'll be using is the first card (device: wlan0). Remember, we'll be using the second Atheros card for other purposes. I'm using hostapd version 6.9 for stability reasons. In the Gentoo world, to install hostapd, we would type:
Check your distribution for information about possible hostapd packages.
Many people who use hostapd build a network 'bridge' between the wireless card and their internal network card. I will not be running hostapd in 'bridge' mode, but rather in NAT mode. This means I'll be assigning my AP card (wlan0) an IP address.
I'll be using this AP just as I would any other one. This means that WPA2 encryption is a must. In this case, I'll be using a pre-shared key. Your configuration may differ, so alter as you see fit. This is simply a 'base' configuration for you to start off with. In my case, the hostapd.conf file is stored in the /etc/hostapd/hostapd.conf.
To start up hostapd.conf in 'debug' mode, simply type:
This will cause hostapd to run in the foreground, which can be useful for debugging. Without the '-dd' options, hostapd will become a system daemon (background). Since we're trying to build this system as a 'real access' point, you'll probably want to run DHCP services on the AP/wireless card (wlan0). If you're using the ISC (Internet Systems Consortium) DHCP server, you would configure the DHCP server just as you would any other. Here's a short example configuration:
Start your DHCP server and test. From another machine equipped with wirelss networking, you should see the SSID 'secure'. You should also be able to get a DHCP lease from your new DHCP server. Once the AP is deemed "operational", tweak your firewall settings and NAT to how you like them. That's outside of the scope of this document, so lets continue forward.
Back hall communications
Since we're attempting to build a Wireless IDS system we'll need to build a secure means to communicate with our back end server(s). This is ultimately where all our IDS/IPS alert information will end up and where we'll have a unified console to tie everything together. We could just send the data across the Internet to our back end unencrypted, but that would be a bad thing. Even though this is a PoC idea, we might as well do it right.
For the back end communications, at Softwink, Inc. we utilize OpenVPN quite a bit. It's pretty simple to setup, and will give us an encrypted layer to transport our IDS events.
To build from source, simply go to http://openvpn.net and follow the instructions. If you're doing this on a Linux platform, odds are your distribution has a repository/build for OpenVPN. On a Gentoo system, you would simply type:
For Ubuntu, you'd type:
Configuration of OpenVPN is pretty straightforward, but I'll go over the basics of my PoC install. OpenVPN will be operating in a client/server model. That is, the clients will be our remote wireless IDS systems and they'll connect to our server, which is our event data storage/correlation back end. We'll basically be building a "point-to-point" VPN (encrypted) tunnel for our IDS data to flow to.
To start off, I'm going to create an OpenVPN configuration file on the "server" side.
The client side is somewhat similar, with a few things switched around and added.
Once the configuration files are in place, you'll need to generate a pre-shared key for OpenVPN to use. This key will go on both the client and the server. Keep in mind, it is a "secret" pre-shared key, so you'll want to transport the key over some sort of "secure" medium (For example, OpenSSH). To generate the key, type:
Verify that both sides have a copy of the key, and test the connection. To test on both sides, type:
With any luck, you'll see something like the below:
To further verify, "ping" across the OpenVPN tunnel. The "server" side will be assigned the TCP/IP address 184.108.40.206. The client side will be assigned 220.127.116.11. If you can successfully "ping" across the OpenVPN connection, we have a secure means to transport our wireless IDS data. Also, after testing the link, you'll probably want to run OpenVPN in a "daemon" mode (background). To do this, simply append the "--daemon" flag. You might want to consider adding this to your startup in case either side gets rebooted. This way, the OpenVPN tunnel will automatically be established.
You might be curious about the IP structure we're using in the PoC wireless IDS system. Why didn't we use RFC1918 style addresses? We actually avoid RFC1918 addresses (for example, 192.168.0.0/24) because we don't know what type of networks these sensors might be installed in. It's likely that the remote wireless IDS system might be installed in a network already using RFC1918 addressing. This could potentially interfere with our wireless IDS system routing. With this in mind, we create a "point-to-point" tunnel using non-RFC1918 addresses to avoid any future conflicts. Remember, this is a point-to-point tunnel, so only two IP addresses are being used. Odds are in our favor that we won't be taking any "important" addresses.
Snort'ing the interface(s)
One part of our wireless IDS system will be used to monitor for attacks from within our network at the packet level. To do this, we'll be using a software from Sourcefire known as Snort. The very basic idea behind Snort is that it monitors traffic on a network interface for security related events. For example, Snort might monitor the network for possible exploit attempts or people probing the network (nmap, etc) for information. Snort accomplishes this by using rule sets. When the rule sets match a 'bad' thing, Snort is able to send an 'alert' letting the administrators know that a possible attack is under way. At Softiwnk, Inc. we've used Snort for quite a while and have become fans of it. In many cases, we use Snort as our IDS/IPS engine. If you don't have experience with Snort and you're in the security field, I highly recommend checking it out.
For the purpose of this article, I'll be giving the basic overview of how we'll be using Snort for our wireless IDS system. Actually, I'm going to be configuring Snort to operate on more than just the wireless interface. My PoC wireless IDS system has the wireless network cards but is also connected to the Internet on a wired interface know as "eth1". So, for better protection of the network and the machines it controls, I'll be running Snort on the Internet facing network device (eth1) and on the wireless AP device (wlan0). On the Internet-facing side, we'll monitor for external attacks to our wireless IDS sensor. On the wireless LAN/AP side, we'll monitor for internally based attacks. The Internet facing "sensor" (Snort) will be known as "wireless-internet" (sensor id [sid]: # 1 on device eth1). The internal wireless LAN's "sensor" (Snort) will be known as "wireless-internal" (sensor id: # 2 on device wlan0).
While Snort will alert us when suspicious activity or attacks happen from within or externally from our wireless IDS system, we'll be running a firewall on both interfaces to hopefully slow or prevent the attack from being successful. The firewall configuration will largely depend on the type of installation you want to do. For example, it may be desired to egress firewall on the wireless/AP (wlan0) devices. Configuring firewalls with Linux has been a topic that's largely documented and outside of the scope of this document. I'll let you determine how you want to handle traffic on you wireless IDS system.
I typically build Snort directly from source. I find that many distributions typically ship older version of Snort, or distribute it with options I don't like. If you're not comfortable building Snort from source, check your distribution's repository. You might have better luck than me and be able to use a pre-built package of Snort. The Sourcefire team, the makers of Snort, also release pre-built packages of Snort that might be useful to you. To get the latest version of Snort, point your browser to:
As of this writing, Snort version 18.104.22.168 is the 'latest'. I'll be using this version as the base of my wireless IDS system. By the time you read this, this may be considered an older version of Snort. While that may be the case, the premise of the article should stand. Simply use the latest version of Snort.
Below is my "./configure" flags I use to build Snort.
You might notice that I've disabled all SQL database support. This might seem incorrect, but it's actually just what I want. We'll get to that a bit later in the 'Barnyard' configuration section of this paper. I also enabled options like 'inline' with Snort, in the event I wish to turn our IDS system into an IPS (Intrusion Prevention System). For the time being, we're only concentrating on IDS, but having the ability to go full IPS in the future is a nice option to have.
You'll also want to create the user 'snort' on your system. While we will start Snort as the user 'root', when Snort finishes initializing, we'll want it to drop its privileges and 'become' the user name 'snort'. We do this for security reasons (ie - privilege separation). On most modern systems, when you add the 'snort' user, the account is 'disabled'. That is, it hasn't been assigned a password and thus can't be logged into. I typically like to keep it that way.
For Snort rule sets, I'll be using the Sourcefire Snort rules and Emerging threats rules. You'll need to download those and put them in the /etc/snort directory. If you wish to put your rules in another directory, don't forget to change the "RULE_PATH" in the configuration files.
The first interface we'll tackle is the Internet facing one (eth1). This is the Interface that connects our wireless AP/IDS system to the Internet. Here's my base configuration file used for that externally facing, Internet connected interface.
For the external interface, I'm not going to load very many rules. We have some general rules loaded to detect certain things, but the fact is, my wireless IDS system is not going to be running many services that will be connectable from the outside. Let me rephrase that. My wireless IDS system will not be running any publicly connectable services on the Internet facing interface. Period. With proper firewalling in place and not running un-needed services, this dramatically reduces our threat level and hence reduces the number of rules I'll be using on this interface.
Think of it this way. I'm not, and will never be running a service on the wireless IDS system that requires "Coldfusion" support. It will never be protecting anything that requires Coldfusion support. Therefore, there's not much of a reason to load the "web-coldfusion.rules" rule set!
The 'wireless' interface (wlan0) is a bit different. I will be monitoring that interface for everything from attacks to malware. Anything in our wireless network, I'm going to consider potentially hostile. The interface configuration is pretty similar, but with different network definitions and more rules loaded.
As you can see, many more rules have been loaded. In reality, you could probably trim down the rule sets loaded a good bit. However, this is a PoC model, so I'm pretty much "throwing the book" at it.
To start and test your Snort configuration, simply run Snort with the appropriate flags:
Substitute the interface (-i wlan0) and configuration file (snort.wlan0.conf) with the appropriate settings for your setup. For this article, I'm simply giving a brief run down of my configurations. Your configuration may vary. If you have problems with Snort, Google around. There are many "HOWTO" documents related to Snort and this article isn't really geared toward a person who is completely new to Snort. Once you verified the Snort setup, you can run Snort with the same configuration options, but add a '-D' (daemonize). This will make Snort run in the background. You might want to consider adding Snort to your system's startup routine. Make sure you put it in after your wireless and hostapd are set up!
It's probably not apparent yet, but we have one more interface we'll be running Snort on. This interface will be a TAP/TUN device supplied to us by Kismet.
Kismet monitoring with Snort in the mix
Remember, we have two Atheros based cards. We're using one card (wlan0) to create our "Access Point" for internal users to connect to the network.
We're already monitoring that network interface with Snort, as well as our network interface connecting our Wireless IDS system to the Internet.
The second wireless interface (wlan1) will be our "Kismet" interface. Kismet will actually supply us with two sets of data. The first set of data supplied by Kismet is layer 2 data. That data will be Kismet scanning wireless frequencies looking for new clients, potentially hostile/rogue AP, and miscellaneous other layer 2 types of attacks.
Basically, we'll be operating Kismet in a "traditional" sense. Think of "war driving", but of course our sensor won't be moving.
Kismet also has a mechanism to supply data collected (packets), as it is channel 'hopping' to a TAP/TUN interface. Think of it this way, as Kismet hops from channel to channel, it will sometimes intercept data (TCP/IP packets). Those data packets can be read by programs like tcpdump or wireshark from the Kismet supplied TAP/TUN interface.
This TAP/TUN interface will be "monitored" by our third Snort sensor.
As of this writing, the 'latest' version of Kismet is "Kismet-2010-07-R1" and can be found at http://www.kismetwireless.net. However, we'll be using Kismet with a bit of a twist to it. In our case, we want the information that Kismet "finds" via "channel hopping" to be fed to syslog for later examination. The reason for this will become more clear later in the article, but we'll go ahead and "patch" Kismet now.
You can download the Kismet "syslog" patch from:
This will only patch the "kismet_server.cc" file. Once you've downloaded Kismet-2010-07-R1 and the kismet-2010-07-R1-syslog-patch-r4.diff patch, application and configuration is pretty simple. For example:
Configuration is pretty simple for Kismet. It should be noted that we will not be using the Kismet console! We'll be using the Kismet server, and passing that information to our back end MySQL/Console system. That's not to say you can't use the Kismet console. Since the 'kismet_server' will be running on remote wireless IDS sensors, you can fire up the Kismet client/console on the sensors. What we are going for is having the 'kismet_server' report information to our back end. This means the console isn't as important to us. I'll go into my reasoning for this later in the document.
Below is my Kismet configuration (/usr/local/etc/kismet.conf).
After reviewing and adjusting your configurations, you can test by firing up /usr/local/bin/kismet_server. With any luck, you'll see something like this:
(Figure 3. The 'kismet_server' running in interactive mode. MAC addresses have been obfuscated)
While the Kismet server is up and running, it might be a good time to check your syslog information. On my PoC system, you'd type, 'tail -f /var/log/messages'.
(Figure 4. Example of syslog output supplied by the 'kismet_server'. MAC addresses have been obfuscated)
You might need to check your system/distribution setup for where the syslog information gets stored.
Once you're satisfied with the Kismet server and syslog results, we can go ahead and start up the Kismet server in the background. This can be done by running the /usr/local/bin/kismet_server with the --daemonize flag. To see other kismet_server flags, pass the --help option.
With the 'kismet_server' operational, we should have a new pseudo interface named "kistap1". This interface is being supplied by Kismet, and this is the data (packet level) that's being gathered while it does its 'channel hopping'.
We'll be running Snort on this interface. Since it's the "channel hopping" interface, things get a little more strange. For example, we have clear needs and solutions for all of our Snort interfaces. For example, Snort is monitoring our externally facing interface for external attacks (eth1). We also monitor our internal interface with Snort for attacks and malicious traffic from within our network at the AP level (wlan0). This interface doesn't really "fit" into those categories.
So basically, this interface is going to be monitoring 'data' outside of our network. This is essentially what Google got in trouble for! If a nearby network isn't encrypted and Kismet "picks up" some of that packet data, we'll see it on our kistap1 interface. So, essentially, we're running Snort on "outside of our network" traffic. We're grabbing packets out of the air an analyzing them.
Do we need to? Probably not. Since this is a PoC design, I'm interested in seeing the data that's supplied. Some might even consider this a slippery legal issue.
In a real world design, this might be over the limit. I'll leave that to the reader. However, the beer is telling me this is a "research project", so let's continue forward.
Considering we don't really have a clear idea what type of traffic we'll be seeing on this interface, we'll use a similar Snort configuration that we used on our AP (wlan0). That is, we'll enable lots of rules and see what it picks up. Unlike previous configurations, where we had a clear definition of TCP/IP address ranges that would be in use, on this interface we do not.
The packets received by our Kismet supplied interface could be within any possible range. Some might be RFC1918, while others might not be. To get around this, we want to run Snort in an "any/any" configuration. That is, any traffic coming from/to any place needs to be examined. However, when we tell Snort to run in a "HOME_NET any" and "EXTERNAL_NET any" configuration, certain rules will complain (mostly emerging threat rules). To get around this issue, I'm creating a 'mirror' of our rules in the "/etc/snort/any" directory. Rules that complain about our 'any/any' configuration will be disabled. It's typically only a handful of rules that cause this problem. By doing it this way, we can keep our kistap1 rules separate from our "real rules".
This is basically the run-down of my Snort configuration file that we're going to be using for our kistap1 interface. Mine is stored in the /etc/snort/snort.kistap1.conf.
We can now "test" Snort by running it like our previous interfaces. Simply type:
If it runs successfully, consider re-running the command with the -D (daemonize) option. You'll probably want to add this to your system rc/startup routines. Remember, Kismet supplies this interface so you'll need to start Kismet first before running this instance of Snort!.
You might have noticed in our Snort configurations the lack of sending data to the MySQL (in our case) back end. There's a good reason for this. We'll be using Barnyard2 to collect data from Snort and send it to our back end data collection point. In each of our Snort configuration files, we're using the "output unified2:" option. As Snort detects potentially hostile traffic, it'll log it to a file using unitied2 format. This means, Snort will record the alert and rule that was triggered, as well as the packet information (packet dump). Barnyard2's job is to "read" this file, in real time, and relay that information to our SQL back end servers. The basic idea is to separate Snort from having to deal with the logging process.
Think of it this way. Snort is monitoring a network interface in real time. If a 'bad event' happens, Snort would have to temporarily 'stop processing' network traffic to log information to the SQL database. This is not good, as we might potentially miss other hostile traffic while Snort is dealing with logging to the SQL server. To avoid this, a separate process is started (Barnyard2) that'll take information from Snort, via the unified2 output format, and INSERT it into the SQL database for Snort; thus off loading that process from Snort to Barnyard2. Since Snort doesn't need to 'concentrate' efforts on SQL logging, it can continue monitoring the network interface.
In each Snort configuration, we've told each instance of Snort to log to its own individual "unified2" file. For example:
Since we have a total of three instances of Snort running, we'll be running three instances of Barnyard2. Each one will read a unique Snort unifed2 formated file. Each Barnyard2 instance will log to our SQL back end as a separate "sensor id". In the Snort SQL database in the 'sensor' table, the 'sensor id' is known as the 'sid'.
Data from each specific instance of Barnyard2 will be loaded to a unique sid. In the end, this allows you to specify traffic by interface from the database. For example, in the end, you'll be able to 'view' data from the sid # 1 (Internet connection) while ignoring sid's #2 (AP) and #3 (Kismet TAP/TUN). Or you can combined all that information together, to get a complete view of all data.
Let's first do a quick overview of creating the database and tables that'll be needed on our MySQL back end server. Keep in mind, I'm using OpenVPN to create a tunnel between our satellite wireless IDS systems and the back end server. The idea is that we'll be collecting information from Snort via Barnyard2 and sending that over the OpenVPN to our MySQL server.
In our case, our satellite (wireless IDS) system has an OpenVPN tunnel address of 22.214.171.124. The peer TCP/IP address on our back end data collection point it to 126.96.36.199. Lets first do a brief overview of setting up the SQL back end server. These instructions are for MySQL, however, PostgreSQL works very well with Barynard2 too.
First, on the server back end, lets create our database and build our tables. Database schemas ship with the tarballs of Snort within the 'schemas' directory. There you'll find MySQL, MS-SQL, DB2 and MySQL schemes. In our example, we'll be using the MySQL schema.
Once the database is created, we need to assign the appropriate grants/ rights to the database for the remote satellite wireless IDS systems to be able to store information.
With the grants/rights in place, we can now move on to configuring Barnyard2 to read our unifed2 output from Snort and inserting data into our MySQL database. Just like Snort, where we separated configuration files via interface (ie - snort.eth1.conf, snort.wlan0.conf, snort.kistap1.conf), we'll be doing the same with Barnyard2 (barnyard.eth1.conf, barnyard.wlan0.conf, barnyard.kistap1.conf).
I'll be putting all my Barnyard2 configuration files in the /etc/barnyard2 directory. So the first interface we'll tackle is eth1, our Internet facing interface. So, our configuration file will be barnyard2.eth1.conf
Obviously, you'll need to tweak this configuration to your environment (ie - 'mypassword').
To start Barnyard for the first time, type:
You should see output similar to the below:
(Figure 5. Barnyard2 starting up. Pay attention to the 'database' information)
Other Barnyard2 configurations from the remaining interfaces will be very similar to our Internet facing side. I've including them in this document, but the changes should be pretty obvious (ie - waldo_file, hostname and interface)
Command line to start Barnyard2:
Command line to start Barnyard2:
Pulling the 'kismet_server' into the mix
To veteran Kismet users, this setup is probably a bit strange. Why not just run Kismet "drones" on the remote wireless IDS systems? The "drones" can report back to a centralized server.
This idea is okay, but relies on the Kismet server to do the data interpretation of the drones. That is, if the Kismet server "dies", information from the drones is lost. Also, I still need a method to "push" information from the Kismet server to our MySQL back end. Kismet supports various log output formats, which is excellent. However, there is a lack of output formats that transport data over a network into, for example, a database format.
Another thought was to do multiple Kismet drone/servers in the field, but we end up with the same situation. That is, the lack of a network capable of transporting to our back end.
I brought this up to Dragorn on the #kismet IRC channel (irc.freenode.net). Dragorn's response was to build an application that'll query the Kismet API via the Kismet server and pull the information we need. Once the application has the information we need, we could transport it over the network however we see fit. Overall, I completely agree with Dragorn. That is a possible way to accomplish network transmission of data.
But, this misses the overall problem. Kismet, at its core, lacks any means to transport information over a network.
I had mentioned that basically what I wanted was the exact same information the Kismet console was being given, but transmitted over syslog. Dragorn opposed this idea, and again pointed me back to the Kismet API idea.
In some aspects, I completely agree with Dragorn. In actuality, I might be able to pull more information from the Kismet servers. However, this adds a bit more complexity to our wireless IDS solution. It could even be argued that it's not much more complexity at all. However, creating a syslog patch for the Kismet server was about 5 lines of C code. Granted, it's a sloppy patch, but this gives the Kismet server itself the ability to transport wireless IDS information via syslog.
Today, almost everything you put in your network has the ability to transport log information over a network. My personal belief is that it should be an option within Kismet itself. Even more so if Kismet is to be used as a serious wireless IDS system.
It's not that an application querying the Kismet API is a bad thing. Dragron pointed out that it could be done in just about any language (Perl, C, Ruby, Python, even bash). If I'd gone with the Kismet server/drone method, this might be acceptable. That's not the model I chose for reasons outlined above.
These will be field sensors. Even though this is only a PoC model, there is an assumption that these development utilities will be available. In the majority of cases for IDS/IPS systems, development tools are not likely to be present on these machines. At my place of employment, it's common not to have Perl, Ruby, GCC (C compiler), Python, etc loaded. That leaves me with one option. Bash, or shell scripting, to work with the Kismet API. That leaves a bad taste in my mouth, so I decided that would not be the way to go for me.
There is one other option. Everything we've done up to this point in our PoC can be supported by a package based system. For example, Snort, Barnyard2 and even Kismet updates or installs can be rolled out as packages. Hence, no development tools are needed on the "sensor" end of things.
I could write a custom C program that communicates with the Kismet API. I could then build that and roll it out as a package to the remote sensor. This idea I don't find so bad. Perhaps I'll come back to this some day. My patch seemed the most simple solution for my needs.
Kismet; Syslog me, baby
So far, we have almost all critical information of our wireless IDS system reporting back to a centralize MySQL database. We're missing one piece. That's the information Kismet provides about layer 2 attacks and other "networks" that "pop up" in our environment.
Again, our ultimate goal here is to build a unified console for wireless IDS. This means, that data being collected by Kismet's channel hopping/sniffing will ultimately need to be within the same database as our Snort information. From the database level, we already have 3 sensors running. They are:
Our final sensor.....
At his point, we have not configured our syslog service to transmit data to our back end. However, there is more to our syslog data than Kismet information. That is, while Kismet will be supplying us information via syslog, so will other services. For example, OpenSSH session information gets logged via syslog. Firewall information (via iptables) might get logged via syslog. It would be best to have all that data.
So really, what Sensor ID # 4 will become is a 'syslog' interface. While most of it will probably be Kismet related, it'll also have other information we might find useful on our PoC wireless IDS system.
The first step to take is to make our PoC system send its syslog information to a centralized repository. As a log is generated, I want it sent to our back end. Not for correlation, but for archival purposes. If we do this correctly, even if an attacker somehow gains access to the system and alters the logs, we'll have a known 'good' copy. The logs are sent in 'real time', so even if the attacker mangles local logs, we'll be able to review something 'clean'.
At the time of this writing, the big players in the syslog field under *nix are syslog-ng and rsyslog. Below are links to example configuration files for each. Remember, "client" means our remote satellite wireless IDS system. This system will be sending the logs to the back end for collection. The "server" is the configuration for the side that will be receiving the logs.
I'm using the the Rsyslog configurations. I've been a long time Syslog-ng user, but recently switched to Rsyslog due to some features it has over Syslog-ng. For example, in our Rsyslog client side configurations, I'm sending via the more reliable TCP method rather than UDP. This helps ensure the messages reach our back end servers. Rsyslog can also 'queue' events in the event our OpenVPN connection has died. On the Rsyslog server side, I'm storing events into a SQL database. This allows me to view all events from our wireless IDS sensor in a nice graphical interface. The interface I'm using is Loganalyzer. You could easily use something like Splunk or Logzilla to view syslog events.
That's getting a bit outside the scope of this document. While access to the archival syslog information is important, what I want are the threats to be located in one console. There is also plenty of documentation and 'HOWTOs' related to projects like Rsyslog and Loganalyzer.
One thing you might have noticed in our rsyslog/syslog-ng server/client examples, is a reference to 'sagan'. Sagan is ultimately the software that will 'patch' the information supplied from our Kismet server via syslog to our back end Snort based MySQL system. To make things a bit more clear, let me explain what Sagan is and what it does.
Sagan is a real-time correlation engine. What this means is that Sagan 'reads' logs, as it receives them, and attempts to correlate the information within your Snort SQL database with the packet/IDS/IPS data based on rules. For the sake of simplicity, lets examine what Sagan does.
Lets assume, for the sake of an example, you run an SMTP server. In front of this server, you use Snort as your IDS/IPS engine. So, as traffic is flowing to and from your SMTP server, that traffic also flows through your Snort sensor. For our example, lets assume a potential attacker is probing your network. They connect to your SMTP server, and issue the SMTP command "expn root". This traffic will be "seen" by Snort and "flagged" as an "attempted recon", and sent to your SQL back end. When Snort logs its information about the 'attempted-recon', it'll record information like, packet data (dump), source TCP/IP address, destination TCP/IP address, source TCP port, destination port, timestamp, etc.
Sagan, does the exact same thing, but instead of gathering the information about the 'attempted recon' at the network/packet level, it pulls the information from the log level. When the SMTP server sends out the log (via syslog), it'll typically have much of the same information. For example, the timestamp, TCP/IP destination and source, destination port (port 25) and sometimes even the source port!
Since Sagan has a lot of the same information as Snort, we can now correlate log events with our IDS/IPS packet level events! Sort of nifty, eh?
It gets better. Sagan can not only communicate directly with our SQL back end, but also store information into our Snort SQL database. Sagan uses a very similar rule set as Snort. Why is this important? The same utilities you use for rule management with Snort work with Sagan.. There's no additional software to load, only Sagan!
Sagan configuration and installation
Like Snort, we'll first need to compile and install Sagan. On our wireless PoC IDS system, we'll download the latest version of Sagan. This can be obtained from http://sagan.softwink.com/download/sagan-current.tar.gz.
Once download, we'll do the following:
Most of this should be straightforward. We want to add a user to the system "sagan", for similar reasons we add a 'snort' user. We'll be starting Sagan as 'root', but once Sagan is initialized, Sagan will 'drop' its privileges and 'become' the user 'sagan'.
This 'mkfifo' builds out FIFO (First In/First Out). This is also sometimes known as a 'named pipe'. This is where Sagan will be receiving log messages from either rsyslog or syslog-ng. Previously, in the syslog-ng and rsyslog "client" example configurations, the FIFO feature and Sagan templates were included. If you're confused, you might want to refer to them.
Next we'll want to pull down the latest Sagan rule set. The rule sets are very similar to Snort rule sets. They tell Sagan what to 'look' for in syslog messages. To get the latest rule set, simply do the following.
We can now configure Sagan. The key thing to look for is the database access ("output database:") plug in information. This tells Sagan how and what database (snort_beave) to access.
If you're interested in enabling other output plug in's, it'd be best to refer to the Sagan web site.
Like Snort, Sagan rules are broken down protocols and/or programs. There are actually many more rules supplied via Sagan, but they aren't needed for this project. For example, Sagan rules ship with "proftpd.rules", but we won't be running a ProFTP server. If we enabled those rules, we would be watching for things that'll never happen on our wireless IDS system. This will simply use CPU ticks and memory. Lets break down the rule set we're using.
As you can see, we're using Sagan for a bit more than just Kismet traffic. We're also using it to keep an eye on other functions of the system.
Once Sagan is installed and configured, we'll need to give it rights to the Snort database (snort_beave). Since Sagan works similarly to Snort, give it the same rights, just with another user name ("sagan"). On our back end server, we'll do the following. This will give our satellite wireless IDS sensors access to the database.
If everything is configured properly, we can now fire up Sagan and verify things are working. To do that, simply type (as "root"):
You should see something similar to the below:
(Figure 6. 'Sagan' startup splash screen. I'm using the SVN version of Sagan)
(Figure 7. Hitting a key in Sagan's interactive mode will dump statistics)
You can further check Sagan to see if it's operating properly by examining the Sagan 'alert' log. This is normally stored in the '/var/log/sagan/alert' file. If you're a Snort user, the output in the Sagan alert file should look pretty familiar, since Sagan uses a 'Snort like' alert syntax. Examining the 'alert' file, you should see something like:
Once you're satisfied with Sagan's setup, you can tell Sagan to run in the background with the --daemon flag. To get statistics from Sagan, when running in the background, simply issue a 'killall -USR1 sagan'. Statistics will be stored in the /var/log/sagan/sagan.log file.
That's it! Final notes!
As a PoC system, we end up with a decent wireless IDS solution. Best yet, we're using nothing but open source software.
You've probably noticed that I've been dwelling on the fact that all potential attack or alert data must go to the same Snort MySQL database back end. Since we have all data in one place, we can now use the power of SQL to correlate that information. Another plus to this, we can use Snort web based front ends to examine the data. Yes, even the Kismet/syslog data!
With this mixture of software, we don't have to hunt through multiple consoles to do our job. We have one, unified console from which to view potential threats.
We can now take advantage of open source IDS consoles like BASE and Snorby. At Softwink, Inc. we use a proprietary console that queries the SQL database. Guess what. It doesn't matter. If your console, report generation utiltities, etc. can query a Snort database, they can be used with this mix! It doesn't matter, it'll always work with this solution!. Here's the short laundry list of things we've accomplished:
It wouldn't be fair to not show you the final outcome of this weekend PoC project. Below, I've included some screen shots of both BASE and Snorby working with our wireless IDS system with data supplied from both Sagan (syslog) and Snort (packet level).