Introduction
As part of my further training, I have to analyze a security incident with splunk. Therefore, I was given access to a Splunk-enviroment and received a list with a couple of questions like What was the first brute force password used?
. I didn’t receive any further information.
As I’m a complete newby with Splunk, I presume that I will be pretty challenged :-)
Preparation
thoughts
the questions, which I have to answer to, are unsorted, but the data seem to be structured. Some of the questions seem easier, some harder to answer to. I’m pretty sure that, once sorted the right way, the questions will lead me through the sec-incident.
approach
I imported the questionlist as csv in Excel and sorted it by the column Number
result
The first question is now This is a simple question to get you familiar with submitting answers. What is the name of the company that makes the software that you are using for this competition? Just a six-letter word with no punctuation.
, so I’m pretty sure to have the list ordered the right way. By the way, the right answer is Splunk
.
101-What is the likely IP address of someone from the Po1s0n1vy group scanning imreallynotbatman.com for web application vulnerabilities?
thoughts
this question shouldn’t be too hard to answer. As an automated scan generates lots of requests, there should be some traces in the logfiles.
approach
to narrow the log-data, I set the query index=* imreallynotbatman.com
. Because I have no idea when the incident happened, I set the option all times.
A quick look to the field src-ip revealed that more than 70% of the traffic was generated by the ip 40.80.148.42. To narrow the data further, I set the query index=* imreallynotbatman.com sourcetype="stream:http"
, because the vulnerability-scan of a web-app will generate most likely http-traffic. Now, 94.424% of the collected data stick to 40.80.148.42.
result
the most likely ip is 40.80.148.42
102-What company created the web vulnerability scanner used by Po1s0n1vy? Type the company name.
thoughts
Hmmm, as I revealed the attackers ip, I can now inspect the traffic between the attacker and the web-server. Probably, there are some traces which lead me to the correct answer?
approach
First, I narrow the data from the http-stream between the attacker and the web-server to post-requests and take a look at the user-agents. index=* imreallynotbatman.com sourcetype="stream:http" src_ip="40.80.148.42" http_method=POST http_user_agent="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.21 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.21"
will do that.
result
Oh yes, as guessed, there are some traces left. Right after the user-agent, there is something written about Acunetix Web Vulnerability Scanner - Free Edition
103-What content management system is imreallynotbatman.com likely using?
thoughts
Also this question should be pretty easy to answer.
approach
Let’s just look for some hints about well known cms in the same traffic I allready searched to answer the previous questions.
result
In the tag dest_header, there are many URL’s cointaining joomla, so this is likely the correct answer.
108-What IP address is likely attempting a brute force password attack against imreallynotbatman.com?
thoughts
To answer this question, I have to keep in mind that the brute force attack was driven against a web-applikation. So, there will for sure be quite a lot of http-traffic between the attacker and the web-server.
approach
Similar to question 114, I have to extract the http-stream between the attacker and the web-server. To achieve this, I set first the query index=* sourcetype="stream:http"
and drill then the field src-ip. Most of the traffic was initiated by 40.80.148.42. That IP I could allready stick to Po1s0n1vy in question 101, but is this also the correct answer now?
To reduce the possibilities, I add a regex to the query, as a brute force attack will most likely contain somewhere passw in the http-traffic, isn’t it?
result
So, index=* sourcetype="stream:http" | regex (passw)
and a drill down on src-ip reveals that Splunk finds 1235 entries (93.62% of all entries) starting from 23.22.63.114. My guess? Correct answer….
114-What was the first brute force password used?
thoughts
Hmmm. Brute force a password? So there will be pretty sure a lot of http traffic, most likely POST-requests. All I have to do is to narrow down the data to the specific fields :-)
approach
index=* source="stream:http" http_method=POST
will narrow the data allready pretty much, but, still, there is to much data in the result-set. Out of question 108, I know, that the attackers IP is most likely 23.22.63.114, so lets add this to the query (index=* source="stream:http" http_method=POST src_ip="23.22.63.114"
). Now, all what is to do is to order the result-set by time and pick the password out of the form data.
result
index=* source="stream:http" http_method=POST src_ip="23.22.63.114" | sort -_time desc
leads to 12345678
115-One of the passwords in the brute force attack is James Brodsky’s favorite Coldplay song. Hint: we are looking for a six character word on this one. Which is it?
thoughts
As in question _114__ explained, I’m able to filter the data to the requests which contain the different passwords of the brute force attack. So lets see if I can extract the pure passwords and compare them with the given criteria about coldplay….
approach
A little research on the Internet showed me, that I can with | table form_data
extract only the form-data out of a result-set, so my first search is index=* source="stream:http" http_method=POST src_ip="23.22.63.114" | table form_data
. Now, I have to sort out all results which don’t contain six characters, this sounds very strong like regex, so a little more research on the net is needed. Tweaking a little bit the queries and some regex-repetition with [https://regexr.com/] led me to the next shot index=* source="stream:http" http_method=POST src_ip="23.22.63.114" | table form_data | rex field=form_data "passwd=(?<passwd>\w+)"
. No, I have a seperate, temporary field passwd, but still much to many canditates….
While rex
extract data out of fields, regex
is used to filter data….so index=* source="stream:http" http_method=POST src_ip="23.22.63.114" | table form_data | rex field=form_data "passwd=(?<passwd>\w+)" | table passwd | regex passwd = \w{6}
extractded a list of 343 candidates. As I’m not a coldplay-fan, still to many options….hmmmm….for the moment, I’m stuck with this one :-(
result
116-What was the correct password for admin access to the content management system running “imreallynotbatman.com”?
thoughts
Huh, this one should be to solve for me too. In my opinion, there could be to ways to find the correct answer.
- count how many times a password was transmitted -> the correct password will at least be sent 2 times, one time to detect, one time to login.
- analyze the 2-way webtraffic, the request and response of the succesfull login should be findable.
approach
lets first stick to way one. In question 115, I examined the passwordlist allready, so I can continue with that part of the queries. But unfortunately, index=* source="stream:http" http_method=POST src_ip="23.22.63.114" | table form_data | rex field=form_data "passwd=(?<passwd>\w+)" | table passwd | stats count by passwd | sort - count
didn’t show any double passwords.
Hmmm…STOP….May be that the login was not made with the same IP as the brute force attack?
result
So, open the query to index=* source="stream:http" http_method=POST | table form_data | rex field=form_data "passwd=(?<passwd>\w+)" | table passwd | stats count by passwd | sort - count
shows, that batman was found 2 times.
117-What was the average password length used in the password brute forcing attempt?
thoughts
Also this one is pretty easy once I extracted allready the passwords used for the brute force attack. Probably all I have to do is do a little research on how to use statistical functions in Splunk.
approach
As a first step, I start with index=* source="stream:http" http_method=POST src_ip="23.22.63.114" | table form_data | rex field=form_data "passwd=(?<passwd>\w+)" | eval laenge = len(passwd)| table passwd laenge
which shows me to every password its length.
After that, I agregate the result with | stats avg(laenge) as durchschnitt
which leads me to the following result:
result
6.174757281553398
118-How many seconds elapsed between the time the brute force password scan identified the correct password and the compromised login?
thoughts
Well, as I’m able to filter out the correct admin-password (116), I should also be able to follow the two events when they were sent to the server…
approach
with index=* source="stream:http" http_method=POST src_ip="23.22.63.114" | rex field=form_data "passwd=(?<passwd>\w+)" | table _time passwd
, I get a first shot with all passwords. Now, I add a regex to the query and open the search for all hosts: index=* source="stream:http" http_method=POST | rex field=form_data "passwd=(?<passwd>\w+)" | table _time passwd | regex passwd = batman
. Now, I could Splunk let calculate the time-delta, or I just calculate it by hand….
result
about 92 secs
119-How many unique passwords were attempted in the brute force attempt?
thoughts
Oh la la, not much to solve here ;-)
approach
In question 115, I allready examined the complete passwordlist. In question 116, I inspected the list to find double entries. All I have to do is count how many results are found with index=* source="stream:http" http_method=POST src_ip="23.22.63.114" | table form_data | rex field=form_data "passwd=(?<passwd>\w+)" | table passwd
to recieve the unique password-requests.
result
412
200-What was the most likely IP address of we8105desk on 24AUG2016?
thoughts
This is probabaly also one of the easier questions. As there is a known hostname and a known date, the search should be easy to define.
approach
I think, the best approach will be to filter the data with this two criteria. To achieve this, I minimize the timerange to 2018-08-24 and I start with the search-request index=*
. A quick look to the field host shows that we8105desk is responsable for quite a lot of the log-data, so I just add it to the search-query: index=* host=we8105desk
. Now, I can inspect the field src-ip which led me to the following result:
result
The IP was most likely 192.168.250.100
201-Amongst the Suricata signatures that detected the Cerber malware; which one alerted the fewest number of times?
thoughts
Probably, this will be easy to answer to once I understand the signature of suricata. A quick research on the I-net shows up that Suricata is an Open Source Intrusion Detection System.
approach
As a first step, I try to reduce the data to those which have suricata as source, but index=* sourcetype=suricata
shows still way to much information, so I need to be more precise about. Because I know, that I have to look out for the Cerber-malware, I can add alert.signature=*cerber*
to the query, which, in fact, reduces the dataset to 5 results. Adding the signature to the shown fields, I can easily count by hand the signatures.
result
So, as shown below, the signature with the id 2816763 was listed only once.