使用Kotlin破解gcaptcha4.js中的w参数加密算法


在本文中,我们将介绍如何使用Kotlin来逆向工程gcaptcha4.js文件,找到并破解w参数的加密算法。整个过程包括观察verify请求,定位加密位置,分析加密算法,并最终还原w参数的明文。

一. 观察verify请求
首先,我们需要观察verify请求的发起者。通过网络请求分析工具,我们可以看到所有verify请求都来自于gcaptcha4.js文件。因此,这个文件成为我们分析的重点。

我们使用Kotlin的OkHttp库来捕获和分析这些请求。

kotlin

import okhttp3.OkHttpClient
import okhttp3.Request

fun main() {
    val client = OkHttpClient()
    val request = Request.Builder()
        .url("https://example.com/verify")
        .build()

    client.newCall(request).execute().use { response ->
        if (!response.isSuccessful) throw IOException("Unexpected code $response")
        println(response.body?.string())
    }
}
通过分析响应内容,可以发现所有的verify请求都指向了gcaptcha4.js文件。

二. 定位w参数加密位置
为了找到w参数的加密位置,我们需要解析gcaptcha4.js文件。我们可以下载并格式化这个文件,然后使用正则表达式搜索关键词:w、.w、'w'或"w"。

kotlin

import java.io.File
import java.util.regex.Pattern

fun main() {
    val file = File("gcaptcha4.js")
    val content = file.readText()
    val regex = Pattern.compile("[.\\'\"]w[.\\'\"]")
    val matcher = regex.matcher(content)

    while (matcher.find()) {
        println(matcher.group())
    }
}
通过搜索"w",我们找到了相关代码。在第2527行,我们发现了w的值r在第2525行被定义。

三. 分析w参数加密算法
接下来,我们需要简化代码中w的定义。假设我们已经提取了相关的JavaScript代码,我们可以使用Kotlin来模拟这个过程。

kotlin

import com.google.gson.Gson
import java.security.MessageDigest

data class Em(
    val cp: Int,
    val ek: String,
    val nt: Int,
    val ph: Int,
    val sc: Int,
    val si: Int,
    val wd: Int
)

data class RequestData(
    val device_id: String,
    val em: Em,
    val ep: String,
    val geetest: String,
    val fq6a: String,
    val lang: String,
    val lot_number: String,
    val passtime: Int,
    val pow_msg: String,
    val pow_sign: String,
    val setLeft: Int,
    val track: List<List<Int>>,
    val userresponse: Double
)

fun toJson(data: Any): String {
    return Gson().toJson(data)
}

fun md5(input: String): String {
    val bytes = MessageDigest.getInstance("MD5").digest(input.toByteArray())
    return bytes.joinToString("") { "%02x".format(it) }
}

fun main() {
    val e = RequestData(
        device_id = "A8A0",
        em = Em(
            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 = "1|0|md5|2022-03-25T14:23:36.364152+08:00|24f56dc13c40dc4a02fd0318567caef5|7e22264d4f3e4dd8a6ffbf6e82e1122d||29f07cebf938aa4e",
        pow_sign = "2b47a3a9425dd19dd5abf902c8bb0763",
        setLeft = 88,
        track = listOf(listOf(38, 18, 0), listOf(1, 0, 33)),
        userresponse = 87.47978686742837
    )

    val a = "your_key"
    val r = md5(toJson(e) + a)
    println(r)
}
4.1 分析pow_msg和pow_sign
通过搜索pow_msg,我们找到相关代码并解析如下:

kotlin

import java.security.MessageDigest
import kotlin.random.Random

fun generateGuid(): String {
    return (1..4).joinToString("") { "%04x".format(Random.nextInt(0, 65536)) }
}

fun md5Hash(input: String): String {
    val bytes = MessageDigest.getInstance("MD5").digest(input.toByteArray())
    return bytes.joinToString("") { "%02x".format(it) }
}

fun main() {
    val n = "example_n"
    val a = "example_a"
    val s = "example_s"
    val o = "example_o"
    val t = "example_t"
    val e = "example_e"
    val r = "example_r"

    val u = "$n|$a|$s|$o|$t|$e|$r|"
    val p = generateGuid()
    val g = u + p
    val powMsg = u + p
    val powSign = md5Hash(g)

    println("pow_msg: $powMsg")
    println("pow_sign: $powSign")
}

main()
4.2 分析set_left、track、passtime、userresponse
set_left:滑块移动距离的整数值
track:移动轨迹,从第二步开始,是相对上一步的相对移动距离(x, y, t)
passtime:总移动时间
userresponse:计算公式为set_left / (0.8876 * 340 / 300)
kotlin

fun main() {
    val setLeft = 88
    val track = listOf(listOf(38, 18, 0), listOf(1, 0, 33))
    val passtime = 166
    val userResponse = setLeft / (0.8876 * 340 / 300)

    println("set_left: $setLeft")
    println("track: $track")
    println("passtime: $passtime")
    println("userresponse: $userResponse")
}

main()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值