← All posts

Web逆向:全国建筑市场监督公共服务平台

#web-reversing#trivial

1 信息

网站 URL
全国建筑市场监督公共服务平台 https://jzsc.mohurd.gov.cn

CleanShot 2026-06-29 at 21.19.02@2x.png

2 接口

点击 数据服务 选择 人员数据 ,进入下面的页面

目标是获取这里的 人员数据信息,首先找到数据接口,通常数据在 XHR

CleanShot 2026-06-29 at 21.25.35@2x.png

这里我们通过接口的数据大小来判断哪个是数据接口,因为通常数据接口都会因为携带大量数据而有着较大的数据大小

因此,我们判断 list 就是数据接口,下面将该接口转换为 requests 请求格式

import requests  
  
cookies = {  
    'Hm_lvt_b1b4b9ea61b6f1627192160766a9c55c': '1782661962',  
    'HMACCOUNT': '967035D1328E903E',  
    'Hm_lpvt_b1b4b9ea61b6f1627192160766a9c55c': '1782662197',  
}  
  
headers = {  
    'Accept': 'application/json, text/plain, */*',  
    'Accept-Language': 'zh-CN,zh;q=0.9',  
    'Cache-Control': 'no-cache',  
    'Connection': 'keep-alive',  
    'Pragma': 'no-cache',  
    'Referer': 'https://jzsc.mohurd.gov.cn/data/person',  
    'Sec-Fetch-Dest': 'empty',  
    'Sec-Fetch-Mode': 'cors',  
    'Sec-Fetch-Site': 'same-origin',  
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36',  
    'accessToken': '',  
    'sec-ch-ua': '"Google Chrome";v="149", "Chromium";v="149", "Not)A;Brand";v="24"',  
    'sec-ch-ua-mobile': '?0',  
    'sec-ch-ua-platform': '"macOS"',  
    'timeout': '30000',  
    'v': '231012',  
}  
  
params = {  
    'pg': '0',  
    'pgsz': '15',  
    'total': '0',  
}  
  
response = requests.get(  
    'https://jzsc.mohurd.gov.cn/APi/webApi/dataservice/query/staff/list',  
    params=params,  
    cookies=cookies,  
    headers=headers,  
)  

CleanShot 2026-06-29 at 21.35.48@2x.png

该接口的请求参数并未出现任何加密,但是响应的数据却是被加密的,因此接下来的工作就是找到解密位置并分析如何解密,获取响应的明文内容

我们可以通过 搜索法 找到解密的位置,一般情况下可以搜索关键字 decrypt 来定位解密位置

CleanShot 2026-06-29 at 21.46.24@2x.png

找到位置后,在关键代码位置打上断点,然后在页面中点击翻页触发 list 接口,观察程序是否停留在断点位置,如果程序停留在断点位置,说明我们找的解密代码位置是正确的,反之不正确需要找其他位置或者另寻出路

很幸运的是,这里我们找的位置是正确的,接下来我们要分析如何解密

3 分析

通常,形如下面形式的代码都是使用 JS 的 Crypto 库 CryptoJS 实现的。这个库我们可以直接在 NodeJS 中安装下载并使用

function decrypt(ciphertextHex, keyStr, ivStr) {  
    var ciphertext = CryptoJS.enc.Hex.parse(ciphertextHex);  
    var key = CryptoJS.enc.Utf8.parse(keyStr);  
    var iv = CryptoJS.enc.Utf8.parse(ivStr);  
  
    var decrypted = CryptoJS.AES.decrypt(  
        { ciphertext: ciphertext },  
        key,  
        { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }  
    );  
  
    return decrypted.toString(CryptoJS.enc.Utf8);  
}  

经过分析,该网站正是使用了 CryptoJS 这个库来实现解密,并且使用的 AES 算法的 CBC 模式,因此我们只需要找到解密的 keyiv 就可以了

在已知 keyiv 的情况下,我们可以通过下面的方法反推出 keyStrivStr ,即已知 keyiv 字节反推出其明文

keyStr = CryptoJS.enc.Utf8.stringify(key);  
ivStr = CryptoJS.enc.Utf8.stringify(iv);  

CleanShot 2026-06-29 at 22.09.40@2x.png

这样我们就找到了明文的 keyiv

const AES_KEY = "Dt8j9wGw%6HbxfFn";  
const AES_IV = "0123456789ABCDEF";  

有了 keyiv ,我们就可以直接对响应的密文进行解密

4 结果

TODO