Scanning and Enumeration
The target IP address is 10.10.10.171, so let’s run a port scanning to identify the services:
As you can see, two services are running: a SSH server and an HTTP one. Both of them appear to be updated, so probably the attack surface involves a web investigation through the web platform; let’s see.
A GET request for the main path of the HTTP server gives us back the default Apache page, so probably a directory guessing enumeration is required to discover other interesting locations. In order to do this, I use dirb and that’s the result:
So we actually discovered two web available locations: /artwork and /music.
Their screenshots are here below and show two simple static pages with no info inside, that only contain broken links. One of the music pages has got a reference to another location: /ona/.
Artwork home page | Music home page |
---|---|
Ona stands for OpenNetAdmin and is the location of an homonymous web application that provides a database managed inventory of your IP network, collecting information about user’s network infrastructure and topology.
Main HTTP Service
Luckly, the login is not required and the guest account is the default one when entering in the application. Inside the main page there is an information box that notifies the user that the platform is not updated, so it’s probably affected by a well-known vulnerability. And after a fast research on exploit-db I found a working PoC to obtain a RCE on that platform version, which involves a command injection using a GET parameter.
1 | # Exploit Title: OpenNetAdmin 18.1.1 - Remote Code Execution |
At this point, I go for a shell upgrade using weevely to improve my capabilities in lateral moving:
Directly looking for the user.txt file containing the first flag, two users’ home directories are found: /home/joanna and /home/jimmy. The flag is probably inside one of these, but our web shell is executed with www-data privileges so that we cannot read inside of them. We need a privilege escalation, so let’s have a look around.
Running netstat to see which processes are listening on the host, a MySQL server instance pops up: it is only accessible from localhost probably because service configuration or firewall rules and makes us thinking that the web app stores data inside of it.
Furthermore, an additional TCP service appears to be listening on port 52846: it isn’t accessible from the outside and requires more investigation.
1 | Active Internet connections (only servers) |
Looking for database related files inside the web folder (/opt/ona/www/ is the directory that hosts it), we find an interesting configuration file: config/config.inc.php
. Let’s have a look at its content:
1 | require_once($conf['inc_functions_db']); |
The code above shows at line 4 a reference to the database configuration file /local/config/database_settings.inc.php
which contains the parameters used by the application to connect to the DBMS:
1 |
|
So we’ve actually got potentially valid credentials to access the local DBMS and extract more information. After a fast manual test, we can look for users’ credentials using the proper weevely module:
1 | ona_sys@localhost SQL> select * from ona_default.users |
The hashes are easly reversable and the resulting credentials are:
guest:guest
admin:admin
None of them let me log in the SSH using the accounts retrived before, so they are useless: a rabbit hole.
SSH - Jimmy
After a while, I succeded in logging in the “jimmy” account via SSH simply using the same password used for MySQL.
1 | ┌─[user@parrot]─[~/OpenAdmin] |
The jimmy’s home doesn’t contain the user flag file, but then I reminded I’d seen before a directory inside the /var/www/
path that was only accessible to it. It could be interesting to check out its content.
A fast ls -al
reveals an internal/
directory containing three PHP files belonging to a different web platform:
- index.php
- main.php
- logout.php
Trying to send an HTTP request to the TCP service running on the port 52846, we get a simple HTML page proving the existence of another web service.
Moreover, the content corresponds with the index one’s, so we’ve found the service content directory.
Internal HTTP Service
The index page actually contains a login form that checks the given credentials using a comparison between user data and statical strings inside the PHP code:
1 | <h2>Enter Username and Password</h2> |
Reversing the SHA512 is actually useless considering that we’ve got writing permissions on that directory and we could directly change the files’ content in order to avoid checks, but it could help us later: jimmy:Revealed
.
The main page is the most interesting one:
1 | session_start(); if (!isset ($_SESSION['username'])) { header("Location: /index.php"); }; |
The shell_exec
command makes us thinking that the process is run by the user joanna because it is supposed to have permissions to read the file /home/joanna/.ssh/id_rsa
.
This means that every PHP file we write inside that path will be run by joanna and that it probably uses a public/private key authentication on SSH: let’s write an exploit to copy our public key inside its authorized_hosts
file and log in with this account.
SSH - Joanna
This is the exploit I wrote:
1 |
|
So I made a GET request to my script through curl via 52846 port and… done!
Let’s log in joanna account using our private key and get the user flag:
1 | ┌─[user@parrot]─[/media/user/data/OpenAdmin/exec] |
Privilege Escalation
Executing LinEnum
didn’t help to find a way to have a root shell, but the solution was very easy:
1 | joanna@openadmin:~$ sudo -l |
So, joanna is allowed to execute the command "/bin/nano /opt/priv"
as root via sudo and we can simply read the /root/root.txt
file using nano: