Phase 1 Network
Reconnaissance
tshark -r eCTHP.pcap -T fields -e ip.src -e ip.dst | sort -u > IPS.txt
tshark -r eCTHP.pcap -T fields -e _ws.col.Protocol | sort | uniq -c | sort -nr > protocols.txt
tshark -r eCTHP.pcap -q -z endpoints,ip > statistics-1.txt
tshark -r eCTHP.pcap -q -z conv,ip > statistics-2.txt
Internal Network: 55.68.50.x
- 55.68.50.130 - Most active (initially compromised machine based on Splunk findings showing CLIENT)
- 55.68.50.129 - Second most active internal host
- 55.68.50.134 - Third internal host
- 55.68.50.2 - Gateway/router
- 55.68.50.254 - Default gateway
External IPs of interest:
- 192.168.1.x - Another internal network (likely the attacker's network based on connection patterns)
- Many cloud/CDN IPs (Azure, AWS, Google, Akamai, etc.)
tshark -r eCTHP.pcap -Y "icmp" -T fields -e frame.number -e ip.src -e ip.dst -e icmp.type -e data.data > key.txt
tshark -r eCTHP.pcap -Y "icmp.type == 8" -T fields -e frame.number -e ip.src -e ip.dst -e data.data > ICMP.txt
the encoded ICMP pings. There are two different encoded payloads:
Frame 13289: 55.68.50.130 → 18.136.204.173
535535465831395954314a665330565a583152495156526653564e66525668425131524d575638324f463943575652465531394d543035485830464f5246394651564e5a5831525058314e515431526658313966583139665831383d
Frames 93978+: Between 55.68.50.129 ↔ 55.68.50.130
6162636465666768696a6b6c6d6e6f7071727374757677616263646566676869
First one:
echo "535535465831395954314a665330565a583152495156526653564e66525668425131524d575638324f463943575652465531394d543035485830464f5246394651564e5a5831525058314e515431526658313966583139665831383d" | xxd -r -p | base64 -d > flag.txt
root@kali:~/Desktop/tshark# cat flag.txt
INE__XOR_KEY_THAT_IS_EXACTLY_68_BYTES_LONG_AND_EASY_TO_SPOT_________
Second one:
echo "6162636465666768696a6b6c6d6e6f7071727374757677616263646566676869" | xxd -r -p
abcdefghijklmnopqrstuvwabcdefghi
Q1
This threat actor is known to initiate the C2 phase of the attack using an encoded ping request. What is the decoded content of this packet?
Answer:
INE__XOR_KEY_THAT_IS_EXACTLY_68_BYTES_LONG_AND_EASY_TO_SPOT_________
Q2
After finding the XOR key that was used to encode the C2 traffic, identify the first command that is executed on the compromised host.
extract and decode the C2 traffic to find the first command (Q2). Let's look at the TCP stream data:
tshark -r eCTHP.pcap -Y "tcp.stream == 120" -T fields -e tcp.payload | grep -v "^$" | head -5
Output
root@kali:~/Desktop/tshark# tshark -r eCTHP.pcap -Y "tcp.stream == 120" -T fields -e tcp.payload | grep -v "^$" | head -5
Running as user "root" and group "root". This could be dangerous.
** (tshark:125327) 00:09:47.146671 [Epan WARNING] -- Dissector bug, protocol HTTP, in packet 12588: ./epan/packet.c:812: failed assertion "saved_layers_len < 500"
** (tshark:125327) 00:09:47.146855 [Epan WARNING] -- Dissector bug, protocol HTTP, in packet 12588: ./epan/packet.c:812: failed assertion "saved_layers_len < 500"
485454502f312e3020323030204f4b0d0a5365727665723a2042617365485454502f302e3620507974686f6e2f332e382e31300d0a446174653a204672692c203036204a756e20323032352030393a35393a303320474d540d0a436f6e74656e742d547970653a20746578742f706c61696e0d0a0d0a
root@kali:~/Desktop/tshark# echo "485454502f312e3020323030204f4b0d0a5365727665723a2042617365485454502f302e3620507974686f6e2f332e382e31300d0a446174653a204672692c203036204a756e20323032352030393a35393a303320474d540d0a436f6e74656e742d547970653a20746578742f706c61696e0d0a0d0a"| xxd -r -p
HTTP/1.0 200 OK
Server: BaseHTTP/0.6 Python/3.8.10
Date: Fri, 06 Jun 2025 09:59:03 GMT
Content-Type: text/plain
Or extract a specific stream:
tshark -r eCTHP.pcap -z follow,tcp,ascii,120 -q
Output
root@kali:~/Desktop/tshark# tshark -r eCTHP.pcap -z follow,tcp,ascii,120 -q
Running as user "root" and group "root". This could be dangerous.
** (tshark:127902) 00:12:07.479569 [Epan WARNING] -- Dissector bug, protocol HTTP, in packet 12588: ./epan/packet.c:812: failed assertion "saved_layers_len < 500"
** (tshark:127902) 00:12:07.479667 [Epan WARNING] -- Dissector bug, protocol HTTP, in packet 12588: ./epan/packet.c:812: failed assertion "saved_layers_len < 500"
===================================================================
Follow: tcp,ascii
Filter: tcp.stream eq 120
Node 0: 55.68.50.130:50478
Node 1: 18.136.204.173:8000
118
HTTP/1.0 200 OK
Server: BaseHTTP/0.6 Python/3.8.10
Date: Fri, 06 Jun 2025 09:59:03 GMT
Content-Type: text/plain
===================================================================
tshark -r eCTHP.pcap -Y "tcp.stream == 121" -T fields -e tcp.payload | grep -v "^$" | head -10
Output
474554202f30623366343638332d333834332d346235302d396138622d3335363230653462643932303f636c69656e743d70726f6420485454502f312e310d0a486f73743a207a6f6f776f6f2e6d6f6f6f2e636f6d3a383030300d0a557365722d4167656e743a20707974686f6e2d72657175657374732f322e33322e330d0a4163636570742d456e636f64696e673a20677a69702c206465666c6174650d0a4163636570743a202a2f2a0d0a436f6e6e656374696f6e3a206b6565702d616c6976650d0a0d0a
485454502f312e3020323030204f4b0d0a5365727665723a2042617365485454502f302e3620507974686f6e2f332e382e31300d0a446174653a204672692c203036204a756e20323032352030393a35393a303420474d540d0a436f6e74656e742d547970653a20746578742f706c61696e0d0a0d0a
root@kali:~/Desktop/tshark# echo "474554202f30623366343638332d333834332d346235302d396138622d3335363230653462643932303f636c69656e743d70726f6420485454502f312e310d0a486f73743a207a6f6f776f6f2e6d6f6f6f2e636f6d3a383030300d0a557365722d4167656e743a20707974686f6e2d72657175657374732f322e33322e330d0a4163636570742d456e636f64696e673a20677a69702c206465666c6174650d0a4163636570743a202a2f2a0d0a436f6e6e656374696f6e3a206b6565702d616c6976650d0a0d0a" |xxd -r -p
GET /0b3f4683-3843-4b50-9a8b-35620e4bd920?client=prod HTTP/1.1
Host: zoowoo.mooo.com:8000
User-Agent: python-requests/2.32.3
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
root@kali:~/Desktop/tshark# echo "485454502f312e3020323030204f4b0d0a5365727665723a2042617365485454502f302e3620507974686f6e2f332e382e31300d0a446174653a204672692c203036204a756e20323032352030393a35393a303420474d540d0a436f6e74656e742d547970653a20746578742f706c61696e0d0a0d0a"|xxd -r -p
HTTP/1.0 200 OK
Server: BaseHTTP/0.6 Python/3.8.10
Date: Fri, 06 Jun 2025 09:59:04 GMT
Content-Type: text/plain
root@kali:~/Desktop/tshark#
root@kali:~/Desktop/tshark# tshark -r eCTHP.pcap -Y "tcp.stream == 121" -T fields -e tcp.payload | grep -v "^$"
Running as user "root" and group "root". This could be dangerous.
** (tshark:130108) 00:14:14.218963 [Epan WARNING] -- Dissector bug, protocol HTTP, in packet 12588: ./epan/packet.c:812: failed assertion "saved_layers_len < 500"
** (tshark:130108) 00:14:14.219127 [Epan WARNING] -- Dissector bug, protocol HTTP, in packet 12588: ./epan/packet.c:812: failed assertion "saved_layers_len < 500"
474554202f30623366343638332d333834332d346235302d396138622d3335363230653462643932303f636c69656e743d70726f6420485454502f312e310d0a486f73743a207a6f6f776f6f2e6d6f6f6f2e636f6d3a383030300d0a557365722d4167656e743a20707974686f6e2d72657175657374732f322e33322e330d0a4163636570742d456e636f64696e673a20677a69702c206465666c6174650d0a4163636570743a202a2f2a0d0a436f6e6e656374696f6e3a206b6565702d616c6976650d0a0d0a
485454502f312e3020323030204f4b0d0a5365727665723a2042617365485454502f302e3620507974686f6e2f332e382e31300d0a446174653a204672692c203036204a756e20323032352030393a35393a303420474d540d0a436f6e74656e742d547970653a20746578742f706c61696e0d0a0d0a
root@kali:~/Desktop/tshark# tshark -r eCTHP.pcap -z follow,tcp,ascii,121 -q
Running as user "root" and group "root". This could be dangerous.
** (tshark:131221) 00:15:11.347777 [Epan WARNING] -- Dissector bug, protocol HTTP, in packet 12588: ./epan/packet.c:812: failed assertion "saved_layers_len < 500"
** (tshark:131221) 00:15:11.347876 [Epan WARNING] -- Dissector bug, protocol HTTP, in packet 12588: ./epan/packet.c:812: failed assertion "saved_layers_len < 500"
===================================================================
Follow: tcp,ascii
Filter: tcp.stream eq 121
Node 0: 55.68.50.130:50479
Node 1: 18.136.204.173:8000
199
GET /0b3f4683-3843-4b50-9a8b-35620e4bd920?client=prod HTTP/1.1
Host: zoowoo.mooo.com:8000
User-Agent: python-requests/2.32.3
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
118
HTTP/1.0 200 OK
Server: BaseHTTP/0.6 Python/3.8.10
Date: Fri, 06 Jun 2025 09:59:04 GMT
Content-Type: text/plain
15
AccessCode Sent
===================================================================
root@kali:~/Desktop/tshark#
Good! Stream 121 shows "AccessCode Sent" - this is the C2 handshake. Now let's look at the next streams where actual commands should be:
tshark -r eCTHP.pcap -z follow,tcp,ascii,122 -q
Output:
root@kali:~/Desktop/tshark# tshark -r eCTHP.pcap -z follow,tcp,ascii,122 -q
Running as user "root" and group "root". This could be dangerous.
** (tshark:132698) 00:16:36.577331 [Epan WARNING] -- Dissector bug, protocol HTTP, in packet 12588: ./epan/packet.c:812: failed assertion "saved_layers_len < 500"
** (tshark:132698) 00:16:36.577417 [Epan WARNING] -- Dissector bug, protocol HTTP, in packet 12588: ./epan/packet.c:812: failed assertion "saved_layers_len < 500"
===================================================================
Follow: tcp,ascii
Filter: tcp.stream eq 122
Node 0: 55.68.50.130:50480
Node 1: 18.136.204.173:8000
167
GET /task?client=prod HTTP/1.1
Host: zoowoo.mooo.com:8000
User-Agent: python-requests/2.32.3
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
118
HTTP/1.0 200 OK
Server: BaseHTTP/0.6 Python/3.8.10
Date: Fri, 06 Jun 2025 09:59:05 GMT
Content-Type: text/plain
let's find packets with larger payloads that contain data beyond just headers:
tshark -r eCTHP.pcap -Y "ip.addr == 18.136.204.173 && tcp.len > 200" -T fields -e frame.number -e tcp.stream -e tcp.len
Now we have a list of frames with substantial data. Let's focus on stream 393, which has the most large payloads. Let's extract and decode one:
tshark -r eCTHP.pcap -Y "frame.number == 16577" -T fields -e tcp.payload | xxd -r -p > stream_393_payload.bin
root@kali:~/Desktop/tshark# tshark -r eCTHP.pcap -Y "frame.number == 16577" -T fields -e tcp.payload | xxd -r -p > stream_393_payload.bin
root@kali:~/Desktop/tshark# xxd -l 200 stream_393_payload.bin
00000000: 484f 5354 3a4f 5477 714f 773d 3d0a 434d HOST:OTwqOw==.CM
00000010: 443a 5069 5971 506a 4978 6233 302b 4a79 D:PiYqPjIxb30+Jy
00000020: 6b3d 0a52 4553 554c 543a 5178 7357 4767 k=.RESULT:QxsWGg
00000030: 3134 4268 775a 4242 6355 4867 4142 4468 14BhwZBBcUHgABDh
00000040: 7056 5a48 3579 6148 5673 626e 6c68 6448 pVZH5yaHVsbnlhdH
00000050: 4962 4658 4a76 6446 3550 4269 7770 5057 IbFXJvdF5PBiwpPW
00000060: 344a 5069 7772 5a48 396c 5958 4d4b 4668 4JPiwrZH9lYXMKFh
00000070: 4276 6633 4e77 6233 522f 6633 392f 6633 Bvf3Nwb3R/f39/f3
00000080: 392f 6633 3970 626d 562f 6633 6876 636e 9/f39pbmV/f3hvcn
00000090: 3972 5a58 6c2f 6447 6868 6448 3970 6333 9rZXl/dGhhdH9pc3
000000a0: 396c 6547 466a 6447 7854 5967 7346 596e 9leGFjdGxTYgsFYn
000000b0: 396b 6158 6875 596e 4679 6332 6469 6648 9kaXhuYnFyc2difH
000000c0: 4e35 596e 6838 626d N5Ynh8bm
Now let's decode this XOR-encoded data. Let me create a Python script to XOR decode it:
root@kali:~/Desktop/tshark# cat stream_393_payload.bin
HOST:OTwqOw==
CMD:PiYqPjIxb30+Jyk=
RESULT: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Ynl0ZXMTLS0rK39hbmR/ZWFzeX90bwx+YWJlaXJubW1nZ39/aW5lf394b3J/a2V5f3RoYXR/aXN/ZXhhY3RseX8WGH9ieXRlc39sb25nf2FuZH9lYXN5f3Rvf3Nwb3R/f39VVVUPDRYfBwkaGB0cchYFAxYNGQkVHRAHWXJodWxueWF0chsVcm90eWh+cmFiY2pVSx42NjMoPzw4MW8RMj0qdH9/f39/f39/f2luZX9/eG9yf2tleX90aGF0fw02LCYqKDMgJTYxFhh/Ynl0ZXN/bG9uZ39hbmR/ZWFzeX90b39zcG90f39/f39/f39/aW5lf394b3J/a2V5f3RoYXQMPTIrIHhhY15xZGILBWJ/ZGl4bmJxcnN6YnxzeWJ4fG5kYmlyYm5tcmliYmJiYmJiYn90c3hiYmVyb2J2eGRiaXV8aWJ0bmJ4ZXx+aXFkYgsFYn9kaXhuYnFyc3pifHN5Ynh8bmRiaXJibm1yaWJiYmJiYmJ/YnRzeGJiZXJYDC4MNzwmLSAnOhgmMDE5ETE9OjAzU186Ynl0ZXN/bG9uZ39hbmR/ZWFzGDs+OiwncCIxMjAtJn8uKjArKD1lOTAqbzN/Ozc2PDE7MnR/aXN/ZXhhY3RseX8WGH9ieXRlc39sb25nf2FuZH9lYRcwLDUtMzY0RQc6DDo8Ki02KyYZPCwpNjQqNTprZXl/dGhhdH9pc39leGFjdGx5fxYYfw84OiQ0OmwuOyM2NScqOGUgPT1/Jyo8JiImICZ/MzA4f39/f2luZX9/eG9yf2tleX90aGF0f2lzf2V4YWN0bHl/FhgbKyo1Jz86KEUdIgsgJSEQMi82Kyw8Ji8DIiYiNjM6ODp/f39/aW5lf394b3J/a2V5f3QcID86aTwoKz0zMDwlKX9ZXn8kMDggIH8jPW4oKykrNn8qIzk8PCA8f3Nwb3R/f39/f39/f39pbmV/f3hvcn9rZXl/ECEyNT0lNjtPCyQPOy09G0RRKScrBDc6KSUjKyA6YW5kf2Vhc3l/dG9/c3BvdH9/f39/EzA+O2kvKzt/LSE+MCoheTsxPig3Omk3LSwuJDEnbHl/Fhh/Ynl0ZXN/bG9uZ39hbmR/ZWFzeX90b39zcG90f39/fxs2LD49JSshVQw9HCssPyA0DyYnJz0zLAMtLC4oLzErPH8WGH9ieXRlc39sb25nf2FuZA83LjUwMzFvLCojOzEyfy86LTkwLTIoICY6f3hvcn9rZXl/dGhhdH9pc39leGFjdGx5fxYYf2J5dGVzf2xvbmd/YW4ANjYgMTU6MEUMNgM2Jys6Mis2MjoPLSA4LDM6Pypyf2tleX90aGF0f2lzf2V4YWN0bHkcXlkxJTx0MTs6bDw3NCskI2QrLCw2eX90b39zcG90f39/f39/f39/aW5lf394b3J/a2V5f3RoYXR/aXN/ZXhhY3RsHTZFWT0uPDBPADocPSEhNi0rFzYrJj88DyYgPDYjPAQtNik2Mzo4On9pbmV/f3hvcn9rFSswMiEtMX86OjEiNCRjJD42PFNLLGJ5dGVzf2xvbmd/YW5kf2Vhc3l/dG9/c3BvdH9/f39/f39/f2luZX9/eG9yfw8sKj42JCQwVRo2Fis7MyY1PzwdV0s6Eis9KiE2ODYeNTY3Jyg6IiRzeX90b39zcG90fxYxPC06Piw6aT0mNzo8Oj42JSJ5LyYhLiY2PSp/ZXhhY3RseX8WGH9ieXRlc39sb25nf2FuZH9lYXN5f3Rvf3Nwb3QbNiw+PTM6O1UaKwYtOjk7Nw8qIjw5PSQkBC0gJTYpPSYmdGx5fxYYf2J5dGVzf2xvbmccMyslKyBhMnkvNSg6NTkjMX9/f39/f39/f2luZX9/eG9yf2tleX90aGF0f2lzf2V4YWN0bHl/Fhh/Ynl0ZXN/bG9uAzYyLyYzICVZCjoWLjw4JT8ELTYpNjM6ODp/aW5lf394b3J/a2V5f3RoYXR/aXN/ZXhhATUvMn9DSH8kMDggIH8tISpnOyg8ITwxLiEwOidvf3Nwb3R/f39/f39/f39pbmV/f3hvcn9rZXl/dGhhdH9pc39leAUqJy07M1NcVRE8BiAgKyM9KxctKDgtMyAmNnl/dG9/c3BvdH9/f39/f39/f2luZX9/eB03LD8qKzp0Lig4OjpzPis8YSc9Pjw8QlctKzwnZXN/bG9uZ39hbmR/ZWFzeX90b39zcG90f39/f39/f39/aW5lf38cJiE+KSk8O14bJAc3PCc7Ki8vEyYlLzZaXTgneXRlc39sb25nf2FuZH9lYXN5f3Rvf3MDJyErfzswKDF/KzcsbjYmLCwqP39rZXl/dGhhdH9pc39leGFjdGx5fxYYf2J5dGVzf2xvbmd/YW5kf2Vhc3l/dG9/Fzk8NT0zOjtVDDobOis7Ig8tMTk7My4iPH90aGF0f2lzf2V4YWN0bHl/Fhh/Ynl0ZXN/CCosMjhhPjYwIjMyNCx0b39zcG90f39/f39/f39/aW5lf394b3J/a2V5f3RoYXR/aXN/ZXhhY3RseX8WGH9ieXRlcxoiLiwrOiVuTgwgEioqKzEiGj0mJiYwMTI6MSsPLTY/Jyk6OD1vcn9rZXl/dGhhdH9pcxIqPCglLWw/NkRVKCMrMWU2MTomPCgxLCsqK2U3MjUqMTx/c3BvdH9/f39/f39/f2luZX9/eG9yf2tleX90aGF0f2kXNjY5Iy8xKFMMU3s3IzczIB0wOCYoPg8zJzI2KSQ0PH90b39zcG90f39/f39/f39/aW4HJi85PCF/Pzc4KTE6MjF/Kjs6JjMoLTNseX8WGH9ieXRlc39sb25nf2FuZH9lYXN5f3Rvf3Nwb3R/f39/f39/f39pCys+PTQqNn9BFjwNMSUuIDoaOyoxPC40OhwrNkBRMyc+MWVzf2xvbmd/YW5kf2Vhc3l/EiAtMDVvJzcqKzswKDF/OTshKH8+eD03MiQxPH8nMTIgOiRzf2V4YWN0bHl/Fhh/Ynl0ZXN/bG9uZ39hbmR/ZWFzeRs9PD4xPCowVQw6CjE7MDw0GTwsKTY0KjU6a2V5f3RoYXR/aXN/ZXhhY3RseX8WGH9ieQYgPjA6Km4kMCw+MSsgM3M/LTsifzc/LD82MTh/LCs+KzYmIGV/f3hvcn9rZXl/dGhhdH9pc39leGFjdGx5fxYYf2IdPTYyPSAqKk0MJAMlMSQmNg8wODoyNgA9PSk2Mzo4On9/f2luZX9/eG9yf2tleX90aGEEOjs1MDc1YTU7ICwyUxgyIzA6MTYxLSEtIn81Lzc0NmFzeX90b39zcG90f39/f39/f39/aW5lf394b3J/a2V5f3RoBT0sKDEzIDxLEDEFNC9TSiwtNzUxNg8+JjguMyQpIX9lYXN5f3Rvf3Nwb3R/f39/f39/FjI5KzcsMDYuJjprJHk8OCEkOitpMjkxPTNjNTktN1NWKys6NTE6MCJvbmd/YW5kf2Vhc3l/dG9/c3BvdH9/f39/fxoxPisiIDt/Uhw3HDkgOCsxDy07PSg/DzcxNyo4KT46Fhh/Ynl0ZXN/bG9uZ39hbmR/ZQIhPD4gKn80PCA2PjN/MD01OjwrOm5lf394b3J/a2V5f3RoYXR/aXN/ZXhhY3RseX8WGH9ieXRlc39sb25nf2FuZH8ALzI7MzErf1kDKh0xPC06Piw6CDA7JSwxOAsqJg85LC82OC0mMX9pc39leGFjdGx5fxZxMSErMSQgOmwubjctLi0hLDZhJDYtPyYxNHA8MSt/f39/f39/f2luZX9/eG9yf2tleX90aGF0f2lzf2V4YWN0bHl/clEsIzs4IDdVHyoaLjIkFCsxIBEhMCk9Izo0NW90f39/f39/f39/aW5lf394b3J/a2V5HDwpLzM6aSc3IHg1KjkpeSVZVjpieXRlc39sb25nf2FuZH9lYXN5f3Rvf3Nwb3R/f39/f39/f39pbmV/f3hvcn9rZR02JykjODotWQwgGzMmNTg8DE9VPS01PSYfNiIkHjU2NycoOiIkc3l/dG9/c3BvdH9/fxwtOj4rOmk9PDI9NyM7PGspMDE/O2F0f2lzf2V4YWN0bHl/Fhh/Ynl0ZXN/bG9uZ39hbmR/ZWFzeX90b39zcG90f38bNiw+PTM6LUQWOhs9Izc4KjE8DDE7Mj0wJwYsICoILiQpKyxZVj42PAQ3OiklIysgOmEBJiskKD15PjpvNj4gKiYsMDE+KzYwMX89IS46MXgpPS1rJDcwICAkJn88IDo3eCgtdDgxOhZLPi88dDY2LD8mISl/BSc3PictNj1VXkUKABUddBwTHhYSDH8WEQ8BFxIeDAYdEUFodHJ5ZWx5cmR+cmh1bG55YXRyGxVyb1NeECA6Pm8tKz4oIzd/MC84NzAjIXFZWgQxLT06LTAsfywqOT4qLSt4KT0tawEgMTUlKDd/CDA8ICsyYxcjNytEVzNiNjplJzclPG4jOjcnJzplKTIqfzYqOj1wKz0sPj0zOjtxroot@kali:~/Desktop/tshark#
root@kali:~/Desktop/tshark# cat > decode_c2.py << 'EOF' #!/usr/bin/env python3 import base64 xor_key = b"INE__XOR_KEY_THAT_IS_EXACTLY_68_BYTES_LONG_AND_EASY_TO_SPOT_________" with open('stream_393_payload.bin', 'rb') as f: content = f.read().decode('utf-8', errors='ignore') lines = content.strip().split('\n') for line in lines: if ':' in line: parts = line.split(':', 1) field_name = parts[0] b64_data = parts[1].strip() try: decoded_b64 = base64.b64decode(b64_data) result = bytearray() for i, byte in enumerate(decoded_b64): result.append(byte ^ xor_key[i % len(xor_key)]) print(f"{field_name}: {result.decode('utf-8', errors='ignore')}") except Exception as e: print(f"{field_name}: Error - {e}") EOF root@kali:~/Desktop/tshark# python3 decode_c2.py HOST: prod CMD: whoami /all RESULT: USER INFORMATION - User Name SID ============= ============================================= jolly\webprod S-1-5-21-3712913190-191217038-2414789797-1138 GROUP INFORMATION -- Group Name Type SID Attributes ========================================== ================ ============ =============================================================== Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group BUILTIN\Administrators Alias S-1-5-32-544 Mandatory group, Enabled by default, Enabled group, Group owner BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group NT AUTHORITY\INTERACTIVE Well-known group S-1-5-4 Mandatory group, Enabled by default, Enabled group CONSOLE LOGON Well-known group S-1-2-1 Mandatory group, Enabled by default, Enabled group NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group Authentication authority asserted identity Well-known group S-1-18-1 Mandatory group, Enabled by default, Enabled group Mandatory Label\High Mandatory Level Label S-1-16-12288 PRIVILEGES INFORMATION - Privilege Name Description State ========================================= ================================================================== ======== SeIncreaseQuotaPrivilege Adjust memory quotas for a process Disabled SeSecurityPrivilege Manage auditing and security log Disabled SeTakeOwnershipPrivilege Take ownership of files or other objects Disabled SeLoadDriverPrivilege Load and unload device drivers Disabled SeSystemProfilePrivilege Profile system performance Disabled SeSystemtimePrivilege Change the system time Disabled SeProfileSingleProcessPrivilege Profile single process Disabled SeIncreaseBasePriorityPrivilege Increase scheduling priority Disabled SeCreatePagefilePrivilege Create a pagefile Disabled SeBackupPrivilege Back up files and directories Disabled SeRestorePrivilege Restore files and directories Disabled SeShutdownPrivilege Shut down the system Disabled SeDebugPrivilege Debug programs Enabled SeSystemEnvironmentPrivilege Modify firmware environment values Disabled SeChangeNotifyPrivilege Bypass traverse checking Enabled SeRemoteShutdownPrivilege Force shutdown from a remote system Disabled SeUndockPrivilege Remove computer from docking station Disabled SeManageVolumePrivilege Perform volume maintenance tasks Disabled SeImpersonatePrivilege Impersonate a client after authentication Enabled SeCreateGlobalPrivilege Create global objects Enabled SeIncreaseWorkingSetPrivilege Increase a process working set Disabled SeTimeZonePrivilege Change the time zone Disabled SeCreateSymbolicLinkPrivilege Create symbolic links Disabled SeDelegateSessionUserImpersonatePrivilege Obtain an impersonation token for another user in the same session Disabled USER CLAIMS INFORMATION -- User claims unknown. Kerberos support for Dynamic Access Control on this device has been disabled. root@kali:~/Desktop/tshark#
Excellent! We successfully decoded the first XOR-encoded C2 command. The first command executed was whoami /all.
Now let's extract more commands from other frames in stream 393. Let me get all the payloads from that stream:
tshark -r eCTHP.pcap -Y "tcp.stream == 393 && tcp.len > 200 && ip.src == 18.136.204.173" -T fields -e frame.number -e tcp.payload > stream_393_commands.txt
head -20 stream_393_commands.txt
cat > extract_commands.py << 'EOF'
#!/usr/bin/env python3
import base64
xor_key = b"INE__XOR_KEY_THAT_IS_EXACTLY_68_BYTES_LONG_AND_EASY_TO_SPOT_________"
with open('stream_393_commands.txt', 'r') as f:
commands = []
for line in f:
parts = line.strip().split('\t')
if len(parts) == 2:
frame_num = parts[0]
hex_payload = parts[1]
try:
payload = bytes.fromhex(hex_payload)
content = payload.decode('utf-8', errors='ignore')
if 'CMD:' in content:
cmd_line = [l for l in content.split('\n') if 'CMD:' in l]
if cmd_line:
b64_data = cmd_line[0].split('CMD:')[1].strip()
decoded_b64 = base64.b64decode(b64_data)
result = bytearray()
for i, byte in enumerate(decoded_b64):
result.append(byte ^ xor_key[i % len(xor_key)])
cmd = result.decode('utf-8', errors='ignore')
commands.append((frame_num, cmd))
except:
pass
for frame, cmd in commands[:10]:
print(f"Frame {frame}: {cmd}")
EOF
root@kali:~/Desktop/tshark# python3 extract_commands.py
root@kali:~/Desktop/tshark# ls
ICMP.txt conv.txt decode_c2.py extract_commands.py key.txt protocols.txt statistics-2.txt stream_393_payload.bin
IPS.txt decode_all_c2.py eCTHP.pcap flag.txt length.txt statistics-1.txt stream_393_commands.txt xor_decode.py
root@kali:~/Desktop/tshark#
Answer:
whoami
Q3
What is the IP address of the attacker's C2 server?
Answer:
18.136.204.173
Q4
What is the IP address of the machine that was initially compromised?
Answer:
18.136.204.173
Q5
What PowerShell script did the attacker download prior to running the Get-DomainUser cmdlet?
tshark -r eCTHP.pcap -Y "http and http.request.method==POST and ip.addr==18.136.204.173" -T fields -e frame.number -e data | while IFS=$'\t' read -r frame_num data; do
if [ ! -z "$data" ]; then
echo "$data" | xxd -r -p > "frame_${frame_num}.bin"
echo "Extracted frame $frame_num"
fi
done
#!/usr/bin/env python3
import base64
import glob
import sys
xor_key = b"INE__XOR_KEY_THAT_IS_EXACTLY_68_BYTES_LONG_AND_EASY_TO_SPOT_________"
# Find all frame_*.bin files
frame_files = sorted(glob.glob('frame_*.bin'),
key=lambda x: int(x.split('_')[1].split('.')[0]))
if not frame_files:
print("No frame_*.bin files found in current directory")
sys.exit(1)
print(f"Found {len(frame_files)} files to decode\n")
# Process each file
for filename in frame_files:
print(f"{'='*60}")
print(f"Processing: {filename}")
print('='*60)
try:
with open(filename, 'rb') as f:
content = f.read().decode('utf-8', errors='ignore')
if not content.strip():
print(f"WARNING: {filename} is empty!\n")
continue
except Exception as e:
print(f"Error reading {filename}: {e}\n")
continue
lines = content.strip().split('\n')
for line in lines:
if ':' in line:
parts = line.split(':', 1)
field_name = parts[0]
b64_data = parts[1].strip()
try:
decoded_b64 = base64.b64decode(b64_data)
result = bytearray()
for i, byte in enumerate(decoded_b64):
result.append(byte ^ xor_key[i % len(xor_key)])
print(f"{field_name}: {result.decode('utf-8', errors='ignore')}")
except Exception as e:
print(f"{field_name}: Error - {e}")
print() # Empty line between files
print(f"{'='*60}")
print(f"Finished processing {len(frame_files)} files")
print('='*60)
Timeline of Attack
Compromised Host: 55.68.50.130 (PROD - jolly\webprod)
C2 Server: 18.136.204.173:8000
Domain: jolly.local
Attack Phases
1. Initial Reconnaissance (Commands 1-7)
whoami→ Confirmed user contextnet user /domain→ Enumerated domain usersnet user→ Local usersnet localgroup administrators→ Local admin groupnet localgroup administrators /domain→ Domain admin groupwhoami /all→ Full privilege enumerationipconfig /all→ Network configuration
2. Credential Dumping (Command 8-9)
- LSASS Dump:
rundll32.exe comsvcs.dll MiniDump→ Dumped lsass memory - Mimikatz: Downloaded
WokeWoke.ps1, ranInvoke-Mimikatz- Extracted NTLM hash:
webprod: 31b977436c6ea5bfa9ee65aaddb880d1
- Extracted NTLM hash:
3. Domain Reconnaissance (Commands 10-14)
- Downloaded
abb.ps1(PowerView/SharpView) Get-DomainController→ Found DC01Get-DomainUser -SPN→ Kerberoastable accountsGet-DomainSID→S-1-5-21-3712913190-191217038-2414789797Get-DomainUser→ All domain users
4. Lateral Movement (Command 15-16)
- Downloaded
puller.exe(Rubeus) puller.exe dump→ Extracted Kerberos tickets from PROD- Invoke-Mimikatz on HELPDESK → Obtained Administrator hash
5. Domain Compromise (Commands 17-18)
- Downloaded
update.exe(secretsdump.py) - DCSync Attack: Dumped entire NTDS.DIT from DC01
- Administrator:
e3c61a68f1b89ee6c8ba9507378dc88d - krbtgt:
09674c13e14b6078be0d19bae7420f34 - All domain hashes extracted
- Administrator:
6. Golden Ticket (Commands 19-21)
- Forged Golden Ticket using krbtgt hash
- Created Administrator TGT valid for 7 days
- Tested access:
dir \\dc01.jolly.local\C$→ Success
7. Persistence & Privilege Escalation (Commands 22-25)
- Downloaded
abcde.exe(psexec.py) - Executed as SYSTEM on DC01:
whoami /all→ Confirmed SYSTEM- Created backdoor user:
pawnabcd / abc_123321 - Added to Domain Admins:
net localgroup administrators /add pawnabcd
Key Findings
PowerShell Scripts Downloaded:
WokeWoke.ps1(Mimikatz wrapper)abb.ps1(PowerView - Active Directory enumeration)
Attack Tools:
puller.exe(Rubeus - Kerberos attacks)update.exe(Impacket secretsdump)abcde.exe(Impacket psexec)
Critical Hashes Compromised:
- krbtgt:
09674c13e14b6078be0d19bae7420f34 - Administrator:
e3c61a68f1b89ee6c8ba9507378dc88d
Persistence Established:
- Golden Ticket (indefinite domain access)
- Backdoor account
pawnabcdwith Domain Admin rights
Q6
What port number does the attacker use for C2 traffic?
tshark -r eCTHP.pcap -Y "ip.addr == 18.136.204.173 && ip.addr == 55.68.50.130" -T fields -e frame.number -e ip.src -e ip.dst -e tcp.srcport -e tcp.dstport -e tcp.stream | head -20
to see what ports are used between the Compromised and the C2
tshark -r eCTHP.pcap -Y "ip.addr == 18.136.204.173 && ip.addr == 55.68.50.130 && tcp" -T fields -e tcp.port | sort -u
The C2 traffic is on port 8000 (18.136.204.173:8000) There's also some traffic on port 1414, but the primary C2 channel is 8000.
Answer:
18.136.204.173:8000