爬虫逆向之360磐云盾案例(某政府网站)

本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!

此文章重在学习调试技巧。模拟参数生成。

今日遇到一个新的安全产品网站,名字都没听说过,后来去了解,发现这产品叫360磐云盾,整体难度不算难。花了差不多两小时就搞定了。(同样是安全产品,为什么阿里滑块那么难!!!)

目标网站:aHR0cHM6Ly93d3cubHVvamlhbmcuZ292LmNuL2luZm8vaUxpc3QuanNwP2NhdF9pZD0yNDE3NyZjdXJfcGFnZT0x

安全产品介绍:aHR0cHM6Ly9iLjM2MC5uZXQvcHJvZHVjdC1jZW50ZXIvMzYwLW5ldC1zYWZlL3Bhbi15dW4=

关键词:

PYCCS ,answer,PYCCV,重定向,异步

逆向思路

网页加载频繁会有这样特征

同一个数据接口会加载三次

第一次请求得出JS文件

并且第一段会响应PYCCV

第二次请求特征,重定向

关键参数answer,由第一次请求里的JS文件获得而来,也是唯一难点

第三次请求携带answer和PYCCVcookies成功获取最终cookies

实操

首先第一次请求获取JS代码。

获取规整的JS代码并报$未定义

接下来把规整的代码扣下来去问ai,chatgpt、claude、deepseek

以下是deepseek的回答:

我们有一段被混淆的JavaScript代码,它使用了十六进制转义序列和变量名混淆。我们将逐步解码并理解这段代码。

首先,我们可以将代码进行格式化,并尝试将十六进制转义序列转换为可读的字符串。

注意:代码开头有一个变量 _$,它是一个包含三个字符串的数组,这些字符串是用十六进制表示的。我们可以将它们转换为ASCII字符串。

转换方法:将每个十六进制序列去掉\x,然后作为ASCII码解析。

例如:

'\x23\x63\x68\x61\x6c\x6c\x65\x6e\x67\x65'

23 -> '#',63->'c', 68->'h', 61->'a', 6c->'l', 6c->'l', 65->'e', 6e->'n', 67->'g', 65->'e'

所以第一个字符串是 "#challenge"

同样,第二个字符串:'\x23\x77\x61\x66\x5f\x61\x6e\x73\x77\x65\x72'

23->'#', 77->'w', 61->'a', 66->'f', 5f->'_', 61->'a', 6e->'n', 73->'s', 77->'w', 65->'e', 72->'r'

所以是 "#waf_answer"

第三个字符串:'\x23\x43\x68\x61\x6c\x6c\x65\x6e\x67\x65\x46\x6f\x72\x6d'

23->'#', 43->'C', 68->'h', 61->'a', 6c->'l', 6c->'l', 65->'e', 6e->'n', 67->'g', 65->'e', 46->'F', 6f->'o', 72->'r', 6d->'m'

所以是 "#ChallengeForm"

因此,数组_$实际上是:

_$ = ['#challenge', '#waf_answer', '#ChallengeForm']

然后,代码:

(_[0])"show"; -> $('#challenge').show();

接下来,是一个jQuery的文档就绪函数:

$(function(){ ... });

在这个函数中,设置了一个超时,延迟1000毫秒(0x3e8=1000)执行。

超时函数内部:

定义了一个空对象x06dd1a,变量x0fcad9,以及x08c924初始化为0x61(即97)。

然后获取navigator.userAgent并转换为小写。

然后进行一系列正则表达式匹配,以检测浏览器类型和版本,并将版本号存入x06dd1a对象。

之后,对x08c924进行一系列算术运算,并根据条件调整值。

最后,如果检测到任意一种浏览器,则继续计算x08c924,然后将其值设置到id为#waf_answer的输入框中,并提交表单#ChallengeForm。

具体步骤:

x08c924初始值:97

x08c924 = x08c924 * 0x31 (49) -> 97*49=4753

然后根据浏览器类型,x06dd1a会设置相应的属性,但不管设置什么,都会进入后面的条件判断。

如果检测到浏览器(即x06dd1a有任意一个属性被设置),则:

x08c924 = (x08c924 * 3 + 7) -> (4753*3+7)=14266

如果x08c924 < 123 (0x7b),则加上0x929(2345),但14266不小于123,所以不加。

然后,获取#waf_answer元素(即x0b515d)

如果x08c924 > 0x929(2345),则x08c924 = Math.floor(x08c924 / 0x7b) -> Math.floor(14266/123) = 115(因为123*115=14145,14266-14145=121,所以为115)

text

复制代码
    然后将x08c924的值设置到#waf_answer输入框,并提交表单。

所以,这段代码的目的是:

显示一个id为#challenge的元素,然后在1秒后,根据用户代理字符串计算一个值(115),并将这个值填入id为#waf_answer的输入框,然后自动提交id为#ChallengeForm的表单。

注意:这个计算过程与浏览器类型无关(因为不管什么浏览器,只要被识别,都会进行计算,而且计算过程中浏览器版本并没有被使用,只是检测了浏览器类型),最终结果都是115。

因此,这段代码可能是一个简单的反爬虫机制,通过计算一个固定的值来验证请求,但这里计算的值是固定的,所以可能只是一个简单的挑战。

由此可见x08c924这个就是answer,也是我们要求,并且这是个定时器,要异步去获取参数。

缺$直接控制台输出

也就是在https://www.360panyun.net/__panyun/jquery-1.4.2.min.js文件里

我采取全扣代码,然后导出函数为例.这个环境非常好补。(可以利用ai进行纯算,或者扣代码也行)

补好了直接导出即可

现在就是如何调用这个JS文件了

因为是异步的,所以直接输出,用subprocess调用

直接获取eval包括,输出不了这个值(也行有其他方法)。

所以只能利用文件存储和正则了

先获取eval里面的JS,不包括eval()

让它赋值给自己定义的参数aaaa

这样子

输出的就是规则的代码了

然后调用aaaba获取规整的JS代码

因为规则JS代码没有输出x08c924,

所以找特征进行替换,

这里是一直不变的,用replace替换,

接着把环境和网页JS文件和已还原的规则代码直接塞入一个新的JS文件里,文件写入类型为覆盖

然后用异步调用。

注意点:

记住第二个接口是重定向302,要设置allow_redirects=False,让它不跳转其它接口,跳转其它接口拿的是其它接口的cookie,跟正确的cookies无关。

输出结果

附nodeJS环境

javascript 复制代码
html = {}
fieldset = {}
implementation = {}
form = {}
body = {}
body.childNodes = function (args) {
    return [form.form]
}
body.body = body
implementation.createHTMLDocument = function (args) {

    return body
}
select = {}
option = {}
a = {}
a.href = 'https:'
option.selected = true
select.appendChild = function (args) {


}
div = {}
div.appendChild = function (args) {

}

input = {}
input.setAttribute = function (args, b) {


}
fieldset.getAttribute = function (args) {

    if (args == 'disabled') {
        return null
    }
}
window = globalThis
window.jQuery = function (args) {
    console.log(args)
}
Node = function Node() {
}
Document = function Document() {
}
HTMLDocument = function HTMLDocument() {
}
Object.setPrototypeOf(Document.prototype, Node.prototype)
Object.setPrototypeOf(HTMLDocument.prototype, Document.prototype)
document = new HTMLDocument()
Node.prototype.nodeType = 9
Document.prototype.documentElement = html
Document.prototype.implementation = implementation
Document.prototype.createElement = function createElement(args) {

    if (args == 'fieldset')
        return fieldset
    if (args == 'input')
        return input
    if (args == "div")
        return div
    if (args == "select")
        return select
    if (args == "option")
        return option
    if (args == "a")
        return a
}
Document.prototype.getElementById = function getElementById(args) {

    if (args == 'waf_answer')
        debugger
    if (args == 'fieldset')
        return fieldset
    if (args == 'input')
        return input
    if (args == "div")
        return div
    if (args == "select")
        return select
    if (args == "option")
        return option
    if (args == "a")
        return a
}
Document.prototype.createDocumentFragment = function createElement(args) {

    return {
        appendChild: function (args) {

            return {
                appendChild: function (args) {

                    return {
                        setAttribute: function setAttribute(args) {

                        }
                    }
                }
            }
        }
    }
}
Navigator = function Navigator() {
}
Navigator.prototype.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"

navigator = new Navigator()
window.navigator = navigator

class Location {
    constructor() {
        this.Symbol = "Location"
    }

}


location = new Location()
location.href = "https:"
location.ancestorOrigins = {}
location.origin = "https:"
location.protocol = "https:"
location.host = "",
    location.hostname = ""

window.location = location

这安全产品太简单了,同样是安全产品,为什么这这么简单。哎,最近想写一篇阿里滑块V2文章加深印象,但是不知道从何写起,虽然已经搞定了,但还是会想起被支配的恐惧,不想跟栈第二次了。有时间有灵感就写吧。

相关推荐
裤裤兔3 小时前
python爬取pdf文件并保存至本地
chrome·爬虫·python·pdf·网络爬虫
beijingliushao3 小时前
96-爬虫XPath解析
爬虫
beijingliushao4 小时前
95-Python爬虫-正则表达式
爬虫·python·正则表达式
百***06014 小时前
python爬虫——爬取全年天气数据并做可视化分析
开发语言·爬虫·python
interception5 小时前
爬虫逆向:websocket实战案例,全国建筑市场
爬虫·websocket·网络协议
q***31899 小时前
爬虫基础之爬取某基金网站+数据分析
爬虫·数据挖掘·数据分析
ycydynq19 小时前
自动化爬虫selenium
爬虫·selenium·自动化
sanggou21 小时前
【Python爬虫】手把手教你从零开始写爬虫,小白也能轻松学会!(附完整源码)
开发语言·爬虫·python
全栈陈序员1 天前
基于Rust 实现的豆瓣电影 Top250 爬虫项目
开发语言·爬虫·rust