As a grumpy architect, in collaboration with a grumpy analyst, it was decided that we should sharpen and hone our hacking skills by doing some CTF — capture the flag — challenges.

Vulnhub.com is an excellent resource for these — indeed there are many more too, but we decided that this was as good a place to start as any.

Mr. Robot 1 is thematically based on the TV series of the same name, which was awesome, so that decided it for us.

SPOILER ALERT

Below here I will detail a walkthrough of the solution. If you’re actively working on it you should probably avoid unless you’re really stumped.

Also note: there are probably many ways of achieving this — and probably all of them are better than what I did here. Since it’s about personal development, and ultimately achieves the same end, I don’t think we need to start comparing how l33t we are at this stage.

To that end, herein is probably a really dumb way of solving Mr. Robot 1.

Set up

So firstly, I’m running VirtualBox from Oracle as my hypervisor. In it, I have an up-to-date installation of Kali linux.

It sits on a NAT-network I’ve created which I use as a lab network.

After downloading and importing the VM from VulnHub and configuring it to use the same NAT network, I booted it up.

This is the initial page you see once it’s fired up, and that’s all the information you’ve got.

From here I tried a few obvious things like “admin:admin” and suchlike, but needless to say that brought me no progress.

So the front door is locked, then.

Let’s see what else there is we can do.

Within VirtualBox I took a look at the config on my NAT network to get the /24 range my VMs pick up their IP addresses from:

So, that’ll be 10.0.2.0/24 then

Now, within my Kali VM I fired up nmap and gave it the following flags:

nmap 10.0.2.0/24 -A -Pn

That is:

10.0.2.0/24 — scan the range we found

-A — get operating system and version information

-Pn — Treat all hosts as online (even if they ignore us)

From this I found that my VM had picked up IP 10.0.2.4 (future references to the VM will use that IP in this write-up) and that it was running web services on :80 and :443

The natural next step is to browse to them and see what’s going on.

firefox 10.0.2.4

should do the trick.

Here, we’re treated to some Mr. Robot themed text and video intro. Have fun with the options and the content for a while if you like, but I didn’t find anything useful going on in there. Maybe I missed it — let me know.

My next step was to check for a robots.txt file in

10.0.2.4/robots.txt

This gave me:

First Key

So, that’s the first key:

wget 10.0.2.4/key-1-of-3.txt

and what looks like a dictionary file:

wget 10.0.2.4/fsocity.dic

Key 1 contains this: 073403c8a58a1f80d943455fb30724b9

It looks like an MD5 hash, but doesn’t ‘un-hash’ to anything known.

The .dic file contains about 800,000 words in a dictionary file format. Some of the words are pretty odd and pretty specific, but a quick scan doesn’t reveal any more clues at this stage.

My next move was to see if there were any vulnerabilities on the webserver with a basic Nikto scan:

nikto -h 10.0.2.4

(-h specifying the host to scan)

This produced this:

nikto -h 10.0.2.4 results

Now then, from here I jumped straight into the Wordpress content which had been detected and proceeded from there. This ultimately proved fruitful — see: rest of write-up, but there’s actually a lesson in how I proceeded from here which I’ve only just learned whilst I was doing the write up:

Use all of the information that you have

I will elaborate more on what the ‘practical’ meaning to this is a little later on. Suffice to say, I could have been saved a fair amount of effort if I’d paid closer attention to what nikto was telling me.

So, Wordpress.

There’s plenty of noise about Wordpress, so let’s start having a look and see if we can find:

wpscan --url 10.0.2.4 --enumerate vp

( — url specifiying the target, and — enumerate vp looking for vulnerabable plugins)

This produced about a dozen plugins, including an Unauthenticated Database Export, and Authentication Bypass courtesy of the All-in-One SEO Plugin.

Attempts to exploit these were ultimately fruitless for me though.

I next spent time looking around the URLs that Nikto had found

10.0.2.4/wp-admin

Again I fell back to trying obvious things — any things — just to try to pick up the scent again.

The trusty old admin:admin username and password combo was predictably fruitless…or was it?

Take a look at the error message that Wordpress throws for user ‘admin’:

Errors: helpful

That looks like it’s giving me marginally too much information.

Thus spawned a fairly boring period of trying random user names that I thought might be admin-y or related enough, until:

Errors: downright friendly

Referring back to the content this challenge is named after, I gave “elliot” a go as the username and Wordpress very helpfully distinguished my earlier bad usernames from my now good username, but bad password.

And remember, passwords we got: fsocity.dic

Armed with my username and dictionary file I set about some brute forcing:

hydra -l elliot -P ~/fsocity.dic 10.0.2.4 http-post-form “/wp-login.php:log=elliot&pwd=^PASS^:ERROR”

Where,

-l specifies the username

-P specifies the dictionary file

http-post-form is the authentication method being used

and,

“/wp-login.php:log=elliot&pwd=^PASS^:ERROR”

roughly parses to,

/wp-login.php the login page to attack

log=elliot is the username on the form

pwd=^PASS^ substitutes the passwords from the dictionary file

ERROR tells it what to look for if it fails

I say “roughly parses to” because it didn’t work and I don’t know why. If anyone know, I’d love to fix it.

So I tried again using a different tool:

wpscan -u 10.0.2.4 --wordlist ~/fsocity.dic --username elliot

And after a lengthy period of time, the password for elliot is:

ER28–0652

Annoyingly a ‘tail’ of the file shows that it was pretty much at the bottom of the list. Well played, Jason. Touché.

So now we’re in to Wordpress, we can see that we’re privileged because we can mess around with Plugins and such.

Some more Googling around getting a shell on a webserver running php leads me to here:

Where the kind folk have done the hard work for me in creating a reverse shell.

At this point I’ll briefly digress to come back to my brief philosophical break from earlier.

Remember good old Nikto? Remember he told us this:

+ OSVDB-5089: /admin/system.php3?cmd=cat%20/etc/passwd: DotBr 0.1 allows remote command execution. + OSVDB-5090: /admin/exec.php3?cmd=cat%20/etc/passwd: DotBr 0.1 allows remote command execution.

Yeah.

Turns out I already had a capability of executing shell commands on the web server, I just hadn’t been paying attention.

Good old Nikto.

Anyway, given that I took the time to use the php-reverse-shell I’d found, I’ll continue with that version of this.

I modified the IP and Port information as directed, saved it and zipped it up.

Within the Wordpress Plugins page I uploaded the .zip.

Before activating the Plugin, I went to my local shell in Kali and set up a listener:

nc -lvp 3344

(listen, be verbose, and use port 3344 — which I had preconfigured in the shell I uploaded)

Upon activating the reverse shell plugin the local shell was bound to the server and I was in as user elliot on the server.

A look around the file structure showed a user in /home called robot.

Promising.

Within that folder I could see

key-2-of-2.txt password.raw-md5

Yes!

Oh wait, no — I don’t have permission to cat the .txt file.

But I do have permission to cat the .raw-md5 file.

That gives us:

robot:c3fcd3d76192e4007dfb496cca67e13b

which looks like a username and hash pair.

Googling for “md5 cracker” gives a load of sites which will take the md5 hash and through pre-computed tables tell us what it was originally.

Originally it was:

abcdefghijklmnopqrstuvwxyz

Nice.

So now, into the VM itself from the original login prompt and using these credentials.

First thing is to get a better shell:

python -c “import pty; pty.spawn(‘/bin/bash’);”

And here we are:

Now I can cat the 2nd key file which gives:

822c73956184f694993bede3eb39f959

So, that was where the easy stuff ended.

At this point I had no threads left to pull at other than the one thing I really didn’t want to have to read about (because it was going to be hard).

Privilege Escalation.

This excellent link from g0tmi1k enumerated not so much the solution, more the scale of the problem I now had.

Reading glasses: on.

What I ended up using was the unix-priv-esc tool, again from pentestmonkey which was a really neat way of automating a lot of what I was reading about.

wget-ing that on to the server and running it in ‘detailed’ mode gave me a huge list of tests that it had performed.

chmod u+x unix-priv-esc

./unix-priv-esc detailed > output.txt

A quick scan through this list was not fruitful — mainly because there was so much information in it. The only next step was to go through the file with a very fine tooth comb.

Using the recommended approach from the instructions and grep-ing through the WARNING lines:

grep WARNING output.txt | less

I eventually found a reference to nmap being installed in:

/usr/local/bin/nmap

with its SUID set to root.

I didn’t know exactly what that meant, but I did figure that nmap isn’t on a vanilla Linux installation so it was worth looking into.

Googling for:

nmap root suid site:exploit-db.com

revealed this article: https://www.exploit-db.com/papers/18168/

And within lies an excellent nmap exploit/vulnerability or maybe backdoor that I didn’t know about.

Basically if you invoke nmap in interactive mode:

nmap --interactive

you can execute shell commands from within nmap with the privileges of the SUID user.

So…

!sh

and then:

id

gives me the glorious news:

I are root

that I am now root.

So, finally:

# cd /root

# ls

firstboot_done key-3-of-3.txt

cat key-3-of-3.txt

04787ddef27c3dee1ee161b21670b4e4

/fin