Fork me on GitHub

合肥市房产市场信息平台跳转链接解密

难度: ★☆☆☆☆ 1星

一、目标

目标网站:

http://60.173.254.126/

这算是一个列表页,展示了一些小区,然后单击小区跳转到小区详情,但是跳转链接被加密了,是通过JS算出来的:

0

本篇文章的目标就是破解这个加密。


二、分析

上一小节的图里可以看到,在单击链接的时候绑定了一个事件reurl,在开发者工具的console上输入reurl并回车:

1

拿到代码:

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

可以看到在这里修改了链接的地址,用到了链接里的一个id属性:

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

同时id的解密还依赖了recode,同样的套路拿到它的代码:

01
02
03
04
05
06
07
08
09
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跟进去拿到它的代码:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
}

从逻辑上看,这个方法是将字符串使用一个映射表映射为一个新的值:

01
02
03
04
05
06
07
08
09
10
11
12
{
    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定义的:

01
02
03
04
05
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

至此,所有逻辑已经捋清楚,接下来就是编码实现。


三、编码实现

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/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日。

posted @   CC11001100  阅读(1098)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
历史上的今天:
2019-11-25 flash逆向练习:以逆向的方式通关flash游戏《谈判专家》
点击右上角即可分享
微信分享提示