Jack-of-All-Trades — Write-up

Jack-of-All-Trades — Write-up

TryHackMe Challenge Link: https://tryhackme.com/room/jackofalltrades

Jack-of-All-Trades is my very first CTF challenge box. It was created for the Securi-Tay conference run on the 28th of February, 2020 by the UAD Hacksoc.

As you play through this box you will find many references to penguins. This will not make much sense to anyone who didn’t attend the conference, so allow me to explain before we get started in earnest.

The theme of the 2020 Securi-Tay conference revolved around the infamous Dundee penguins. All six CTFs followed a basic narrative: the penguins have escaped from the zoo! Each of the engineers created a challenge that revolved around some aspect of this overarching theme. Jack-of-All-Trades targets a retired penguin-hunter (now jolly old toymaker) who has been brought in by the zoo to capture the mischievous creatures; but all is not quite as it seems, and Jack isn’t the jolly old man he appears to be. We need to hack into his computer to stop him!

Let’s begin.


We’re going to go straight for an nmap scan here to see what potential attack vectors we can find:

nmap -sV -p- -vv <remote-ip>
Results of the nmap scan
nmap results

We can see that there are two ports open. What’s this though? Usually you would see SSH on port 22 and a webserver on port 80. In this case they’ve been switched around — we have a webserver on port 22, and an SSH server on port 80.

I’ll tell you for free: you are not going to be able to bruteforce that SSH just now, so let’s proceed by taking an initial look at the webpage.

You’ll find that your browser most likely throws a hissy fit when you attempt to access the webserver at http://<machine-ip>:22:

Can't access port 22 through a web browser
Address Restricted

I’m going to demonstrate how to bypass this using Firefox, but if you’re using another browser you’ll need to Google how to do it for yourself. It’s usually relatively straight forward.

In Firefox, navigate to about:config. You’ll get a message telling you that you’re voiding your warranty (for free software). Agree, and you’ll be shown a list of configurations:

Firefox configuration file
about:config in Firefox

From here, search for network.security.ports.banned.override. In some versions of Firefox this might show nothing (in which case right-click anywhere on the page, choose new -> String and use the search query as the preference name) — in others it will show the same as for me:

Adding a rule to override the port restriction
Port Override Rule

Whether you’ve had to create a new entry or not, add or change the “Value” field to be 22:

Adding 22 to the list of allowed ports
Enter String Value

You can now go back to the webpage and click reload. It should now load properly:

Homepage of the website

We’re greeted with an introductory homepage, and a nice little monologue from the creator: Jack. Despite his rambling, we don’t actually learn very much from just looking at this page, so let’s take a look at the source code:

Source code for the Jack-of-All-Trades homepage
Homepage -> Source

Well look at that. We have a comment telling us about a page called /recovery.php, as well as an encoded comment. We’ll put the new page aside for the time being. Let’s have a look at this comment.

At a glance we can tell that it’s most likely encoded with base64, so let’s go with that assumption and decode it:

Decoding the comment from the homepage source code
Decoded Comment

Interesting. We have a reference to a man named Johny Graves, as well as a password, but for what?

Let’s search for Johny Graves and see if he’s got any hints for us:

Johny Graves Search on DuckDuckGo
Johny Graves Search on DuckDuckGo

This looks interesting!

Unfortunately the link is dead. Dead end. Wonderful.

There has got to be more information on the guy lying around. Linkedin doesn’t have anything for us, but how about Facebook or Twitter?

Johny Graves' Twitter
Johny Graves’ Twitter

Bingo! The guy has a Twitter account!

(Author’s Note: He also has Facebook, Quora, Medium, Myspace, Soundcloud and probably a bunch more that I can’t actually remember making at 3AM)

Notice his tweet about his favourite crypto method:

Graves' Favourite Encoding Method
Graves’ Favourite Encoding Method

I have a hunch that this might come in handy later!

For now though, it’s time to head back to the Jack-of-all-trades website and have a look at that recovery page:

Recovery Page

Looks like it might be a login screen to help Jack reset his password! You’re welcome to try bruteforcing it, but again, you’re really not going to get very far.

Instead let’s take a look at the source code for the recovery page:

Source code for the recovery page of the Jack-of-All-Trades website
/recovery.php -> Source

Another nice long comment. By the looks of it, it’s encoded into a different base, so we could try just decoding it ourselves. Alternatively, we could try using the encoding system found on Johny Graves’ Twitter account?

Graves said that he liked to first encode his message with ROT13. Then he took the result and converted it to Hex. Finally he took the hex and encoded it with base32.

Theoretically, all we need to do is reverse the process to get the original message!

Using CyberChef:

Decoding from Base32
Decoding from Base32

That’s definitely a hex output!

Decoding From Hex
Decoding From Hex

Looking good! That could well be ROT13:

Decoded ROT13
Decoded the ROT13

And there we have it — the full recipe!

Looks like the creds for the recovery page are actually somewhere back on the homepage. Good thing Jack is so forgetful! Let’s look at the hint he’s left for himself:

Wikipedia Page on Stego(sauria)
Wikipedia Page on Stego(sauria)

Well that ain’t exactly subtle… I don’t know if I’ve ever seen a stronger indicator of “steganography.”

And whaddya know, there’s a stegosaurus just sitting there on the homepage!

Your friendly neighbourhood Stegosaurus
Your friendly neighbourhood Stegosaurus — looks angry

Download it and let’s try to extract it with steghide using the password we found earlier:

steghide extract -sf stego.jpg
Downloaded and extracted the "creds" from stego.jpg
File in stego.jpg

Um, creds?
Apparently not…

Maybe the jack-in-the-box image? That’s to do with his name, right?

I’ll spare you the effort.

It’s actually in the header — the jack in the box is another ruse: it has nothing in it.

Download the header and extract the real creds:

Extracted the real creds from the header image
Extracted Creds from header (For real this time)


Success! We have some credentials to log into the recovery screen.

Use them now:

Recovery screen in the Jack-of-All-Trades website
Recovery Screen

It’s asking us to send it a command. Huh, let’s give this a shot.

Try adding ?cmd=id to the end of the URL:

Successfully injected the id command via the cmd parameter of the URL

Success! We have RCE on the server. By sending commands at the end of the request, the website will return the results. At this point you can see that the output is all on one line. I would suggest switching into the View Source mode to get it better formatted.

Have a look around the machine, you’ll notice that there’s something unusual in the /home directory:

Passlist in the home directory
/home directory

We’ve got a user called jack, and there’s a file (duplicated) called jacks_password_list. Let’s open it up and take a look!

Used our RCE to get a password list in the /home directory
Password List

That, to me, looks suspiciously like a wordlist we could use to bruteforce a password. Say… Jack’s SSH password?

Copy that list across into a file on your local computer. We’re going to break the SSH password with Hydra:

hydra -l jack -P <path-to-copied-passwords> -s 80 ssh://<remote-ip>
Broke Jack's SSH password with Hydra

And there we have it. Jack’s SSH password.
(See why I said you wouldn’t be able to bruteforce it, way back at the start?..)

Let’s login as jack over SSH:

ssh -p 80 jack@<remote-ip>
Logged in as Jack over SSH
Successful Login

Terrific. The user flag is a JPEG. Download it from your local machine, then open it up and see what we’ve got:

scp -P 80 jack@<remote-ip>:user.jpg /tmp
Downloaded and opened user.jpg
User Flag

Now what would a man contracted to rescue the penguins be doing with a recipe for penguin soup? Something seems off here…

Let’s keep digging.

Root Flag:

Back on the remote machine, the first thing (as ever in Linux privilege escalation) is to check to see if we can execute anything with sudo:

sudo -l
No sudo access
Nope — no sudo access

Damn. No sudo permissions.
Ah well — worth a try.

Our next best bet is finding an executable file with the SUID bit set:

find / -type f -user root -perm -4000 -exec ls -ldb {} \; 2>>/dev/null
List of root owned binaries with SUID set
Results of the find search

One of these stands out as being really unusual: /usr/bin/strings.

strings is usually used to scan a file for human-readable strings of text. It’s very useful if you’re analysing files (e.g. for pulling strings out of compiled binaries, or for looking for signs of steganography having been used). In this case we’re looking for a text file (root.txt). Text files are, unsurprisingly, entirely comprised of strings.

So, for the easiest root flag in the history of CTFs, let’s use /usr/bin/strings to read the flag:

/usr/bin/strings /root/root.txt
Used strings to grab the root flag
Root Flag

That monster! Not only is he trying to kill the penguins for a rug, he’s got a dead body in his garage! Well, at least we’ve got enough to go to the police now. The penguins are saved!

Leave a Reply

Your email address will not be published. Required fields are marked *

Enter Captcha Here : *

Reload Image

Scroll Up