123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- #!/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
- """
- from PIL import Image
- import hashlib, os, math, time
- import shutil
- class VectorCompare:
- def magnitude(self, concordance):
- total = 0
- for word, count in concordance.items():
- # print concordance
- total += count ** 2
- return math.sqrt(total)
- def relation(self, concordance1, concordance2):
- topvalue = 0
- for word, count in concordance1.items():
- if word in concordance2:
- topvalue += count * concordance2[word]
- return topvalue / (self.magnitude(concordance1) * self.magnitude(concordance2))
- class CIntruderCrack(object):
- """
- Class to bruteforce captchas
- """
- def __init__(self, captcha=""):
- """
- Initialize main CIntruder
- """
- self.captcha = self.set_captcha(captcha)
- start = time.time()
- if not os.path.exists("core/images/previews/"):
- os.mkdir("core/images/previews/")
- else:
- shutil.rmtree("core/images/previews/")
- os.mkdir("core/images/previews/")
- def buildvector(self, im):
- d1 = {}
- count = 0
- for i in im.getdata():
- d1[count] = i
- count += 1
- return d1
- def set_captcha(self, captcha):
- """
- Set the captcha.
- """
- self.captcha = captcha
- return captcha
-
- def crack(self, options):
- v = VectorCompare()
- path, dirs, files = next(os.walk("dictionary/"))
- dictionary = dirs
- imageset = []
- last_letter = None
- print("[Info] Loading dictionary...\n")
- for letter in dictionary:
- for img in os.listdir('dictionary/'+letter):
- temp = []
- temp.append(self.buildvector(Image.open("dictionary/%s/%s"%(letter, img))))
- imageset.append({letter:temp})
- try:
- im = Image.open(self.captcha)
- im.save("core/images/previews/last-preview.gif")
- im2 = Image.new("P", im.size, 255)
- im = im.convert("P")
- except:
- print("[Error] Fail during cracking!. Is that captcha supported?\n")
- if os.path.exists('core/images/previews'):
- shutil.rmtree('core/images/previews') # remove last OCR
- return
- temp = {}
- try:
- setids = int(options.setids)
- except:
- setids = 3 # default pixel colour id
- for x in range(im.size[1]):
- for y in range(im.size[0]):
- pix = im.getpixel((y, x))
- temp[pix] = pix
- if pix == setids: # pixel colour id
- im2.putpixel((y, x), 0)
- inletter = False
- foundletter = False
- start = 0
- end = 0
- letters = []
- for y in range(im2.size[0]): # slice across
- for x in range(im2.size[1]): # slice down
- pix = im2.getpixel((y, x))
- if pix == 0: # != 255
- inletter = True
- if foundletter == False and inletter == True:
- foundletter = True
- start = y
- if foundletter == True and inletter == False:
- foundletter = False
- end = y
- letters.append((start, end))
- inletter = False
- count = 0
- countid = 1
- word_sug = None
- end = time.time()
- elapsed = end - start
- words = {}
- for letter in letters:
- m = hashlib.md5()
- try:
- m.update(str(letter))
- except:
- m.update(str(letter).encode('utf-8'))
- im3 = im2.crop((letter[0], 0, letter[1], im2.size[1]))
- guess = []
- for image in imageset:
- for x, y in image.items():
- if len(y) != 0:
- guess.append(( v.relation(y[0], self.buildvector(im3)), x))
- guess.sort(reverse=True)
- word_per = guess[0][0] * 100
- if str(word_per) == "100.0":
- print("Image position : "+ str(countid))
- print("Broken Percent : "+ str(int(round(float(word_per))))+ "%"+ " [ FULL CRACKED!!! ]")
- words[countid] = guess[0][1]
- else:
- print("Image position : "+ str(countid))
- print("Broken Percent : %.4f" % word_per+ "%")
- words[countid] = "_"
- print("Word suggested : "+str(guess[0][1]))
- print("-------------------")
- if word_sug == None:
- word_sug = str(guess[0][1])
- else:
- word_sug = word_sug + str(guess[0][1])
- count += 1
- countid = countid + 1
- print("\n========================================")
- if options.verbose:
- print("[Info] Elapsed OCR time : "+ str(elapsed))
- print("========================================")
- if word_sug is None:
- print("Suggested Solution: [ No idea!. Try to add more images to your dictionary/ ]")
- else:
- print("Cracked Words: "+ str(list(words.values())))
- print("Suggested Solution: [ "+ str(word_sug)+ " ]")
- print("========================================\n")
- return word_sug
|