Lately, I’ve been playing TryHackMe’s King of the Hill (KoTH), where players compete to attack and defend a machine while finding as many flags as they can. Many of the boxes have hardcoded credentials, but a few, such as Hackers, generate new credentials every game, requiring players to brute-force them.
All the passwords are in rockyou.txt
, but it only seems to pick entries fairly close to the top of the list. If I knew which exact ones, I could make an optimized wordlist for it…
There are three different accounts that a player can brute-force the password for: plague
, rcampbell
, and gcrawford
. plague corresponds to a backdoor in the webserver (yes, the webserver binary itself) and does not have an actual account on the system, while the others are actual users in /etc/passwd
.
I started with plague
first. All I have to do is fetch the webserver and run strings
on it, right? Not quite. I ran strings
on it, and it does contain passwords as expected, but there’s no sort of seperator between them; it’s just a big lump of passwords!
...
_MSpanDead_MSpanFreeatomicand8audio/aiffaudio
/wavebabygirl10babygirl21babygirl23bustamantebutterfly3
/%dcaramelitocasgstatuscesarteamochristmas1complex128
/woff2franchescafunnybunnygetsockoptghostrider
heartbreakheavymetalhttp_proxyidontknow1iloveyou08
/webpinvalidptrjosecarloskagandahankeep-alive
...
There may be an easier way: perhaps it only contains the first x lines of rockyou.txt
? I tried to check for this, but I couldn’t find a clear cut-off point. Line 200 of rockyou.txt
(september) does not appear, yet line 9583 (reddragon) does. So we can’t just use head -n x rockyou.txt
to make our wordlist either.
I’m not brave enough for real static analysis, so let’s try a different approach. When starting, it prints the date and time, the username (always plague
), the password (presumably selected at random), and an MD5 hash. If I run the binary enough times, I could hopefully extract all the passwords.
$ ./server
2022/02/17 01:50:59 {plague swimmer1 4ae8af349c8334b2758746bde79db9e5}
2022/02/17 01:50:59 Listening for requests
This is where the fun begins. I ran the binary 280,208 times, and put each password into a list. This should get all the passwords, but since they’re chosen at random, what if we’re really unlucky and miss a few? I checked the distribution of the passwords, and each one was chosen at minimum 222 times, and at most 340 times. This gave me enough confidence in the list to sort out the duplicates and give it a try, and it worked great! This list finds the password in around 2-15 seconds, while rockyou.txt
can take 5-10 minutes. This is a silly way to do dynamic analysis, but it did work.
$ hydra ...
[80][http-post-form] host: 10.10.179.79 login: plague password: anthony12
1 of 1 target successfully completed, 1 valid password found
But this wordlist doesn’t work at all for rcampbell
and gcrawford
. What gives? Time to look for clues. On the box itself, there is a cronjob that runs /passwords.sh
on reboot, and the logs indicate that their passwords change soon after. This must be it, but /passwords.sh
doesn’t exist. It must be deleting itself to cover its tracks.
Feb 17 06:42:10 gibson CRON[788]: (root) CMD (/passwords.sh)
Feb 17 06:42:30 gibson passwd[838]: pam_unix(passwd:chauthtok): password changed for gcrawford
Feb 17 06:42:31 gibson passwd[843]: pam_unix(passwd:chauthtok): password changed for rcampbell
Starting with a fresh Hackers box (thankfully I can run the box solo, outside of KoTH), I rooted the machine, quickly installed photorec, and started to recover deleted files. Normally, restoring deleted files to the same filesystem is a terrible idea, but we can always start over if we don’t find anything. I managed to recover the elusive passwords.sh
, which showed that there were actually two wordlists being used, one per user. And as I suspected, it is in fact deleting itself. This gave me some important insight, but it didn’t contain the actual wordlists.
!/bin/bash
rm /home/gcrawford/.ssh/id_rsa.pub
rm /home/gcrawford/.ssh/id_rsa
rm /home/gcrawford/.ssh/authorized_keys
sudo -u gcrawford ssh-keygen -f /home/gcrawford/.ssh/id_rsa -N $(shuf -n 1 /passwordsGCrawford.txt)
cat /home/gcrawford/.ssh/id_rsa.pub > /home/gcrawford/.ssh/authorized_keys
echo $(shuf -n 1 /passwordsGCrawford.txt) > /tmp/passwd; (cat /tmp/passwd; cat /tmp/passwd) | passwd gcrawford
echo $(shuf -n 1 /passwordsRCampbell.txt) > /tmp/passwd; (cat /tmp/passwd; cat /tmp/passwd) | passwd rcampbell
rm /tmp/passwd
rm /passwords*
After some more tries, I was eventually able to recover what appear to be the two wordlists. I grabbed the /etc/shadow
file from the machine a few times as well, so I had something to test against. I used the new wordlists to crack the hashes, and they worked! Interesting, there’s no overlap between the lists; they’re all derivatives of rockyou.txt
, but different passwords in each.
This is the part where I would post the wordlists, but I have been politely asked to not disclose them. They have been sealed away, and I pinky-promise not to use them.
This is the end, my friend. Thank you for
callingreading.― Eugene ‘The Plague’ Belford