合肥市房產市場信息平台跳轉鏈接解密


難度: ★☆☆☆☆ 1星

一、目標

目標網站:

http://60.173.254.126/

這算是一個列表頁,展示了一些小區,然后單擊小區跳轉到小區詳情,但是跳轉鏈接被加密了,是通過JS算出來的:

0

本篇文章的目標就是破解這個加密。


二、分析

上一小節的圖里可以看到,在單擊鏈接的時候綁定了一個事件reurl,在開發者工具的console上輸入reurl並回車:

1

拿到代碼:

function reurl(a) {
    a.href = "/item/" + recode(a.id)
}

可以看到在這里修改了鏈接的地址,用到了鏈接里的一個id屬性:

<a id="2714" style="cursor:pointer" onclick="reurl(this)" target="_blank" title="清樾園">清樾園</a>

同時id的解密還依賴了recode,同樣的套路拿到它的代碼:

function recode(a) {
    var n = nscaler(a);
    var c = SetObjNum(String(a).length);
    var d = SetObjNum(String(a).length);
    n = parseInt(n) + parseInt(d);
    var b = $("#iptstamp").val();
    b = nscaler(b.toString());
    return c + "-" + n + "-" + d + "-" + b
}

這個方法中依賴了兩個方法和一個dom元素,先看nscaler,用同樣的方法從console跟進去拿到它的代碼:

function nscaler(a) {
    var b = "";
    var ar = String(a).split('');
    $.each(ar, function (i, e) {
        switch (e) {
            case "0":
                b += "0";
                break;
            case "1":
                b += "2";
                break;
            case "2":
                b += "5";
                break;
            case "3":
                b += "8";
                break;
            case "4":
                b += "6";
                break;
            case "5":
                b += "1";
                break;
            case "6":
                b += "3";
                break;
            case "7":
                b += "4";
                break;
            case "8":
                b += "9";
                break;
            case "9":
                b += "7";
                break
        }
    });
    return b
}

從邏輯上看,這個方法是將字符串使用一個映射表映射為一個新的值:

{
    0: 0,
    1: 2,
    2: 5,
    3: 8,
    4: 6,
    5: 1,
    6: 3,
    7: 4,
    8: 9,
    9: 7,
}

然后是SetObjNum,從console跟進去拿到源碼,注意到跟進去的時候tab的標題是VMxxx格式的,說明可能是eval定義的:

function SetObjNum(n) {
    var a = "";
    for (var i = 0; i < n; i++) a += Math.floor(Math.random() * 10);
    return a
}

這個方法就是生成一個隨機數,然后是$("#iptstamp").val();,在頁面源代碼:

view-source:http://60.173.254.126/

中搜索iptstamp可以找到,這就是服務器返回的一個時間戳:

2

至此,所有邏輯已經捋清楚,接下來就是編碼實現。


三、編碼實現

#!/usr/bin/env python3
# encoding: utf-8
"""
@author: CC11001100
"""
import random

import requests
from bs4 import BeautifulSoup


def crawl():
    url = "http://60.173.254.126/"
    html = requests.get(url).text
    doc = BeautifulSoup(html, features="html.parser")
    iptstamp = doc.select_one("#iptstamp")["value"]

    r = {}
    for x in doc.select("a[id][onclick][title][style]"):
        id = x["id"]
        link = "http://60.173.254.126/item/" + recode(id, iptstamp)
        title = x["title"]
        r[title] = link
    return r


def recode(s, iptstamp):
    n = nscaler(s)
    c = set_obj_num(len(n))
    d = set_obj_num(len(n))
    n = int(n) + int(d)
    b = nscaler(iptstamp)
    return str(c) + "-" + str(n) + "-" + str(d) + "-" + str(b)


def set_obj_num(n):
    r = 0
    for _ in range(0, n):
        r += int(random.random() * 10)
    return r


def nscaler(s):
    mapping = {
        0: 0,
        1: 2,
        2: 5,
        3: 8,
        4: 6,
        5: 1,
        6: 3,
        7: 4,
        8: 9,
        9: 7,
    }
    result = 0
    for x in s:
        result = result * 10 + mapping[int(x)]
    return str(result)


if __name__ == "__main__":
    print(crawl())

運行效果:

3

經驗證無誤。


倉庫:

https://github.com/CC11001100/misc-crawler-public/tree/master/001-anti-crawler-js-re/01-003-60.173.254.126


請注意爬蟲文章具有時效性,本文寫於2020-11-25日。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM