|  | @@ -0,0 +1,465 @@
 | 
	
		
			
				|  |  | +#!/usr/bin/python
 | 
	
		
			
				|  |  | +# -*- coding: iso-8859-15 -*-
 | 
	
		
			
				|  |  | +"""
 | 
	
		
			
				|  |  | +This file is part of the cintruder project, http://cintruder.03c8.net
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +Copyright (c) 2012/2016 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, urlparse
 | 
	
		
			
				|  |  | +import platform, subprocess, re, webbrowser
 | 
	
		
			
				|  |  | +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
 | 
	
		
			
				|  |  | +from urlparse 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
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    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
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @classmethod
 | 
	
		
			
				|  |  | +    def try_running(cls, func, error, args=None):
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        Try running a function and print some error if it fails and exists with
 | 
	
		
			
				|  |  | +        a fatal error.
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        args = args or []
 | 
	
		
			
				|  |  | +        try:
 | 
	
		
			
				|  |  | +            return func(*args)
 | 
	
		
			
				|  |  | +        except Exception:
 | 
	
		
			
				|  |  | +            print(error, "error")
 | 
	
		
			
				|  |  | +            if DEBUG:
 | 
	
		
			
				|  |  | +                traceback.print_exc()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    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+"\n")
 | 
	
		
			
				|  |  | +            captchas = [options.track]       
 | 
	
		
			
				|  |  | +        return captchas
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def train(self, captchas):
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        Learn mode:
 | 
	
		
			
				|  |  | +            + Add words to the brute forcing dictionary
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        self.train_captcha(captchas)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    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] Using module: [", options.name, "]"
 | 
	
		
			
				|  |  | +            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, captchas):
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        Crack mode:
 | 
	
		
			
				|  |  | +            + Brute force target's captcha against a dictionary
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        self.crack_captcha(captchas)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def crack_captcha(self, captcha):
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        Crack mode: bruteforcing...
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        options = self.options
 | 
	
		
			
				|  |  | +        if options.name:
 | 
	
		
			
				|  |  | +            print "Loading module:", options.name
 | 
	
		
			
				|  |  | +            print "==============="
 | 
	
		
			
				|  |  | +            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)
 | 
	
		
			
				|  |  | +            l.append(c)
 | 
	
		
			
				|  |  | +        return l
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    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()
 | 
	
		
			
				|  |  | +            m.update(captcha)
 | 
	
		
			
				|  |  | +            c = "%s.gif"%(m.hexdigest())
 | 
	
		
			
				|  |  | +            h = "inputs/" + 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:", 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()
 | 
	
		
			
				|  |  | +                m.update("%s%s"%(time.time(), captcha))
 | 
	
		
			
				|  |  | +                h = "inputs/%s/%s.gif"%(self.domain, m.hexdigest())
 | 
	
		
			
				|  |  | +                f = open(h, 'wb')
 | 
	
		
			
				|  |  | +                f.write(buf.getvalue())
 | 
	
		
			
				|  |  | +                f.close
 | 
	
		
			
				|  |  | +                buf.close
 | 
	
		
			
				|  |  | +                print "[Info] Saved:", h
 | 
	
		
			
				|  |  | +                print "------------"
 | 
	
		
			
				|  |  | +            i=i+1
 | 
	
		
			
				|  |  | +        if buf != "exit":
 | 
	
		
			
				|  |  | +            print "\n================="
 | 
	
		
			
				|  |  | +            print "Tracking Results:"
 | 
	
		
			
				|  |  | +            print "================="
 | 
	
		
			
				|  |  | +            print "\nNumber of tracked captchas: [", 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("\nSomething was wrong!. To have working this feature, you should clone CIntruder with:\n")
 | 
	
		
			
				|  |  | +                print("$ git clone https://github.com/epsylon/cintruder\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 #sys.exit(2)    
 | 
	
		
			
				|  |  | +        captchas = self.try_running(self.get_attack_captchas, "\nInternal error getting -captchas-. look at the end of this Traceback.")
 | 
	
		
			
				|  |  | +        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 "[-] 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.try_running(self.track, "\nInternal problems tracking: ", (captchas2track, options.proxy, num_tracks))
 | 
	
		
			
				|  |  | +            else:
 | 
	
		
			
				|  |  | +                self.try_running(self.track, "\nInternal problems tracking: ", (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"
 | 
	
		
			
				|  |  | +                        else:
 | 
	
		
			
				|  |  | +                            print "Target:", options.train
 | 
	
		
			
				|  |  | +                            print "=======\n"
 | 
	
		
			
				|  |  | +                            self.try_running(self.train, "\nInternal problems training: ", (captchas))   
 | 
	
		
			
				|  |  | +                else:
 | 
	
		
			
				|  |  | +                    for captcha in captchas:
 | 
	
		
			
				|  |  | +                        if len(captchas) > 1 and captcha is None:
 | 
	
		
			
				|  |  | +                            pass
 | 
	
		
			
				|  |  | +                        else:
 | 
	
		
			
				|  |  | +                            print "Target: ", options.train
 | 
	
		
			
				|  |  | +                            self.try_running(self.train, "\nInternal problems training: ", (captchas))
 | 
	
		
			
				|  |  | +            except:
 | 
	
		
			
				|  |  | +                print "\n[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"
 | 
	
		
			
				|  |  | +                    else:
 | 
	
		
			
				|  |  | +                        print "Target: ", options.crack
 | 
	
		
			
				|  |  | +                        print "======="
 | 
	
		
			
				|  |  | +                        self.try_running(self.crack, "\nInternal problems cracking: ", (captchas))
 | 
	
		
			
				|  |  | +            else:
 | 
	
		
			
				|  |  | +                for captcha in captchas:
 | 
	
		
			
				|  |  | +                    if len(captchas) > 1 and captcha is None:
 | 
	
		
			
				|  |  | +                        pass
 | 
	
		
			
				|  |  | +                    else:
 | 
	
		
			
				|  |  | +                        print "Target: ", options.crack
 | 
	
		
			
				|  |  | +                        print "======="
 | 
	
		
			
				|  |  | +                        self.try_running(self.crack, "\nInternal problems cracking: ", (captchas))
 | 
	
		
			
				|  |  | +            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: [", 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:", options.command, "\n"
 | 
	
		
			
				|  |  | +        #step 3: export
 | 
	
		
			
				|  |  | +        if options.xml:
 | 
	
		
			
				|  |  | +            self.try_running(self.export, "\nInternal problems exporting: ", (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):
 | 
	
		
			
				|  |  | +        from webgui import ClientThread
 | 
	
		
			
				|  |  | +        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()
 |