【Python】使用pillow和numpy通过knn算法破解简单验证码

我到底是怀着怎样的心情写下这段程序的呢……
大概是之前hw手机解锁的设备识别码因为开不了机无法获取而试图去枚举出来吧……

首先,本篇博文不提供对应枚举攻击代码,需要使用的请自行拿去改造,造成的责任自负。

这段程序需要预装的模块有pillow,progressbar,requests和numpy。

try:
	import requests
except:
	os.system('pip install requests')
	import requests

try:
	import progressbar
except:
	os.system('pip install progressbar')
	import progressbar
try:
	import numpy as np
except:
	os.system('pip install numpy')
	import numpy as np
try:
	from PIL import Image
except:
	os.system('pip install pillow')
	from PIL import Image
from random import *
import sys,os

程序开始,我们先从某网站爬取一个验证码。
那个网站的请求有点奇怪,获取验证码的时候需要用GET方法给它发送一个随机数。

然后提交验证码的时候需要提交图片的文字以及之前请求时提交的随机数,才算完成验证。

我们使用random模块直接给它生成一个随机数,发送过去。

hds={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36","Referer":"https://www.emui.com/cn/unlock_detail"}
rd=random()
lin="https://www.emui.com/cn/plugin/unlock/vercode?"+str(rd)

rq=requests.get(lin,headers=hds)
gi=rq.content

gi里面装有一个gif图片的二进制,我们要把它写入文件才能使用pillow来读取。

f_p=sys.path[0]+'\\raw'+'\\'+str(rd)+'.gif'
f=open(f_p,'wb')#这以下三行是存图片的
f.write(gi)
f.flush()

接下来使用pillow读取图片,并按照字符相对位置进行切割,保证每个字符相互独立。

lc=[(2,4,13,19),(17,4,28,19),(32,4,43,19),(47,4,58,19)]
f=open(f_p,'rb')
ig=Image.open(f)
ig.show()

vercode_knn=[]


for i in range(4):
	crig=ig.crop(lc[i])

然后把切下来的每个字符转成矩阵,送去比较。统计出现最多的颜色,然后记入列表。
每个字符的本体实际上颜色是单一的,而干扰色块的颜色是随机的,所以要进行比较统计出现最频繁的颜色
强烈安利numpy的array方法!炒鸡好用!

giff=crig
	res=np.array(giff)
	color_static={}

	for cur_row in res:
		for cur_pix in cur_row:
			if cur_pix!=0:
				color_static[str(cur_pix)]=color_static.get(str(cur_pix),0)+1
	#print(res)
	mx_color=''
	mx_color_times=0
	for ke,va in color_static.items():
		if va>mx_color_times:
			mx_color_times=va
			mx_color=ke
	for cur_row in range(len(res)):
		for cur_pix in range(len(res[cur_row])):
			if res[cur_row][cur_pix]!=int(mx_color):
				res[cur_row][cur_pix]=0
	#以下是knn
	map=[]
	tags=[]
	from_digit_list=res

	for j in to_list:
		pat=to+'\\'+j
		to_digit_list=np.loadtxt(pat)
		t1=from_digit_list-to_digit_list
		t1=t1**2
		t1=sum(t1)
		t1=sum(t1)
		map.append(t1)
		tags.append(j[:1])

	ranking=np.argsort(map)
	tagctr={}
	
	for ima in range(3):#knn中的k值
		cur_tag=tags[ranking[ima]]
		tagctr[cur_tag]=tagctr.get(cur_tag,0)+1
	
	mx=0#找出现最多的标签的出现数
	
	for k,v in tagctr.items():
		if v>mx:
			mx=v
			output_tag=k
	#print('分类结果:'+output_tag)
	#print('第k邻近表:')
	#print(tagctr)

完整代码及训练数据会在附件上传。
https://files.cnblogs.com/files/voidf/华为vercode.zip
以后可能会尝试开发学习开关。

posted @ 2018-06-04 18:51  昵称不能为空voidf  阅读(145)  评论(0)    收藏  举报