使用R语言破解极验验证码:详细指南

一. 观察verify请求
首先,我们需要观察verify请求的Initiator,可以看到所有请求都来自于gcaptcha4.js这个文件,所以该文件是我们此次的目标所在。

打开gcaptcha4.js文件,格式化后,我们在13339行发现,代码经过混淆处理,这时候我们有两种选择:硬刚或者使用AST还原。我选择了AST还原JS文件,然后使用Chrome上的reres插件将混淆的JS替换掉,再一步步调试。AST还原代码已放在GitHub上,reres插件的安装和使用请自行搜索。

替换成功后,我们得到以下结果:

二. 定位w参数加密位置
搜索w参数,我们可以通过以下关键词定位:

w
.w
'w'
"w"
搜索"w"后,我们找到了目标,在2527行打上断点,可以看到w的值r在2525行定义,我们也在此打上断点,刷新页面,成功断上。至此,我们已完成w参数的加密位置定位。

三. 分析w参数加密算法
简化w的值r的定义:

javascript

var r = (0, d["default"])(l["default"]["stringify"](e), a)
等价于:

javascript

var r = d.default(l.default.stringify(e), a)
分析l.default.stringify(e)的含义:
可以看出此处是对e进行JSON序列化操作。

分析d.default(l.default.stringify(e), a)的含义:
跟进d函数,在几个条件判断处打上断点,调试后得出结论:

javascript

function a(e, t) {
    var n = c["guid"](), 
        a = new _["default"]()["encrypt"](n);
        o = i["default"]["encrypt"](e, n);
    return c["arrayToHex"](o) + a;
}
我们确定参数t并未使用,参数e即w的明文。继续分析JSON序列化前e的组成:

r

library(jsonlite)

e <- list(
  device_id = "A8A0",
  em = list(
    cp = 0,
    ek = "11",
    nt = 0,
    ph = 0,
    sc = 0,
    si = 0,
    wd = 1
  ),
  ep = "123",
  geetest = "captcha",
  fq6a = "1925502591",
  lang = "zh",
  lot_number = "7e22264d4f3e4dd8a6ffbf6e82e1122d",
  passtime = 166,
  pow_msg = "",
  pow_sign = "",
  setLeft = 88,
  track = list(c(38, 18, 0), c(1, 0, 33)),
  userresponse = 87.47978686742837
)
四. 分析pow_msg和pow_sign
搜索pow_msg,打上断点,刷新,保留成功断上的断点:

r

u <- paste(n, a, s, o, t, e, r, sep = "|")
p <- generate_guid()
g <- paste(u, p, sep = "")
pow_msg <- g
pow_sign <- digest::digest(g, algo = "md5")
我们需要分析generate_guid算法:

r

generate_guid <- function() {
  guid <- paste0(sample(c(0:9, letters), 4, replace = TRUE), collapse = "")
  return(paste0(guid, guid, guid, guid))
}
五. 分析set_left、track、passtime、userresponse
set_left为滑块移动距离取整。
track为移动轨迹,从第二步开始,是上一步的相对移动距离(x, y, t)。
passtime为总移动时间。
userresponse为set_left / (0.8876 * 340 / 300)。
至此,我们已将w的明文分析完毕。以下是R实现代码:

六. 代码实现
r

library(jsonlite)
library(digest)

generate_guid <- function() {
  guid <- paste0(sample(c(0:9, letters), 4, replace = TRUE), collapse = "")
  return(paste0(guid, guid, guid, guid))
}

generate_w_params <- function() {
  device_id <- "A8A0"
  em <- list(cp = 0, ek = "11", nt = 0, ph = 0, sc = 0, si = 0, wd = 1)
  ep <- "123"
  geetest <- "captcha"
  fq6a <- "1925502591"
  lang <- "zh"
  lot_number <- "7e22264d4f3e4dd8a6ffbf6e82e1122d"
  passtime <- 166
  set_left <- 88
  track <- list(c(38, 18, 0), c(1, 0, 33))
  userresponse <- set_left / (0.8876 * 340 / 300)
  
  guid <- generate_guid()
  u <- paste(lot_number, guid, sep = "|")
  p <- generate_guid()
  g <- paste(u, p, sep = "")
  pow_msg <- g
  pow_sign <- digest(g, algo = "md5")
  
  e <- list(
    device_id = device_id,
    em = em,
    ep = ep,
    geetest = geetest,
    fq6a = fq6a,
    lang = lang,
    lot_number = lot_number,
    passtime = passtime,
    pow_msg = pow_msg,
    pow_sign = pow_sign,
    setLeft = set_left,
    track = track,
    userresponse = userresponse
  )
  
  return(toJSON(e, auto_unbox = TRUE))
}

w_params <- generate_w_params()
print(w_params)

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值