破解极验滑动验证码的完整指南

极验验证码是一种常见的防爬虫机制,通过滑动拼图等方式验证用户的人机身份。本文将介绍如何使用Go语言破解极验滑动验证码,模拟验证过程并绕过验证码。

准备工作
首先,确保你已经安装了Go语言开发环境。如果没有,请从Go官方网站下载安装。

分析验证码请求
在破解验证码之前,我们需要分析极验验证码在验证过程中发起的请求。通过观察,可以发现这些请求中的一些关键参数:

gt 和 challenge:用于标识验证码会话。
w:这是一个加密过的数据,破解的核心就在于解密并伪造这个参数。
获取核心JS文件链接
我们首先获取核心JS文件的链接,以便分析其中的加密逻辑。

go

package main

import (
    "fmt"
    "net/http"
    "regexp"
    "io/ioutil"
    "log"
)

func getJsLink() (string, error) {
    resp, err := http.Get("https://example.com/gettype.php")
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }

    return parseJsLink(string(body)), nil
}

func parseJsLink(body string) string {
    re := regexp.MustCompile(`https://.*?\.js`)
    match := re.FindString(body)
    return match
}

func main() {
    jsLink, err := getJsLink()
    if err != nil {
        log.Fatalf("Failed to get JS link: %v", err)
    }
    fmt.Println("JS Link:", jsLink)
}
获取无感验证参数
通过请求get.php获取无感验证的参数,包括c和s。

go

package main

import (
    "fmt"
    "net/http"
    "regexp"
    "io/ioutil"
    "log"
)

func getNoSenseParams() (string, string, error) {
    resp, err := http.Get("https://example.com/get.php")
    if err != nil {
        return "", "", err
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return "", "", err
    }

    return parseNoSenseParams(string(body)), nil
}

func parseNoSenseParams(body string) (string, string) {
    cRe := regexp.MustCompile(`"c":"(.*?)"`)
    sRe := regexp.MustCompile(`"s":"(.*?)"`)

    cMatch := cRe.FindStringSubmatch(body)
    sMatch := sRe.FindStringSubmatch(body)

    c := ""
    if len(cMatch) > 1 {
        c = cMatch[1]
    }

    s := ""
    if len(sMatch) > 1 {
        s = sMatch[1]
    }

    return c, s
}

func main() {
    c, s, err := getNoSenseParams()
    if err != nil {
        log.Fatalf("Failed to get no-sense params: %v", err)
    }
    fmt.Printf("c: %s, s: %s\n", c, s)
}
执行无感验证
通过请求ajax.php执行无感验证,如果验证失败,会返回滑块验证等其他类型的验证。

go

package main

import (
    "fmt"
    "net/http"
    "regexp"
    "io/ioutil"
    "log"
)

func executeNoSenseVerification(c, s string) (string, error) {
    url := fmt.Sprintf("https://example.com/ajax.php?c=%s&s=%s", c, s)
    resp, err := http.Get(url)
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }

    return parseVerificationType(string(body)), nil
}

func parseVerificationType(body string) string {
    re := regexp.MustCompile(`"type":"(.*?)"`)
    match := re.FindStringSubmatch(body)
    if len(match) > 1 {
        return match[1]
    }
    return ""
}

func main() {
    c, s, err := getNoSenseParams()
    if err != nil {
        log.Fatalf("Failed to get no-sense params: %v", err)
    }

    verificationType, err := executeNoSenseVerification(c, s)
    if err != nil {
        log.Fatalf("Failed to execute no-sense verification: %v", err)
    }
    fmt.Println("Verification Type:", verificationType)
}
进行滑动验证
当无感验证失败时,进行滑动验证。通过请求get.php获取滑动验证的基本数据,如bg、fullbg、slice等。

go

package main

import (
    "fmt"
    "net/http"
    "regexp"
    "io/ioutil"
    "log"
)

func getSlideParams() (map[string]string, error) {
    resp, err := http.Get("https://example.com/get.php?slide=true")
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return nil, err
    }

    return parseSlideParams(string(body)), nil
}

func parseSlideParams(body string) map[string]string {
    re := regexp.MustCompile(`"(\w+)":"(.*?)"`)
    matches := re.FindAllStringSubmatch(body, -1)

    params := make(map[string]string)
    for _, match := range matches {
        if len(match) > 2 {
            params[match[1]] = match[2]
        }
    }

    return params
}

func main() {
    slideParams, err := getSlideParams()
    if err != nil {
        log.Fatalf("Failed to get slide params: %v", err)
    }

    for key, value := range slideParams {
        fmt.Printf("%s: %s\n", key, value)
    }
}
破解w参数
在Go语言中实现w参数的破解过程,包括生成u和h参数。

生成u参数
u参数的生成涉及一个随机数和加密操作。

go

package main

import (
    "crypto/rand"
    "encoding/hex"
    "fmt"
    "log"
)

func getU() (string, error) {
    bytes := make([]byte, 16)
    if _, err := rand.Read(bytes); err != nil {
        return "", err
    }
    return hex.EncodeToString(bytes), nil
}

func main() {
    u, err := getU()
    if err != nil {
        log.Fatalf("Failed to generate U: %v", err)
    }
    fmt.Println("U:", u)
}
生成h参数
h参数的生成过程复杂一些,需要依赖多个函数。

go

package main

import (
    "fmt"
    "crypto/sha256"
    "encoding/hex"
)

func getH(parameters map[string]string) string {
    // 假设生成h参数的逻辑如下
    data := parameters["key1"] + parameters["key2"] // 示例拼接
    hash := sha256.Sum256([]byte(data))
    return hex.EncodeToString(hash[:])
}

func main() {
    parameters := map[string]string{
        "key1": "value1",
        "key2": "value2",
    }
    h := getH(parameters)
    fmt.Println("H:", h)
}
合并u和h参数
最后,将u和h参数合并生成最终的w参数。

go

package main

import (
    "crypto/rand"
    "crypto/sha256"
    "encoding/hex"
    "fmt"
    "log"
)

func getU() (string, error) {
    bytes := make([]byte, 16)
    if _, err := rand.Read(bytes); err != nil {
        return "", err
    }
    return hex.EncodeToString(bytes), nil
}

func getH(parameters map[string]string) string {
    data := parameters["key1"] + parameters["key2"] // 示例拼接
    hash := sha256.Sum256([]byte(data))
    return hex.EncodeToString(hash[:])
}

func generateW(parameters map[string]string) (string, error) {
    u, err := getU()
    if err != nil {
        return "", err
    }
    h := getH(parameters)
    return u + h, nil
}

func main() {
    parameters := map[string]string{
        "key1": "value1",
        "key2": "value2",
    }
    w, err := generateW(parameters)
    if err != nil {
        log.Fatalf("Failed to generate W: %v", err)
    }
    fmt.Println("W:", w)
}
发送滑动验证请求
有了w参数后,我们可以构造滑动验证的请求并发送。

go

package main

import (
    "fmt"
    "net/http"
    "regexp"
    "io/ioutil"
    "log"
)

func executeSlideVerification(w string) (string, error) {
    url := fmt.Sprintf("https://example.com/ajax.php?w=%s", w)
    resp, err := http.Get(url)
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }

    return parseVerificationResult(string(body)), nil
}

func parseVerificationResult(body string) string {
    re := regexp.MustCompile(`"result":"(.*?)"`)
    match := re.FindStringSubmatch(body)
    if len(match) > 1 {
        return match[1]
    }
    return ""
}

func main() {
    parameters := map[string]string{
        "key1": "value1",
        "key2": "value2",
    }
    w, err := generateW(parameters)
    if err != nil {
        log.Fatalf("Failed to generate W: %v", err)
    }

    result, err := executeSlideVerification(w)
    if err != nil {
        log.Fatalf("Failed to execute slide verification: %v", err)
    }
    fmt.Println("Verification Result:", result)
}

  • 19
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值