某网站返回数据加密的还原

逆向的网站:aHR0cHM6Ly93d3cucWltaW5ncGlhbi5jbi9maW5vc2RhL3Byb2plY3QvcGludmVzdG1lbnQ=

需要抓取的数据如下:

某网站返回数据加密的还原_第1张图片

1. 观察请求

        打开控制台,输入网址并回车。在DOC模块下返回的html源码中,没有找到我们需要的数据,返回的数据大概率是通过ajax返回的。

        在XHR模块下发现以下两个接口:

某网站返回数据加密的还原_第2张图片

        并且这两个接口返回的数据都是加密后的数据,如下:

某网站返回数据加密的还原_第3张图片

        由此分析,`encrypt_data` 里边包含的则是我们需要的数据,只不过被加密了,我们看不到正常的明文数据。接下来我们要做的就是把这些密文数据,通过分析它的加密逻辑,把它的明文数据给还原出来。

2. 定位 `encrypt_data`

        通过搜索关键字 `encrypt_data`,只有一个js文件:
某网站返回数据加密的还原_第4张图片        点击进去改js文件,并点击页面左下角中的 `{}` 符号,格式化js代码:

某网站返回数据加密的还原_第5张图片

        并在格式化之后的js文件中,搜索 `encrypt_data` 关键字,共有六处地方包含该关键字:

某网站返回数据加密的还原_第6张图片

        并且通过观察这六处代码,发现只有一处比较可疑,并在此处打上断点

某网站返回数据加密的还原_第7张图片        重新刷新该页面,发现断点生效,说明我们分析的地方是正确的,该断点就是我们需要分析的地方: 

某网站返回数据加密的还原_第8张图片3. 定位加密入口

        在 `Object(d.a)` 处再下一个断点,并点击单步调试按钮:某网站返回数据加密的还原_第9张图片

        最终会走到 `s(e)` 这个函数,并且该函数的参数e,就是加密后的数据 `encrypt_data`。

        我们在控制台输出 `s(e)`,输出的结果是明文的,不再是密文的,说明 `s(e)` 这个函数是解密的入口。

某网站返回数据加密的还原_第10张图片4. 分析 s(e) 函数的逻辑,并构造js代码

        该函数通过调用函数 o ,并往函数 o 中传递六个参数,其中 除了 `a.a.decode(e)` 是需要进一步 分析的以外,其他的五个都是定值。最后通过 JSON.parse 把函数 o 的返回值转化为 json对象。分析到这里之后,我们就可以构造大体的js逻辑了,如下:

function s(e) {
    return JSON.parse(o("5e5062e82f15fe4ca9d24bc5", decode(e), 0, 0, "012345677890123", 1))
}

// encrypt_data 就是接口返回到密文数据
var encrypt_data = "字符串太长了,自行去复制encrypt_data粘贴到此处"

decrypt_data = s(encrypt_data)

        该代码中,函数 o 还没有定义,函数 o 的定义和函数 s(e) 在同级目录,往上翻就能看到,把函数 o 全部复制下来,放入到我们自己构造的js代码中去:

某网站返回数据加密的还原_第11张图片

        函数 o 搞定之后,就只剩 `a.a.decode(e)` 参数了,在以下地方打上断点:

某网站返回数据加密的还原_第12张图片         并点击单步调试按钮,会看到以下这个函数:

某网站返回数据加密的还原_第13张图片

        把该函数全部复制下来,放入我们构造到js代码中。

5. 补全js运行环境

        通过第四步,我们已经构造完毕js文件,通过node环境运行该js文件,会发现以下错误:

ReferenceError: f is not defined
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
    at internal/main/run_main_module.js:17:47

        提示 f 未定义,通过报错,我们定位到 f 在decode函数中被调用:

某网站返回数据加密的还原_第14张图片

        并且我们能找到定义 f 的地方,如下:

某网站返回数据加密的还原_第15张图片

        f 为定值,补全 f 之后,再次运行js代码,又发现以下错误:

ReferenceError: c is not defined
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
    at internal/main/run_main_module.js:17:47

         提示 c 未定义,并且在定义 f 的上方,也能找到 c 的声明。补全 c 之后,再次运行js代码,结果正常: 

6. 总结

        该网站还是比较简单,比较适合新手用来练手,初步用来了解逆向的过程。

ps: 最后,该项目的源码已提交至 GitHub 中,需要可自取。

你可能感兴趣的:(js逆向,python爬虫)