DirtyFrag is a Linux forensics lab that covers the exploitation of a kernel vulnerability (CVE-2026-43284) in the IPsec subsystem of an Ubuntu 22.04.2 workstation. The attacker created an exploit user account, triggered the XFRM/ESP subsystem initialization, and performed a privilege escalation visible through anomalous kernel log messages. Persistence was achieved through a hidden SUID backdoor binary in a writable directory and a reverse-shell cron job. Players will investigate kernel logs, /etc/passwd and /etc/shadow entries, file permissions, hashes, and cron configurations to reconstruct the attack chain.
An attacker on an Ubuntu workstation created a local account and used it to run a kernel exploit against the IPsec XFRM/ESP subsystem. The kernel log shows the subsystem initializing and, a few seconds later, a su process launching a shell in an abnormal way, which is the privilege escalation. Persistence followed in two forms: a hidden SUID binary dropped in a world-writable temporary directory, and a per-minute root cron entry that opens a reverse shell. A UID 0 service account with a locked password was also present on the host.
gunzip, then debugfs rdump / x to extract the filesystemvar/log/ in the extracted tree → grepetc/ in the extracted tree → cat, grepsnapshot/uname.txt, collection-time kernel stringvar/installer/media-info, installer metadataTimestamp note: Log times are wall-clock only (no date shown in the answers). The kernel ring buffer also carries an uptime counter in brackets, which is what Q9 needs.
Triage first: the evidence is a gzipped disk image of a plain ext4 filesystem, so debugfs rdump extracts the whole tree without root (ownership errors are harmless). Everything below is read from that extracted tree. The snapshot/uname.txt file captured at collection time holds the running kernel string.
cat x/snapshot/uname.txt
The Ubuntu installer leaves media-info behind with the exact point release, which is more precise than /etc/os-release.
cat x/var/installer/media-info
Reference knowledge from the scenario brief: the kernel IPsec (XFRM/ESP) flaw behind this case is tracked as the CVE below. No artifact states it, so it is the identifier tying the kernel messages in Q7 and Q8 to a named bug.
Read etc/passwd and list accounts with real login purposes. Two have normal UIDs (t3m0 at 1000, mm0x at 1001). The third, svc_monitor, is a UID 0 account with a login shell, so it counts as non-system even though a naive UID >= 1000 filter drops it.
cat x/etc/passwd
Gotcha: The obvious filter, UID >= 1000, omits
svc_monitor. HTB’s answer includes it because it has a login shell, despite UID 0.
The exploit user is the one that ran su to reach root. auth.log shows a su session for mm0x at 09:35:41, minutes after that account was created (Q6) and just before the kernel noise in Q7 and Q8.
grep -h 'su\[\|su:' x/var/log/auth.log
auth.log records the useradd for the exploit account from Q2. The time is the entry’s timestamp.
grep useradd x/var/log/auth.log
Tracing the kernel ring buffer in kern.log for XFRM/ESP initialization. The only line that appears when the subsystem is first loaded by the exploit is the XFRM netlink socket initialization, stamped 09:36:08 with kernel uptime 2296.641117.
grep -i xfrm x/var/log/kern.log
Eight seconds later kern.log logs a su process starting /bin/sh with a NULL argv, at 09:36:16 and uptime 2304.134824. That kernel complaint is the side effect of the exploit hijacking the setuid su binary, so it marks the moment of escalation.
grep -i 'NULL argv' x/var/log/kern.log
Subtract the kernel uptime stamps from Q7 and Q8, not the wall-clock times, since the uptime values carry microseconds: 2304.134824 minus 2296.641117.
python3 -c "print(round(2304.134824-2296.641117,6))"
Tip: Use the bracketed kernel uptime, not the syslog wall clock, for sub-second precision.
In etc/shadow the password field for svc_monitor is a single !, a locked password that no hash can match. The account is UID 0 (Q5), so it is a root-equivalent that can only be reached by other means such as the backdoor or a key.
grep svc_monitor x/etc/shadow
Tip: A
*would also mean no password login;!means the account was explicitly locked.
Hunting for the hidden binary: /var/tmp/.syshelper is a dot-file in a world-writable directory. debugfs stat reports mode 06755, which is setuid and setgid with rwxr-xr-x, and the answer is written without the leading zero.
debugfs -R 'stat /var/tmp/.syshelper' image.ext4
Hash the extracted copy of the same file.
sha256sum x/var/tmp/.syshelper
/etc/crontab carries a per-minute entry run as root that opens an interactive bash with its descriptors redirected to a TCP socket on port 4444: a reverse shell. The same command appears in syslog as a CRON execution, so it was actually firing.
grep -n 'dev/tcp' x/etc/crontab x/var/log/syslog
| Phase | Action |
|---|---|
| Initial Access | Local account mm0x created |
| Privilege Escalation | su run from mm0x |
| Privilege Escalation | XFRM netlink socket initialized by the exploit |
| Privilege Escalation | Kernel logs su launching /bin/sh with NULL argv |
| Persistence | Hidden SUID binary placed in /var/tmp |
| Persistence | Root cron entry with a bash reverse shell to port 4444 |
| Timestamp | Event |
|---|---|
| 09:35:13 | mm0x account created |
| 09:35:41 | su session for mm0x in auth.log |
| 09:36:08 | XFRM netlink socket initialized (uptime 2296.641117) |
| 09:36:16 | Kernel logs su launching /bin/sh with NULL argv (uptime 2304.134824) |
| Type | Value |
|---|---|
| Account | mm0x (UID 1001) |
| Account | svc_monitor (UID 0, locked password) |
| File | /var/tmp/.syshelper (mode 6755) |
| SHA256 | 2c336c63e26881d2f02f34379024e7c314bce572c08cbaa319bacbbec29f93ed |
| Cron | /etc/crontab reverse shell to 10.0.0[.]99:4444 |
| CVE | CVE-2026-43284 |
| Technique | ID | Description |
|---|---|---|
| Create Account: Local Account | T1136.001 | mm0x created on the host |
| Exploitation for Privilege Escalation | T1068 | XFRM/ESP kernel flaw exploited via su |
| Abuse Elevation Control Mechanism: Setuid and Setgid | T1548.001 | Hidden SUID/SGID binary /var/tmp/.syshelper |
| Scheduled Task/Job: Cron | T1053.003 | Per-minute root cron entry |
| Command and Scripting Interpreter: Unix Shell | T1059.004 | bash -i reverse shell over /dev/tcp |
Kernel exploitation leaves a log signature. The NULL argv message from a su launching a shell is a rare kernel warning and the XFRM initialization on a workstation that does not use IPsec is another. Alert on both from kern.log.
UID 0 accounts other than root should never exist. svc_monitor has a root UID and a locked password, so it looks harmless in a shadow review. Audit passwd for any non-root UID 0 entry.
Dot-files with SUID bits in /var/tmp are a persistence tell. Mount world-writable directories nosuid and periodically sweep for setuid files.
A cron entry that touches /dev/tcp is a reverse shell. File integrity monitoring on /etc/crontab and egress filtering on port 4444 would have caught it.
The attacker went from a freshly created local user to root through a kernel bug within seconds, then left a SUID backdoor and a reverse-shell cron job behind. The kernel log was the tell for both the exploit and its timing.