v0mit

PyXSSer.v0.2

Aug 9th, 2011
763
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.59 KB | None | 0 0
  1. '''
  2. Created on Aug 5, 2011
  3.  
  4. @author: v0mit
  5. '''
  6. import urllib, urllib2, random, sys, urlparse
  7. from BeautifulSoup import BeautifulSoup
  8. from BeautifulSoup import BeautifulStoneSoup
  9.  
  10. if len(sys.argv) == 3:
  11.     url = sys.argv[1]
  12.     log_file = sys.argv[2]
  13.    
  14. elif len(sys.argv) == 2:
  15.     url = sys.argv[1]
  16.     log_file = "vulnerable.txt"
  17.  
  18. else:
  19.     print("Usage: pyxsser.py <target> <output>")
  20.     sys.exit(0)
  21.    
  22. base_url = urlparse.urlsplit(url).netloc
  23.    
  24. header = """
  25. ______      __   _______ _____          
  26. | ___ \    \ \ / /  ___/  ___|          
  27. | |_/ /_   _ \ V /\ `--.\ `--.  ___ _ __
  28. |  __/| | | |/   \ `--. \`--. \/ _ \ '__|
  29. | |   | |_| / /^\ |\__/ /\__/ /  __/ |  
  30. \_|    \__, \/   \|____/\____/ \___|_|  
  31.        __/ |                            
  32.       |___/        v0.2
  33. """
  34. print(header)    
  35.  
  36. injection_str = ""
  37. for x in range(0,8):
  38.     injection_str += random.choice("abcdefghi1234567890")
  39.  
  40. injection_str = ";!--\"'<%s>=&{()}" % injection_str
  41.  
  42. encoded_injection_str = urllib.urlencode({"":injection_str})
  43. #encoded_injection_str = "=lol"
  44.    
  45. class _http_handler():
  46.     def __init__(self):
  47.         self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
  48.         urllib2.install_opener(self.opener)
  49.  
  50.     def request(self, url, data=None):
  51.  
  52.         req = urllib2.Request(url)
  53.         req.add_header('User-Agent',"PyXSSer.v0.2")
  54.        
  55.         if data != None:
  56.             data = urllib.urlencode(data)
  57.             try:
  58.                 response = self.opener.open(req,data)
  59.             except urllib2.URLError as errno:
  60.                 print(errno)
  61.                 print("[!]urllib2.URLError({0})\n".format(errno))
  62.                
  63.                 return
  64.                
  65.             return response.read()
  66.         else:
  67.             try:
  68.                 response = self.opener.open(req)
  69.             except urllib2.URLError as errno:
  70.                 print("[!]urllib2.URLError({0})\n".format(errno))
  71.                
  72.                 return
  73.                
  74.             except ValueError as errno:
  75.                 print("[!]ValueError({0}\n".format(errno))
  76.                
  77.                 return
  78.            
  79.             return response.read()
  80.            
  81. def get_forms(forms):
  82.     valid_forms = []
  83.     for form in forms:
  84.         action = form.get("action")
  85.         if action != None:
  86.             inputs = form.findAll("input", attrs={"type":"text"})
  87.             names = []
  88.             for input in inputs:
  89.                 name = input.get("name")
  90.                 if input != None:
  91.                     names.append(str(name))
  92.                    
  93.             valid_forms.append([str(action), names])
  94.                    
  95.     return valid_forms
  96.  
  97. def parse_target(data):
  98.     soup = BeautifulSoup(data)
  99.     forms = soup.findAll("form", attrs={"method":"get"})
  100.     forms += soup.findAll("form", attrs={"method":"post"})
  101.     links = soup.findAll("a")
  102.    
  103.     valid_forms = get_forms(forms)
  104.     urls = generate_form_links(valid_forms)
  105.    
  106.     valid_links = get_links(links)
  107.     urls += generate_links(valid_links)
  108.    
  109.     return urls
  110.    
  111. def generate_links(valid_links):
  112.     urls = []
  113.     for link in valid_links:        
  114.         buff_list = []
  115.         for x in valid_links[link]:
  116.             buff_list.append(x)
  117.            
  118.         for x in range(0, len(buff_list)):
  119.             new_url = link
  120.            
  121.             if not new_url.endswith("?"):
  122.                 new_url += "?"
  123.                
  124.             buff = ""
  125.             for query in buff_list[:x]:
  126.                 buff += "&{0}=gl1".format(query)
  127.                
  128.             buff += "&{0}{1}".format(buff_list[x], encoded_injection_str)
  129.  
  130.             for query in buff_list[x:]:
  131.                 buff += "&{0}=gl2".format(query)
  132.              
  133.             new_url += buff[1:]  
  134.             urls.append(new_url)
  135.    
  136.     return urls
  137.    
  138. def generate_form_links(forms):
  139.     urls = []
  140.     for form in forms:
  141.         for para in range(0, len(form[1])):
  142.             if form[0] == "#":
  143.                 new_url = url
  144.             else:
  145.                 new_url = form[0]
  146.             if not new_url.endswith("?"):
  147.                 new_url += "?"
  148.                
  149.             buff = ""
  150.             for x in form[1][:para]:
  151.                 buff += "&{0}=1".format(x)
  152.                
  153.             buff += "&{0}{1}".format(form[1][para], encoded_injection_str)
  154.            
  155.             for x in form[1][para+1:]:
  156.                 buff += "&{0}=1".format(x)
  157.             new_url += buff[1:]  
  158.             urls.append(urlparse.urljoin(url,new_url))
  159.            
  160.     return urls
  161.    
  162. def get_links(links):
  163.     urls = {}
  164.     for link in links:
  165.         link = link.get("href")
  166.         if link == None:continue
  167.         a = urlparse.urlparse(link)
  168.        
  169.         query = a.query
  170.         if query == "":
  171.             continue
  172.         parsed_query = queries(query)
  173.        
  174.         if a.netloc == "":
  175.             buf = urlparse.urljoin(url, a.path)
  176.         else:
  177.             if a.netloc != base_url:
  178.                 continue
  179.             buf = "{0}://{1}{2}".format(a.scheme, a.netloc, a.path)
  180.            
  181.         if buf in urls:
  182.             for q in parsed_query:
  183.                 urls[buf].add(str(q))
  184.         else:
  185.             urls[buf] = set()
  186.             for q in parsed_query:
  187.                 urls[buf].add(str(q))
  188.    
  189.     return urls
  190.                
  191. def queries(queries):
  192.     queries_parsed = set()
  193.     queries = queries.split("&")
  194.     for q in queries:
  195.         queries_parsed.add(q.split("=")[0])
  196.        
  197.     return queries_parsed
  198.  
  199. h = _http_handler()
  200. data = h.request(url)
  201. if data is None:
  202.     print("[!]Could not connect to target.")
  203.     sys.exit(0)
  204.    
  205. urls = parse_target(data)
  206.  
  207. vulnerable = []
  208. for url in urls:
  209.     print("[+]Testing:{0}".format(url))
  210.     h = _http_handler()
  211.     data = h.request(url)
  212.    
  213.     if data == None:
  214.         continue
  215.    
  216.     if injection_str in data:
  217.         print("\n[!]Possible XSS found!")
  218.         print("[+]URL:{0}".format(url))
  219.         vulnerable.append(url)
  220.         n = data.find(injection_str)
  221.         print("[+]Injection string found @ {0}".format(n))
  222.         print("[+]{0}\n".format(data[n:n+len(injection_str)]))
  223.  
  224. print("\n[+]Scann completed.")
  225.  
  226. if not len(vulnerable):
  227.     print("[+]Nothing found.")
  228.     sys.exit(0)
  229.  
  230. try:
  231.     out = open(log_file, "wb")
  232. except IOError as errno:
  233.     print("\n[!]IOError: [0}".format(errno))
  234.     sys.exit(0)
  235.    
  236. for url in vulnerable:
  237.     out.write("{0}\n".format(url))
  238.    
  239. out.close()
  240.  
  241. print("[+]Report saved to: {0}".format(log_file))
Advertisement
Add Comment
Please, Sign In to add comment