顶象

补环境代码

示例网站地址

https://www.dingxiang-inc.com/business/captcha

大体流程的实现步骤

  • 下载bg图与icon图;

  • 还原bg图;

  • 使用icon图匹配bg图缺口位置,获得坐标;

  • 模拟请求参数,获取返回信息

混淆图片还原的js代码

function e(n, i) {
    for (var e = [2, 1, 0], t = 0; ; ) {
        switch (e[t++]) {
        case 0:
            return !1;
        case 1:
            for (var r = 0, o = n.length; r < o; r++)
                if (n[r] === i)
                    return !0;
            continue;
        case 2:
            if (n.includes)
                return n.includes(i);
            continue
        }
        break
    }
}
function t(n) {
    if (!n)
        return "";
    for (var i = "", e = "V587", t = 49698, r = 0; r < n.length; r++) {
        var o = n.charCodeAt(r);
        o ^= e.charCodeAt(t = (t + 1) % 4),
        i += String.fromCharCode(o)
    }
    return i
}

get_ranges = function(n){
    for (var i = [], r = 0; r < n.length; r++) {
        var o = n.charCodeAt(r);
        if (32 === r)
            break;
        for (; e(i, o % 32); )
            o++;
        i["push"](o % 32)
    }
    return i
}

ccc = get_ranges("9e41db87fce54d1c8bb92952311114a3")
console.log(ccc)

window=this;
location={
    href:"https://www.dingxiang-inc.com/business/captcha",
}
navigator={
    userAgent:"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
    platform: "Win32",
}
document={
    "referrer":"https://www.dingxiang-inc.com/",
    "documentElement":{
        "doScroll":undefined,
        "getAttribute":function(arg){return null}
    },
    "getElementsByTagName":function(arg){return {"0":{},"1":{},"2":{},"3":{},"4":{},"5":{},"6":{},"7":{},"8":{}}}
}

var screen = function () {
}
screen.prototype.width = 1920;
screen.prototype.height = 1080;
screen.prototype.availWidth = 1920;
screen.prototype.availHeight = 1040;
screen.prototype.colorDepth = 24;
window.screen = new screen();



// ####################
// 最新的greenseer.js的代码

// ###########################################
function slide_track(distance) {
    function __ease_out_expo(sep) {
        if (sep == 1) {
            return 1
        } else {
            return 1 - Math.pow(2, -10 * sep)
        }
    }
 
    function random_randint(min, max) {
        var range = max - min;
        var rand = Math.random();
        var num = min + Math.round(rand * range);
        return num;
    }
 
    var slide_track = [
        [400, 500, 3500]
    ]
    var count = 30 + parseInt(distance / 2)
    var t = random_randint(50, 100)
    var _x = 0,
        _y = 0
    for (i = 0; i < count; i++) {
        var x = Math.round(__ease_out_expo(i / count) * distance)
        var t = t + random_randint(30, 50)
        if (x == _x) {
            continue
        }
        slide_track.push([400 + x, 500 + _y, 3500 + t])
        _x = x
    }
    return slide_track
}

function get_ac(sid,xdistance,ydistance){
    mousemove=slide_track(xdistance)
    console.log(window._dx)
    console.log(mousemove)
    xxx=window._dx['UA']['init']({})
    xxx.__proto__.ua=""
    xxx.__proto__._ua=[]
    xxx.__proto__.option={
       "token":sid,
       "form":""
    }
    console.log("sid",sid)
    xxx.__proto__.getTK()
    xxx.__proto__._sa=[]
    for(i=0;i<mousemove.length;i++){
        xxx.__proto__.tm=new Date().getTime()-mousemove[i][2]
        xxx.__proto__.recordSA({"pageX":mousemove[i][0],"pageY":mousemove[i][1]})
    }
    xxx.__proto__.sendSA()
    xxx.__proto__.sendTemp({              
        "xpath": "/html/body/div[10]",
        "x": xdistance,
        "y": ydistance
    })
    return xxx.__proto__.ua
}
console.log(get_ac("6c441f0c6299d10f36befe3e0f7d29ac",207,69));

python调用补环境的js代码

import cv2
from io import BytesIO
from PIL import Image
import numpy as np
import requests

from pprint import pprint

debug = True

def ar(r):
    """ 生成数组的字符串 """
    t = []
    for n in range(len(r)):
        e = ord(r[n])
        if 32 == n:
            break
        while e % 32 in t:
            e += 1
        t.append(e % 32)
    return t

def img_recover(location_array, img_url):
    """ 图片拼合 """
    img = np.array(Image.open(
        BytesIO(requests.get(url=img_url, verify=False).content)))
    new_img = np.zeros((200, 400, 3), dtype=np.uint8)
    lk = len(location_array)
    ck = int(400 / lk)
    for cp in range(lk):
        c = location_array[cp] % lk * ck
        xp = cp % lk * ck
        slice_img = img[0: 200, c: c + ck]
        new_img[0: 200, xp:xp + len(slice_img[0])] = slice_img
    # print(new_img)
    return new_img

def show(image_path):
    import os
    print(image_path)
    # if isinstance(image_path,np.array):
    #     image_base = image_path
    # else:
    #     image_base = cv2.imread(image_path)
    image_base = cv2.imread(image_path)
    print(image_path, image_base.shape[0:2])
    cv2.imshow('Show', image_base)
    key = cv2.waitKey(0)
    if key & 0xFF == ord("q"):
        import sys
        cv2.destroyAllWindows()
        sys.exit()
    else:
        cv2.destroyAllWindows()

def get_distance(bg_path, tg_path):
    # 下载背景图和滑块图
    background_image_path = bg_path
    slider_image_path = tg_path
    template_base = cv2.imread(background_image_path)
    target = cv2.imread(slider_image_path, 0)
    template = cv2.imread(background_image_path, 0)
    w, h = target.shape[::-1]
    target = abs(255 - target)
    result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
    x, y = np.unravel_index(result.argmax(), result.shape)

    # 展示圈出来的区域
    if debug:
        # 图片左上角的点
        p1 = (y, x)
        # 图片右下角的点
        p2 = (y + h, x + w)
        # 图片的中心点
        # p_c = (int(y+h/2), int(x+w/2))
        cv2.rectangle(template_base, p1, p2, (100, 225, 100), 2)
        point_size = 1
        point_color = (0, 0, 255)  # BGR
        thickness = 4
        cv2.circle(template_base, p1, point_size,
                   point_color, thickness)
        result_path = "result.png"
        cv2.imwrite(result_path, template_base)
        show(result_path)
    return int(y)

def run():
    import time
    print(time.time())
    aid = 'dx-{}-27682978-3'.format(str(int(time.time()*1000)))
    ak = "99de95ad1f23597c23b3558d932ded3c"
    cc = "6554343aU0MT73yU0M2yQGgeDMa2Xtr12D7gEwc1"
    cid = "16304958"
    jsv = "6.0.0"
    print(aid)
    url_path = "https://cap.dingxiang-inc.com/api/a?"
    params_dict = {'_r': '0.9521698022950165',
                   'aid': aid,
                   'ak': ak,
                   'c': cc,
                   'cid': cid,
                   'de': '0',
                   'h': '165',
                   'jsv': jsv,
                   'lf': '0',
                   's': '50',
                   't': '4085B077824270AF7C665701763BFA18C748A3283E9ACCA1724373867844D826952CCDC8EB47F07D7958263F41DA328D128C9048C4EC473C5234B94E2C91141251078D38364B124318D48FF8275487BE',
                   'tpc': '',
                   'uid': '',
                   'w': '380',
                   'wp': '1'}
    item_list = []
    for item_key, item_value in params_dict.items():
        item_str = "{}={}".format(item_key, str(item_value))
        item_list.append(item_str)
    get_params_string = "&".join(item_list)
    url_a = url_path + get_params_string
    url_a_res = requests.get(url=url_a).json()
    pprint(url_a_res)
    sid = url_a_res.get("sid")
    cid = url_a_res.get("cid")
    ay = str(url_a_res.get("y"))
    p1 = url_a_res.get("p1")
    p2 = url_a_res.get("p2")
    image_p1 = "https://static.dingxiang-inc.com/picture" + p1
    image_p2 = "https://static.dingxiang-inc.com/picture" + p2
    print(image_p1)
    print(image_p2)
    bg_origin = "bg_origin.jpg"
    bg_path = "bg.jpg"
    tg_path = "tg.jpg"
    response = requests.get(image_p1)
    with open(bg_origin, 'wb') as f:
        f.write(response.content)

    ttt = img_recover(
        ar(image_p1[image_p1.rfind('/') + 1: image_p1.rfind('.')]), image_p1)
    cv2.imwrite(bg_path, ttt)

    response_tg = requests.get(image_p2)
    with open(tg_path, 'wb') as f:
        f.write(response_tg.content)

    if debug:
        show(bg_origin)
        show(bg_path)
        show(tg_path)
    distance = get_distance(bg_path, tg_path)
    distance = str(int(distance) - 10)
    ########################################
    headers = {
        'Accept': '*/*',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        'Content-type': 'application/x-www-form-urlencoded',
        'Origin': 'https://www.dingxiang-inc.com',
        'Pragma': 'no-cache',
        'Referer': 'https://www.dingxiang-inc.com/',
        'Sec-Fetch-Dest': 'empty',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Site': 'same-site',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36',
        'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
    }
    import execjs
    token = sid
    xdistance, ydistance = int(distance), int(ay)
    ac = execjs.compile(open('./greenseer.js', 'r', encoding='utf-8').read()).call(
        'get_ac',
        token, int(xdistance), int(ydistance)
    )

    data = {
        'ac': ac,
        'ak': ak,
        'c': cc,
        'uid': '',
        'jsv': jsv,
        'sid': sid,
        'code': '',
        'aid': aid,
        'x': xdistance,
        'y': ydistance,
        'w': 380,
        'h': 165,
    }
    pprint(data)
    response = requests.post(
        'https://cap.dingxiang-inc.com/api/v1', headers=headers, data=data)
    print(response.text)

run()

代码地址

https://gitee.com/gunhe/js_cracking/tree/master/ding_xiang

posted @ 2024-09-01 15:19  cerofang  阅读(136)  评论(0)    收藏  举报