Advertisement
Guest User

Untitled

a guest
Jun 26th, 2017
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.19 KB | None | 0 0
  1. import argparse
  2. import logging
  3. import queue
  4. import re
  5. import threading
  6.  
  7. from urllib.request import HTTPRedirectHandler, Request, build_opener
  8.  
  9.  
  10. MAX_THREADS = 100
  11. # TODO: добавить больше правил
  12. SQL_ERROR_RE = re.compile((
  13.   # mysql/mysqli
  14.   r'mysqli?_fetch\w+\(\)|'
  15.   # pdo
  16.   r'You have an error in your SQL syntax|'
  17.   # PostgreSQL
  18.   r'Query failed|'
  19.   # Bitrix
  20.   r'DB query error'))
  21.  
  22.  
  23. logger = logging.getLogger('SQLiScanner')
  24.  
  25.  
  26. class RedirectHandler(HTTPRedirectHandler):
  27.  
  28.   def redirect_request(self, req, fp, code, msg, headers, newurl):
  29.     pass
  30.  
  31.  
  32. class Scanner(threading.Thread):
  33.  
  34.   def __init__(self, urls, results, lock, stop):
  35.     super().__init__()
  36.     self.urls = urls
  37.     self.results = results
  38.     self.lock = lock
  39.     self.stop = stop
  40.     self.daemon = True
  41.     self.start()
  42.  
  43.   def run(self):
  44.     while not self.stop.is_set():
  45.       try:
  46.         url = self.urls.get_nowait()
  47.       except queue.Empty:
  48.         continue
  49.       try:
  50.         # '" . mysqli_real_escape_string($link, trim($_GET['id'])) . "'
  51.         url = url.replace('*', "'--%20[")
  52.         req = Request(url, headers={'User-Agent': self.user_agent()})
  53.         opener = build_opener(RedirectHandler())
  54.         with opener.open(req, timeout=5) as resp:
  55.           content = resp.read()
  56.           enc = resp.info().get_content_charset('utf-8')
  57.           content = content.decode(enc, 'replace')
  58.           match = SQL_ERROR_RE.search(content)
  59.           if match:
  60.             with self.lock:
  61.               logger.info('Found "%s" at url "%s".', match.group(0), url)
  62.               self.results.append(url)
  63.       except Exception as e:
  64.         with self.lock:
  65.           logger.error(e)
  66.       finally:
  67.         self.urls.task_done()
  68.  
  69.   def user_agent(self):
  70.     # TODO: сделать рандомный юзер-агент
  71.     return 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246'
  72.  
  73.  
  74. def enqueue(o):
  75.   q = queue.Queue()
  76.   for x in o:
  77.     q.put(x)
  78.   return q
  79.  
  80.  
  81. def scan(urls, max_threads=MAX_THREADS):
  82.   urls = enqueue(urls)
  83.   num_threads = min(max_threads, urls.qsize())
  84.   results = []
  85.   lock = threading.Lock()
  86.   stop = threading.Event()
  87.   logger.info('Start scanning.')
  88.   threads = [Scanner(urls, results, lock, stop) for _ in range(num_threads)]
  89.   urls.join()
  90.   stop.set()
  91.   for t in threads:
  92.     t.join()
  93.   logger.info('Scanning finished.')
  94.   return results
  95.  
  96.  
  97. if __name__ == '__main__':
  98.   logging.basicConfig(level=logging.DEBUG)
  99.   parser = argparse.ArgumentParser(description='SQLiScanner by tz4678@gmail.com.')
  100.   parser.add_argument('-f', '--file', default='urls.txt', help='file with urls', type=str)
  101.   parser.add_argument('-o', '--out', default='results.txt', help='file with results', type=str)
  102.   parser.add_argument('-m', '--max_threads', default=MAX_THREADS, help='max number of threads', type=int)
  103.   args = parser.parse_args()
  104.   with open(args.file, 'r', encoding='utf-8') as fp:
  105.     urls = [line.strip() for line in fp]
  106.   results = scan(urls, args.max_threads)
  107.   with open(args.out, 'w', encoding='utf-8') as fp:
  108.     fp.writelines(results)
  109.   input('Press any key to exit.')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement