使用gan破解极验滑动验证码

使用gan破解极验滑动验证码

本文提供一个使用GAN破解滑动验证码的思路,完整代码由于利益关系,没有办法公开。

极验的滑动验证码原理

捕捉滑动轨迹,通过分类器判断动作是人做的还是机器做的。
极验是没有办法捕获我们完整的动作的,它会在几个时间点,捕捉滑动块的位置,生成一个序列发送给服务端做检验。这也为我们提供了破解的思路。

破解方法

破解方法很直观,我们生成一组滑动块位置,然后以0.3秒的间隔依次滑动过去,骗过极验的后台。

1,获取原始图片

极验验证码的原始图片会和带缺口的图片一起传过来,但是并不会显示给用户,虽然它就在页面上,但是被设置为不显示。
获取方法也很简单:
仔细分析极验的验证码,你会发现,在标签里面有一个叫geetest_canvas_fullbg 的cavas非常奇怪,鼠标放上去会有完整的图片展示出来。
废话就不多说了,这就是我们要的原始图片。

2,获取带缺口的图片

3,计算滑动距离

获取原始图片和缺口图片以后,就可以开始计算需要滑动的距离。这里,计算距离方法如下:
依次遍历图片的每一个像素,找到原始图片和带缺口图片差异较大的点。这些点都有可能师缺口位置的点

def get_distance(image1, image2, left=57, threshold=60, deviation=6):
    i = 0

    for i in range(left, image1.size[0] - 40):
        for j in range(image1.size[1] - 40):
            rgb1 = image1.load()[i, j]
            rgb2 = image2.load()[i, j]
            res1 = abs(rgb1[0] - rgb2[0])
            res2 = abs(rgb1[1] - rgb2[1])
            res3 = abs(rgb1[2] - rgb2[2])
            if not (res1 < threshold and res2 < threshold and res3 < threshold):
                # image2.crop((i,j,i+40,j+40)).save('tmp_cod1.png')
                # image1.crop((i,j,i+40,j+40)).save('tmp_cod2.png')
                if is_sub_cod(i, j, image1, image2, threshold)://有可能为缺口,需要进一步确认
                    tmp_imge = image2.crop((i, j, i + 40, j + 40))
                    tmp_imge.save('tmp_cod.png')
                    print(i)
                    return i
                break
    logging.debug("未识别出验证码中的不同位置, 或图片定位出现异常")
    print(i)
    return 260

确定了候选点以后,需要进行进一步的确认,确认方法如下:

def is_sub_cod(left, top, image1, image2, threshold):
    count = 0
    all = 40 * 40
    for i in range(left, left + 40):
        for j in range(top, top + 40):
            rgb1 = image1.load()[i, j]
            rgb2 = image2.load()[i, j]
            res1 = abs(rgb1[0] - rgb2[0])
            res2 = abs(rgb1[1] - rgb2[1])
            res3 = abs(rgb1[2] - rgb2[2])
            if not (res1 < threshold and res2 < threshold and res3 < threshold):
                count += 1
    print("count is {0}".format(count))
    if count / all >= 0.6:
        return True
    else:
        return False

到了这里,我们就可以获得需要滑动的距离了。
如果你直接使用这个距离,模拟浏览器操作,你会悲惨的发现,验证通过不了。
极验的后端会识别出哪些不是人进行的操作。接下来,我们就尝试破解行为验证。

4,随机生成数据,产生训练样本

为了能够训练模型,首先我们需要获得训练数据。这里,训练数据的获得有两种方法:

  1. 人为拖动滑块,记录滑块的位置点。
  2. 随机生成一些点,尝试进行极验的验证,记录验证成功和失败的操作。
    我们这里采用第二种方法。
    这里会有一个问题,就是尝试次数过多的化,会被网站封锁ip,所以这里提示大家一个好方法:
    申请极验的试用,然后在本地进行数据采集,就不会有被封ip的风险了。

5,训练生成模型

有了数据以后,我们就可以训练模型了。使用tesorflow构建一个gan生成神经网络:
在构建模型时候,主要踩到坑如下:

  • 不需要使用rnn,因为我们最终生成的序列长度不会超过10位,事实上大部分都只有2-3位,多的部分用0补齐
  • 不要在判别或者生成器最后使用sigmod函数,如果使用了,那么你的模型很可能不会收敛
  • 不要使用批量训练,批量计算时会将梯度平均化,会导致训练结果全都是一个值
  1. 构建生成模型:
Gh1 = tf.nn.leaky_relu(tf.matmul(self.Z, G_W1z) + tf.matmul(self.Y, G_W1y) + G_b1)
      Gh2 = tf.nn.leaky_relu(tf.matmul(Gh1, G_W2) + G_b2)
      Gh3 = tf.nn.leaky_relu(tf.matmul(Gh2, G_W3) + G_b3)
      self.G = tf.matmul(Gh3, G_W4) + G_b4
  1. 构建判别模型
Dh1 = tf.nn.leaky_relu(tf.matmul(self.X, D_W1x) + tf.matmul(self.Y, D_W1y) + D_b1)
Dh2 = tf.nn.leaky_relu(tf.matmul(Dh1, D_W2) + D_b2)
Dh3 = tf.nn.leaky_relu(tf.matmul(Dh2, D_W3) + D_b3)
self.D = tf.matmul(Dh3, D_W4) + D_b4
  1. 判别生成的样本
DGh1 = tf.nn.leaky_relu(tf.matmul(self.G, D_W1x) + tf.matmul(self.Y, D_W1y) + D_b1)
    DGh2 = tf.nn.leaky_relu(tf.matmul(DGh1, D_W2) + D_b2)
    DGh3 = tf.nn.leaky_relu(tf.matmul(DGh2, D_W3) + D_b3)
    self.DG = tf.matmul(DGh3, D_W4) + D_b4
  1. 构建训练器
self.D_solver = tf.train.AdamOptimizer(learning_rate=0.1).minimize(self.Dloss, var_list=theta_D)
self.G_solver = tf.train.AdamOptimizer(learning_rate=0.01).minimize(self.Gloss, var_list=theta_G)
  1. 训练模型
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    counter = 0
    g_count = 0
    d_count = 0
    start_dis = True
    for e in range(epochs):
        # new_state = sess.run(model.initial_state)
        loss = 0
        for x, y in get_batches(*read_data(data_path), batch_size)://这里一定要一条一条数据的训练,血的教训
            counter += 1
            start = time.time()
            feed = {
                model.X: x,
                model.Y: y,
                model.Z: sample_Z(batch_size, 100)
            }

            if start_dis:
                _, d_loss_crr, d, dg, g_x, g_restract, t_x, t_y, g_y = sess.run(
                    [model.D_solver, model.Dloss, model.D, model.DG,
                     model.G_x, model.G_restrct, model.X, model.Y, model.G_y],
                    feed_dict=feed)


                d_count += 1
                if d_count < 10:
                    pass
                elif d_loss_crr < 0.1 or d_count > 100:
                    start_dis = False
                    g_count = 0
                end = time.time()
                if (d_count %1 ==0):
                    print('Epoch:{}/{}..'.format(e + 1, epochs),
                          'Training Step:{}...'.format(counter),
                          'Discriminater loss:{:.4f}...'.format(d_loss_crr),
                          '{:.4f} sec/batch'.format((end - start)),
                          'd_count is {}'.format(d_count))

            else:
                _, g_loss_crr = sess.run([model.G_solver, model.Gloss],
                                         feed_dict=feed)

                g_count += 1
                if g_loss_crr < 1 or g_count > 100:
                    start_dis = True
                    d_count = 0
    saver.save(sess, 'checkpoints2/i{}.ckpt'.format(counter))

6,使用生成模型,进行验证码破解

使用生成的数据进行破解比较简单,就不细说了。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值