Advertisement
v0mit

PyXSSer.v0.2

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