七貓中文網js逆向分析(acw_sc__v2參數分析)

2020-08-12 20:48:38

七貓中文網cookie acw_sc__v2參數分析

宣告:七貓中文網加密破解僅用於研究和學習使用

列表頁鏈接:https://www.qimao.com/shuku/a-a-a-a-a-a-a-click-1/

七貓中文網的反爬措施主要是cookie中的 acw_sc__v2參數, 如何確認是這個參數呢,首先清空瀏覽器中快取的關於七貓cookie資訊,重新請求
在这里插入图片描述
我們可以看到cookie中的資訊有這幾個, 我們來做個具體分析:
1、Hm_lpvt_*** 和 Hm_lvt_*** 這兩個是百度聯盟或者其他站做統計用的,我們不需要管
2、頁面的響應頭 set-cookie中有acw_tc 和 aliyungf_tc 這是伺服器端給我們返回來,不需要管
3、還剩下csrf-frontend、acw_sc__v2 和 HMACCOUNT_BFESS, 我們可以模擬請求測試,經測試發現只有acw_sc_v2是反爬用的

當然這裏還有個問題, 就是七貓在偵錯的時候會有無限debugger,我們需要跳過dehugger
在这里插入图片描述
在第三行前右鍵點選Add Conditional breakpoint 輸入break 回車繼續向下偵錯就可以了
在这里插入图片描述
跳過debugger後 當前鏈接返回的是一個包含js的html頁面, 可以直接的看到這裏向cookie中寫入了acw_sc__v2這個參數,然後reload()重新載入, 就可以進入正常的html頁面了
在这里插入图片描述
下面 下麪我們來逆向這個acw_sc__v2是如何生成的
在这里插入图片描述
可以看到的是reload呼叫的setCookie寫入的, 我們找下哪裏呼叫的reload直接進行搜尋,發現沒有搜尋到,我們可以看到好多都被編碼了,先解碼在搜尋,直接在網上找個js線上解碼的工具, 再次進行搜尋可以看到這裏呼叫reload(arg2)
在这里插入图片描述
通過Console對程式碼進行簡單還原_0x55f3(‘0x19’, ‘Pg54’)像這總就是混淆後的變數

var _0x23a392 = arg1["unsbox"]();
arg2 = _0x23a392["hexXor"](_0x5e8b26);
setTimeout(reload(arg2), 2);
// 經過多次偵錯發現 _0x23a392["hexXor"](_0x5e8b26);中_0x5e8b26是固定的爲3000176000856006061501533003690027800375

首先看第一行 var _0x23a392 = arg1"unsbox";
arg1在程式碼的第一行是寫固定的 第一次請求用正則匹配出來

var arg1 = 'F70819CD0285BF6E118357F3402F3F75C6F35182';

接下來我們需要找到unsbox函數, 通過設定斷點偵錯, 首先進入的這個韓素
在这里插入图片描述
我們將js進行還原, 這樣我們就能看懂了

String['prototype']['unsbox'] = function() {
                var _0x4b082b = [0xf, 0x23, 0x1d, 0x18, 0x21, 0x10, 0x1, 0x26, 0xa, 0x9, 0x13, 0x1f, 0x28, 0x1b, 0x16, 0x17, 0x19, 0xd, 0x6, 0xb, 0x27, 0x12, 0x14, 0x8, 0xe, 0x15, 0x20, 0x1a, 0x2, 0x1e, 0x7, 0x4, 0x11, 0x5, 0x3, 0x1c, 0x22, 0x25, 0xc, 0x24];
                var _0x4da0dc = [];
                var _0x12605e = '';
                for (var _0x20a7bf = 0; _0x20a7bf < this['length']; _0x20a7bf++) {
                    var _0x385ee3 = this[_0x20a7bf];
                    for (var _0x217721 = 0; _0x217721 < _0x4b082b['length']; _0x217721++) {
                        if (_0x4b082b[_0x217721] == _0x20a7bf + 1) {
                            _0x4da0dc[_0x217721] = _0x385ee3;
                        }
                    }
                }
                _0x12605e = _0x4da0dc['join']('');
                return _0x12605e;
            }
            ;

接下來使用python 進行重寫

import requests
import re

def get_unsbox(arg1):
	_0x4b082b = [0xf, 0x23, 0x1d, 0x18, 0x21, 0x10, 0x1, 0x26, 0xa, 0x9, 0x13, 0x1f, 0x28, 0x1b, 0x16, 0x17, 0x19, 0xd,
                 0x6, 0xb, 0x27, 0x12, 0x14, 0x8, 0xe, 0x15, 0x20, 0x1a, 0x2, 0x1e, 0x7, 0x4, 0x11, 0x5, 0x3, 0x1c,
                 0x22, 0x25, 0xc, 0x24]
    _0x4da0dc = []
    _0x12605e = ''
    for i in _0x4b082b:
        _0x4da0dc.append(arg1[i-1])
    _0x12605e = "".join(_0x4da0dc)
    return _0x12605e

# arg1 是第一次請求返回js中匹配出來的
headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"}
r = requests.get(url, headers=headers)
arg1 = re.findall("arg1=\'(.*?)\'", r.text)[0]

get_unsbox()

接下來看第二行 arg2 = _0x23a392[「hexXor」](_0x5e8b26); 繼續向下偵錯 進入了下面 下麪的js
在这里插入图片描述
一樣先進行還原, 快點拿到hexXor就知道我們找對了

String["prototype"]["hexXor"] = function(_0x4e08d8) {
            var _0x5a5d3b = '';
            for (var _0xe89588 = 0; _0xe89588 < this["length"] && _0xe89588 < _0x4e08d8["length"]; _0xe89588 += 2) {
                    var _0x401af1 = parseInt(this["slice"](_0xe89588, _0xe89588 + 2), 16);
                    var _0x105f59 = parseInt(_0x4e08d8["slice"](_0xe89588, _0xe89588 + 2), 16);
                    var _0x189e2c = (_0x401af1 ^ _0x105f59)["toString"](16);
                    if (_0x189e2c["length"] == 1) {
                        _0x189e2c = '0' + _0x189e2c;
                    }
                    _0x5a5d3b += _0x189e2c;
                }
                return _0x5a5d3b;
            }

使用python進行重寫

def get_hexxor(s1, _0x4e08d8):
    _0x5a5d3b = ''
    for i in range(len(s1)):
        if i % 2 != 0: continue
        _0x401af1 = int(s1[i: i+2], 16)
        _0x105f59 = int(_0x4e08d8[i: i+2], 16)
        _0x189e2c_10 = (_0x401af1 ^ _0x105f59)
        _0x189e2c = hex(_0x189e2c_10)[2:]
        if len(_0x189e2c) == 1:
            _0x189e2c = '0' + _0x189e2c
        _0x5a5d3b += _0x189e2c
    return _0x5a5d3b

# s1 爲 第一步get_unsbox()返回的值
# _0x4e08d8 爲固定的3000176000856006061501533003690027800375
# 該函數的返回值就是我們想要的arg2 

第三部就是reload(arg2)將該參數寫入cookie 重新請求

下面 下麪是全部程式碼

import requests
import re

url = "https://www.qimao.com/shuku/a-a-a-a-a-a-a-click-1/"

def get_hexxor(s1, _0x4e08d8):
    _0x5a5d3b = ''

    for i in range(len(s1)):
        if i % 2 != 0: continue
        _0x401af1 = int(s1[i: i+2], 16)
        _0x105f59 = int(_0x4e08d8[i: i+2], 16)
        _0x189e2c_10 = (_0x401af1 ^ _0x105f59)
        _0x189e2c = hex(_0x189e2c_10)[2:]
        if len(_0x189e2c) == 1:
            _0x189e2c = '0' + _0x189e2c
        _0x5a5d3b += _0x189e2c
    return _0x5a5d3b

def get_unsbox(arg1):
    _0x4b082b = [0xf, 0x23, 0x1d, 0x18, 0x21, 0x10, 0x1, 0x26, 0xa, 0x9, 0x13, 0x1f, 0x28, 0x1b, 0x16, 0x17, 0x19, 0xd,
                 0x6, 0xb, 0x27, 0x12, 0x14, 0x8, 0xe, 0x15, 0x20, 0x1a, 0x2, 0x1e, 0x7, 0x4, 0x11, 0x5, 0x3, 0x1c,
                 0x22, 0x25, 0xc, 0x24]
    _0x4da0dc = []
    _0x12605e = ''
    for i in _0x4b082b:
        _0x4da0dc.append(arg1[i-1])
    _0x12605e = "".join(_0x4da0dc)
    return _0x12605e


# 第一次請求獲取js程式碼
headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"}

r = requests.get(url, headers=headers)
# 重js中匹配出 arg1
arg1 = re.findall("arg1=\'(.*?)\'", r.text)[0]

# 參數生成
s1 = get_unsbox(arg1)
_0x4e08d8 = "3000176000856006061501533003690027800375"
_0x12605e = get_hexxor(s1, _0x4e08d8)

print(s1, _0x12605e)
# 二次請求攜帶cookie 獲取html檔案
headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36",
           "cookie": "acw_sc__v2=%s" % _0x12605e}

r = requests.get(url, headers=headers, proxies=proxy)
print(r.text)

結果:
在这里插入图片描述








坐得住板凳,耐得住寂寞,守得住初心!