Analyzing the Mirai Botnet with Splunk

On September 20th, the largest Distributed Denial of Service attack ever recorded targeted security researcher Brian Krebs. This attack was made up of Internet of Things (IoT) 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 underway by security researchers.

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 associated with Mirai with malicious IP addresses, providing me with insights about Mirai’s attempts to gain access to my system.

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 (My honeypot started collecting the week of July, 25th, so a little over sixty days worth of data.). From this view, we can determine that nodes in the botnet have attempted to access my server using both Telnet and SSH. In the case of telnet, this is blocked by default since it is an insecure protocol for administration of your server. To determine if these bots were successful at authenticating using SSH 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. For a detailed analysis of the products targeted by Mirai check out Brian Krebs’ post “Who Makes the IoT things Under Attack?

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 IoT 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 the other botnet.


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 significant number of the systems targeting my server are based in Ukraine, Netherlands, Germany, China & United States.


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


A similar pattern emerges with a majority of the attacks attributed to Ukraine, Germany, United States and China. This would indicate there is overlap between the Mirai botnet in Ukraine and this secondary botnet targeting the Raspberry Pi.  This could indicate a few different scenarios: the Mirai infected devices are infected with another botnet or other devices on the same network are infected. Another plausible explanation, is the leak of Mirai’s source code lead to other botnets adopting this code to their existing routines in an attempt to gain more penetration across the web.


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.

Are those new visualizations in Splunk 6.5? I don’t see those as map options in my 6.4 stack.

October 9, 2016

Choropleth maps were introduced in 6.4, for the background I am using dark.css from the dashboard examples app and have the opacity set to 0. The other map is using a darktile set from MapBox’s web API.

Anthony Tellez
October 9, 2016

when I sudo to root on my splunk server 1 week ago, the System informed me there round about 3600 failed login attempts occurred since the last login. After a “whoop wtf” I also index my /var/log/secure and also create a list of the Usernames which are tried. I found also ‘mother, ubnt and pi’ and post this list on my pastebin:
Thanks for this great work. Maybe I will follow this inspiration and do something similar.
Kind Regards

Dirk Mader
October 10, 2016

Nice work

October 13, 2016

2 Trackbacks

  1. […] from Splunk Blogs […]

  2. […] by /u/campuscodi [link] […]