Skip to content

Instantly share code, notes, and snippets.

What would you like to do?

Analyzing the Mirai Botnet with Splunk

On September 20th, the largest Distributed Denial of Service attack ever recorded targeted security researcher Bryan Krebs. This attack was made up of an Internet of Things devices such as cameras, wireless controllers and internet enabled devices peaking at 400,000 total. Now dubbed the "Mirai botnet", these devices scanned the internet for devices running telnet and SSH with default credentials, infecting them and further propagating. The source code for the botnet has since leaked to GitHub[] where further analysis is taking place.

During the infection time period, I happened to be running a honeypot and captured some infection attempts on my own system. Using Suricata and /var/log/secure.log I can correlate invalid login attempts with malicious IP addresses, providing me with insights about Mirai and other IoT botnets.

Telnet & SSH Traffic

Filter down to only SSH & Telnet port activity on the server and get a count of the SSH attempts for a time range:

index=suricata dest_port=23 OR dest_port=22 | stats count by src_ip dest_port | sort -count

There are more than 10,000 unique IPs which have communicated with my server over port 23 & 22. Some of which have attempted to connect in excess of 1000 times during the time range specified. From this view we can determine that bots have attempted to access my server using both Telnet and SSH. In the case of telnet, this is blocked since it is an insecure protocol. To determine if these bots were successful we need to review secure.log

Invalid Users - mother, ubnt, 666666, 888888, supervisor, pi

In /var/log/secure.log there are differently formatted events as Linux is tracking not just logon attempts, but all authentication attempts made on the system. So for example sudo or su - Splunk to become the Splunk user is tracked in this log in addition to SSH attempts with a bad password. To quickly parse these logs and find what I needed, I built a TA for specific log types found in secure log. The specific type of event we are looking for is an invalid user SSH attempt.

Oct  6 15:23:45 splunk-honeypot sshd[17214]: Invalid user ubnt from

The reason I have picked this event is because there are features of the Mirai botnet and other IoT botnets which attempt to login as users that are specific to IoT devices. As an example, there are 62 usernames & password combinations hardcoded in Mirai's scanner.c module. Five stand out as good indicators of Mirai: mother ubnt, 666666, 888888, and supervisor. These usernames are unique to specific IoT products targeted by Mirai and create behavioral signature to look for. [] The following search: gives us a list of all the invalid user access attempts on the system. Some of which are Mirai, others are botnets targeting default account credentials or bad passwords.

index=os operation="invalid user" 
| stats count by user src_ip 
| table user src_ip
| sort user

An interesting user account not targeted by Mirai, but seemingly being targeted by another botnet is the user pi. We can save those results to a separate lookup or filter to that specific user in our correlation search for investigation into another botnet targeting IoTs.

To save the results for correlation we append | outputlookup bonet-user-scans.csv to the end of the search.

Correlate using lookups

We could just focus on the two dest_ports for SSH & Telnet to create our correlation search, but since we can't say with 100% certainty that those were the only two ports used by an attacker, we need to widen our search. Suricata is helpful to us in this case, because it is monitoring all ports and protocols including sessions dropped by the OS where there is not a service listening on that port. In this example search, we are searching all Suricata logs for the matching src_ip found in our botnet lookup file.

index=suricata [ | inputlookup bonet-user-scans.csv | table src_ip | dedup src_ip ] 
| iplocation src_ip 
| geostats count by event_type

We can take this a step further and pass in specific usernames tied to Mirai in the subsearch using the where clause. This narrows the criteria of matching src_ips in the Suricata logs to only src_ips which attempted to login using a username used by Mirai.

index=suricata [ | inputlookup bonet-user-scans.csv where user="ubnt" OR user="mother" OR user="666666" OR user="888888" OR user="supervisor"  | table src_ip | dedup src_ip ] 
| iplocation src_ip 
| geostats count by event_type

This gives us the following view of the Mirai nodes targeting our system, broken apart by event_type as seen by Suricata:

GeoIP Attribution from MaxMind tells us that a majority of the system targeting my specific server

Another interesting user account to look at is the pi user. This search allows us to filter down to botnets targeting Raspberry Pi's enabled with default credentials.

index=suricata [ | inputlookup bonet-user-scans.csv where user="pi" | table src_ip | dedup src_ip ] 
| iplocation src_ip 
| geostats count by event_type


Botnets are becoming less sophisticated and easier to create due to the difficulty for consumers to lock these products down. Manufacturers of IoT devices are not helping in this struggle by shipping products with easily guessable and static passwords. Most of the problem could be mitigated by requiring stronger passwords on the devices when consumers first activate the product and shipping the product with a randomly generated strong password only known the user. As this problem persists, monitoring your network infrastructure for unsecured IoT devices is critical to preventing attackers from gaining a foothold. Splunk can provide insights by correlating various data sources which together form a behavioral signature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment