| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500 | 
							- #!/usr/bin/python3
 
- # -*- coding: iso-8859-15 -*-
 
- """
 
- This file is part of the cintruder project, https://cintruder.03c8.net
 
- Copyright (c) 2012/2020 psy <epsylon@riseup.net>
 
- cintruder is free software; you can redistribute it and/or modify it under
 
- the terms of the GNU General Public License as published by the Free
 
- Software Foundation version 3 of the License.
 
- cintruder is distributed in the hope that it will be useful, but WITHOUT ANY
 
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
- FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 
- details.
 
- You should have received a copy of the GNU General Public License along
 
- with cintruder; if not, write to the Free Software Foundation, Inc., 51
 
- Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
- """
 
- import os, traceback, hashlib, sys, time, socket, datetime
 
- import platform, subprocess, re, webbrowser, shutil
 
- from core.options import CIntruderOptions
 
- from core.crack import CIntruderCrack
 
- from core.ocr import CIntruderOCR
 
- from core.curl import CIntruderCurl
 
- from core.xml_export import CIntruderXML
 
- from core.update import Updater
 
- try:
 
-     from urlparse import urlparse
 
- except:
 
-     import urllib.request, urllib.parse, urllib.error
 
-     from urllib.parse import urlparse
 
- # set to emit debug messages about errors (0 = off).
 
- DEBUG = 0
 
- class cintruder():
 
-     """
 
-     CIntruder application class
 
-     """
 
-     def __init__(self):
 
-         self.captcha = ""
 
-         self.optionOCR = []
 
-         self.optionCrack = []
 
-         self.optionParser = None
 
-         self.optionCurl = None
 
-         self.options = None
 
-         self.word_sug = None
 
-         self.train == 0
 
-         self.crack == 0
 
-         self.ignoreproxy = 1  
 
-         self.isurl = 0
 
-         self.os_sys = platform.system()
 
-         self._webbrowser = webbrowser
 
-         self.GIT_REPOSITORY = 'https://code.03c8.net/epsylon/cintruder' # oficial code source [OK! 26/01/2019]
 
-         self.GIT_REPOSITORY2 = 'https://github.com/epsylon/cintruder' # mirror source [since: 04/06/2018]
 
-     def set_options(self, options):
 
-         """
 
-         Set cintruder options
 
-         """
 
-         self.options = options
 
-     def create_options(self, args=None):
 
-         """
 
-         Create the program options for OptionParser.
 
-         """
 
-         self.optionParser = CIntruderOptions()
 
-         self.options = self.optionParser.get_options(args)
 
-         if not self.options:
 
-             return False
 
-         return self.options
 
-     def set_webbrowser(self, browser):
 
-         self._webbrowser = browser
 
-     def banner(self):
 
-         print('='*75)
 
-         print("")
 
-         print("        o8%8888,    ")
 
-         print("       o88%8888888. ")
 
-         print("      8'-    -:8888b   ")
 
-         print("     8'         8888  ")
 
-         print("    d8.-=. ,==-.:888b  ")
 
-         print("    >8 `~` :`~' d8888   ")
 
-         print("    88         ,88888   ")
 
-         print("    88b. `-~  ':88888  ")
 
-         print("    888b \033[1;31m~==~\033[1;m .:88888 ")
 
-         print("    88888o--:':::8888      ")
 
-         print("    `88888| :::' 8888b  ")
 
-         print("    8888^^'       8888b  ")
 
-         print("   d888           ,%888b.   ")
 
-         print("  d88%            %%%8--'-.  ")
 
-         print(" /88:.__ ,       _%-' ---  -  ")
 
-         print("     '''::===..-'   =  --.  `\n")
 
-         print(self.optionParser.description, "\n")
 
-         print('='*75)
 
-     def get_attack_captchas(self):
 
-         """
 
-         Get captchas to brute force
 
-         """
 
-         captchas = []
 
-         options = self.options
 
-         p = self.optionParser
 
-         if options.train:
 
-             print(('='*75))
 
-             print((str(p.version)))
 
-             print(('='*75))
 
-             print("Starting to 'train'...")
 
-             print(('='*75))
 
-             captchas = [options.train]
 
-         if options.crack:
 
-             print(('='*75))
 
-             print((str(p.version)))
 
-             print(('='*75))
 
-             print("Starting to 'crack'")
 
-             print(('='*75))
 
-             captchas = [options.crack]
 
-         if options.track:
 
-             print(('='*75))
 
-             print((str(p.version)))
 
-             print(('='*75))
 
-             print("Tracking captchas from url...")
 
-             print(('='*75))
 
-             captchas = [options.track]
 
-         return captchas
 
-     def train(self, captcha):
 
-         """
 
-         Learn mode:
 
-             + Add words to the brute forcing dictionary
 
-         """
 
-         self.train_captcha(captcha)
 
-     def train_captcha(self, captcha):
 
-         """
 
-         Learn mode:
 
-             1- Apply OCR to captcha/image and split into unities
 
-             2- Human-Recognize that unities like alphanumeric words (gui supported)
 
-             3- Move that words into dictionary (gui supported)
 
-         """
 
-         options = self.options
 
-         # step 1: applying OCR techniques
 
-         if options.name: # with a specific OCR module
 
-             print("[Info] Loading module: [ "+ options.name + " ]\n")
 
-             try:
 
-                 sys.path.append('mods/%s/'%(options.name))
 
-                 exec("from " + options.name + "_ocr" + " import CIntruderOCR") # import module
 
-             except Exception:
 
-                 print("\n[Error] '"+ options.name+ "' module not found!\n")
 
-                 return #sys.exit(2)
 
-             if options.setids: # with a specific colour ID
 
-                 setids = int(options.setids)
 
-                 if setids >= 0 and setids <= 255:
 
-                     self.optionOCR = CIntruderOCR(captcha, options)
 
-                 else:
 
-                     print("\n[Error] You must enter a valid RGB colour ID number (between 0 and 255)\n")
 
-                     return #sys.exit(2)
 
-             else:
 
-                 self.optionOCR = CIntruderOCR(captcha, options)
 
-         else: # using general OCR algorithm
 
-             if options.setids: # with a specific colour ID
 
-                 setids = int(options.setids)
 
-                 if setids >= 0 and setids <= 255:
 
-                     self.optionOCR = CIntruderOCR(captcha, options)
 
-                 else:
 
-                     print("\n[Error] You must enter a valid RGB colour ID number (between 0 and 255)\n")
 
-                     return #sys.exit(2)
 
-             else:
 
-                 self.optionOCR = CIntruderOCR(captcha, options)
 
-     def crack(self, captcha):
 
-         """
 
-         Crack mode:
 
-             + Brute force target's captcha against a dictionary
 
-         """
 
-         self.crack_captcha(captcha)
 
-     def crack_captcha(self, captcha):
 
-         """
 
-         Crack mode: bruteforcing...
 
-         """
 
-         options = self.options
 
-         if options.name:
 
-             print("[Info] Loading module: ["+ str(options.name) + "] \n")
 
-             try:
 
-                 sys.path.append('mods/%s/'%(options.name))
 
-                 exec("from " + options.name + "_crack" + " import CIntruderCrack")
 
-             except Exception:
 
-                 print("\n[Error] '"+ options.name+ "' module not found!\n")
 
-                 return #sys.exit(2)
 
-             self.optionCrack = CIntruderCrack(captcha)
 
-             w = self.optionCrack.crack(options)
 
-             self.word_sug = w
 
-         else:
 
-             self.optionCrack = CIntruderCrack(captcha)
 
-             w = self.optionCrack.crack(options)
 
-             self.word_sug = w
 
-     def remote(self, captchas, proxy):
 
-         """
 
-         Get remote captchas 
 
-         """
 
-         l = []
 
-         if not os.path.exists("inputs/"):
 
-             os.mkdir("inputs/")
 
-         for captcha in captchas:
 
-             c = self.remote_captcha(captcha, proxy)
 
-             if c:
 
-                 l.append(c)
 
-                 return l
 
-             else:
 
-                 return
 
-     def remote_captcha(self, captcha, proxy):
 
-         """
 
-         Get remote captcha
 
-         """
 
-         if proxy:
 
-             self.ignoreproxy=0
 
-         self.optionCurl = CIntruderCurl(captcha, self.ignoreproxy, proxy)
 
-         buf = self.optionCurl.request()
 
-         if buf != "exit":
 
-             m = hashlib.md5()
 
-             try:
 
-                 m.update(captcha.encode('utf-8')+str(datetime.datetime.now()))
 
-             except:
 
-                 m.update(str(datetime.datetime.now()).encode('utf-8'))
 
-             c = "%s.gif"%(m.hexdigest())
 
-             h = "inputs/" + str(c)
 
-             f = open(h, 'wb')
 
-             f.write(buf.getvalue())
 
-             f.close
 
-             buf.close
 
-             return h
 
-         else:
 
-             return #sys.exit(2)
 
-     def export(self, captchas):
 
-         """
 
-         Export results
 
-         """
 
-         if self.options.xml and not (self.options.train):
 
-             self.optionXML = CIntruderXML(captchas)
 
-             if self.word_sug == None:
 
-                 print("[Info] XML NOT created!. There are not words to suggest...")
 
-             else:
 
-                 self.optionXML.print_xml_results(captchas, self.options.xml, self.word_sug)
 
-                 print("[Info] XML created: "+str(self.options.xml)+ "\n")
 
-     def track(self, captchas, proxy, num_tracks):
 
-         """
 
-         Download captchas from url
 
-         """
 
-         for captcha in captchas:
 
-             self.track_captcha(captcha, proxy, num_tracks)
 
-     def track_captcha(self, captcha, proxy, num_tracks):
 
-         """
 
-         This technique is useful to create a dictionary of 'session based' captchas
 
-         """
 
-         options = self.options
 
-         urlp = urlparse(captcha)
 
-         self.domain = urlp.hostname
 
-         if not os.path.exists("inputs/%s"%(self.domain)):
 
-             os.mkdir("inputs/%s"%(self.domain))
 
-         if proxy:
 
-             self.ignoreproxy = 0
 
-         buf = ""
 
-         i=0
 
-         while i < int(num_tracks) and buf != "exit":
 
-             self.optionCurl = CIntruderCurl(captcha, self.ignoreproxy, proxy)
 
-             buf = self.optionCurl.request()
 
-             if options.verbose:
 
-                 print("\n[-]Connection data:")
 
-                 out = self.optionCurl.print_options()
 
-                 print('-'*45)
 
-             if buf != "exit":
 
-                 m = hashlib.md5()
 
-                 try:
 
-                     m.update(captcha.encode('utf-8')+str(datetime.datetime.now()))
 
-                 except:
 
-                     m.update(str(datetime.datetime.now()).encode('utf-8'))
 
-                 h = "inputs/%s/%s.gif"%(self.domain, m.hexdigest())
 
-                 f = open(h, 'wb')
 
-                 f.write(buf.getvalue())
 
-                 f.close
 
-                 buf.close
 
-                 print("[Info] Saved: "+ str(h))
 
-                 print("------------")
 
-             i=i+1
 
-         if buf != "exit":
 
-             print("\n=================")
 
-             print("Tracking Results:")
 
-             print("=================")
 
-             print("\nNumber of tracked captchas: [ "+ str(num_tracks)+" ] \n")
 
-     def run(self, opts=None):
 
-         """ 
 
-         Run cintruder
 
-         """ 
 
-         if opts:
 
-             options = self.create_options(opts)
 
-             self.set_options(options)
 
-         options = self.options
 
-         #step -1: run GUI/Web interface
 
-         if options.web:
 
-             self.create_web_interface()
 
-             return
 
-         #step -1: check/update for latest stable version
 
-         if options.update:
 
-             self.banner()
 
-             try:
 
-                 print("\nTrying to update automatically to the latest stable version\n")
 
-                 Updater() 
 
-             except:
 
-                 print("Not any .git repository found!\n")
 
-                 print("="*30)
 
-                 print("\nTo have working this feature, you should clone CIntruder with:\n")
 
-                 print("$ git clone %s" % self.GIT_REPOSITORY)
 
-                 print("\nAlso you can try this other mirror:\n")
 
-                 print("$ git clone %s" % self.GIT_REPOSITORY2 + "\n")
 
-         #step 0: list output results and get captcha targets
 
-         if options.listmods:
 
-             print("=====================================")
 
-             print("Listing specific OCR exploit modules:")
 
-             print("=====================================\n")
 
-             top = 'mods/'
 
-             for root, dirs, files in os.walk(top, topdown=False):
 
-                 for name in files:
 
-                     if name == 'DESCRIPTION':
 
-                         if self.os_sys == "Windows": #check for win32 sys
 
-                             subprocess.call("type %s/%s"%(root, name), shell=True)
 
-                         else:
 
-                             subprocess.call("cat %s/%s"%(root, name), shell=True)
 
-             print("\n[Info] List end...\n")
 
-             return
 
-         if options.track_list:
 
-             print("==============================")
 
-             print("Listing last tracked captchas:")
 
-             print("==============================\n")
 
-             top = 'inputs/'
 
-             tracked_captchas = []
 
-             for root, dirs, files in os.walk(top, topdown=False):
 
-                 for name in files:
 
-                     path = os.path.relpath(os.path.join(root, name))
 
-                     if self.os_sys == "Windows": #check for win32 sys
 
-                         atime = os.path.getatime(path)
 
-                     else:
 
-                         date = os.stat(path)
 
-                         atime = time.ctime(date.st_atime)
 
-                     tracked_captchas.append([atime,str(" + "+name),str("   |-> "+path)])
 
-             tracked_captchas=sorted(tracked_captchas,key=lambda x:x[0]) # sorted by accessed time
 
-             ca = 0 # to control max number of results
 
-             for t in tracked_captchas:
 
-                 ca = ca + 1
 
-                 print("-------------------------")
 
-                 for c in t:
 
-                     if ca < 26:
 
-                         print(c)
 
-                     else:
 
-                         break
 
-                 print("-------------------------")
 
-             print("\n[Info] List end...\n")
 
-             return 
 
-         captchas = self.get_attack_captchas()
 
-         captchas = self.sanitize_captchas(captchas)
 
-         captchas2track = captchas
 
-         if self.isurl == 1 and (options.train or options.crack):
 
-             if options.proxy:
 
-                 captchas = self.remote(captchas, options.proxy)
 
-             else:
 
-                 captchas = self.remote(captchas, "")
 
-             if options.verbose:
 
-                 print("\n[-] Connection data:")
 
-                 out = self.optionCurl.print_options()
 
-                 print('-'*45)
 
-         #step 0: track
 
-         if options.track:
 
-             if options.s_num:
 
-                 num_tracks = int(options.s_num) # tracking number defined by user
 
-             else:
 
-                 num_tracks = int(5) # default track connections
 
-             if options.proxy:
 
-                 self.track(captchas2track, options.proxy, num_tracks)
 
-             else:
 
-                 self.track(captchas2track, "", num_tracks)
 
-         #step 1: train
 
-         if options.train:
 
-             try:
 
-                 if len(captchas) == 1:
 
-                     for captcha in captchas:
 
-                         if captcha is None:
 
-                             print("\n[Error] Applying OCR algorithm... Is that captcha supported?\n")
 
-                             if os.path.exists('core/images/previews'):
 
-                                 shutil.rmtree('core/images/previews') # remove last OCR
 
-                         else:
 
-                             print("\n[Info] Target: "+ options.train+"\n")
 
-                             self.train(captcha)
 
-                 else:
 
-                     for captcha in captchas:
 
-                         if len(captchas) > 1 and captcha is None:
 
-                             pass
 
-                         else:
 
-                             print("\n[Info] Target: "+ options.train+"\n")
 
-                             self.train(captcha)
 
-             except:
 
-                 print("[Error] Something wrong getting captcha. Aborting...\n")
 
-             if options.xml:
 
-                 print("[Info] You don't need export to XML on this mode... File not generated!\n")
 
-         #step 2: crack
 
-         if options.crack:
 
-             if len(captchas) == 1:
 
-                 for captcha in captchas:
 
-                     if captcha is None:
 
-                         print("\n[Error] Trying to bruteforce... Is that captcha supported?\n")
 
-                         if os.path.exists('core/images/previews'):
 
-                             shutil.rmtree('core/images/previews') # remove last OCR
 
-                     else:
 
-                         print("\n[Info] Target: "+ options.crack+"\n")
 
-                         self.crack(captcha)
 
-             else:
 
-                 for captcha in captchas:
 
-                     if len(captchas) > 1 and captcha is None:
 
-                         pass
 
-                     else:
 
-                         print("\n[Info] Target: "+ options.crack+"\n")
 
-                         self.crack(captcha)
 
-             if options.command:
 
-                 print("[Info] Executing tool connector... \n")
 
-                 if self.word_sug is not None:
 
-                     print("[Info] This is the word suggested by CIntruder: [ "+ str(self.word_sug)+ " ] \n")
 
-                 else:
 
-                     print("[Error] CIntruder hasn't any word to suggest... Handlering tool process aborted! ;(\n")
 
-                     sys.exit(2)
 
-                 if "CINT" in options.command: # check parameter CINT on command (*)
 
-                     # change cintruder suggested word for the users captchas input form parameter
 
-                     # and execute handlered tool with it.
 
-                     if self.word_sug is not None:      
 
-                         cmd = options.command.replace("CINT", self.word_sug)
 
-                         subprocess.call(cmd, shell=True)
 
-                     else:
 
-                         cmd = options.command
 
-                         subprocess.call(cmd, shell=True)
 
-                 else:
 
-                     print("[Error] Captcha's parameter flag: 'CINT' is not present on: "+ str(options.command)+ "\n")
 
-         #step 3: export
 
-         if options.xml:
 
-             self.export(captchas)
 
-     def sanitize_captchas(self, captchas):
 
-         """
 
-         Sanitize correct input of source target(s)
 
-         """
 
-         options = self.options
 
-         all_captchas = set()
 
-         for captcha in captchas:
 
-             # captcha from url
 
-             if "http://" in captcha or "https://" in captcha:
 
-                 all_captchas.add(captcha)
 
-                 self.isurl = 1
 
-             elif self.isurl == 0: # captcha from file
 
-                 (root, ext) = os.path.splitext(captcha)       
 
-                 if ext != '.gif' and ext != '.jpg' and ext != '.jpeg' and ext != '.png': # by the moment                    
 
-                     captcha = None
 
-                     all_captchas.add(captcha)
 
-                 else:
 
-                     all_captchas.add(captcha)
 
-                 self.isurl = 0
 
-         return all_captchas
 
-     def create_web_interface(self):
 
-         # launch webserver+gui
 
-         from .webgui import ClientThread
 
-         import webbrowser
 
-         host = '0.0.0.0'
 
-         port = 9999
 
-         try:
 
-             webbrowser.open('http://127.0.0.1:9999', new=1)
 
-             tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
-             tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 
-             tcpsock.bind((host,port))
 
-             while True:
 
-                 tcpsock.listen(4)
 
-                 (clientsock, (ip, port)) = tcpsock.accept()
 
-                 newthread = ClientThread(ip, port, clientsock)
 
-                 newthread.start()
 
-         except (KeyboardInterrupt, SystemExit):
 
-             sys.exit()
 
- if __name__ == "__main__":
 
-     app = cintruder()
 
-     options = app.create_options()
 
-     if options:
 
-         app.set_options(options)
 
-         app.run()
 
 
  |