JS逆向——建筑市场监管公共服务平台

全国建筑市场监管公共服务平台(四库一平台)

问题:(1)接口返回值加密 

1、接口返回的数据为加密后的文本,先根据密文长度无法直接判断具体的加密方式d2dc962c2f6a1fd2648d4fc2ccabe43e.png

2、个人比较喜欢用hook,所以先对几个常用的加解密函数进行hook,并进行控制台输出(hook的工具写在下面,需要的自行提取)

4c9e6954035c4d8c9c959a0bf6e54ba9.png

3、上图可以很清楚的看到,红色部分是接口链接的参数部分,绿色部分为已经解密过后的数据,也就是我们需要的,最下面蓝色部分也可以看到解密后的文本经过了json.parse解析成数据字典,这里可以从json.parse入手。

4、定位到 json.parse这行的hook函数中,并在此处打上断点,在进行下一页操作,到此处暂停后发现右侧调用栈里又个方法h( ),跟进去

8e77f9c45612e8568cf8b49036a89871.png

5、 即可发现,t 为接口请求的密文,并且加密方式为AES.CBC,偏移量为

f = d.a.enc.Utf8.parse("jo8j9wGw%6HbxfFn")

m = d.a.enc.Utf8.parse("0123456789ABCDEF")

6、至此我们就可以用代码进行还原解密函数

var CryptoJS = require('C:/Data/npm/node_modules/crypto-js')

function getDecryptedData(t) {
    var m = CryptoJS.enc.Utf8.parse("0123456789ABCDEF"),
        f = CryptoJS.enc.Utf8.parse("jo8j9wGw%6HbxfFn"),
        e = CryptoJS.enc.Hex.parse(t),
        n = CryptoJS.enc.Base64.stringify(e),
        a = CryptoJS.AES.decrypt(n, f, {
            iv: m,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        }),
        r = a.toString(CryptoJS.enc.Utf8);
    return r.toString()
}

var fs = require('fs')

fs.readFile('./jzsc_mohurd.txt','utf8',function(err,dataStr) {
    if(err){
        return console.log("读取文件失败!"+err.message)
    }

    console.log(getDecryptedData(dataStr))
})

7、请求接口,并执行以下方法,此处说下,我是用的cmd执行的node命令,由于我电脑环境下,接口的加密字符远远超过了命令行的最大字符数,所以采用了 jzsc_mohurd.txt 文件做中转。

def get_data(projectType, region_id, page):
    '''
    获取接口数据
    @return:
    '''

    url = 'https://jzsc.mohurd.gov.cn/api/webApi/dataservice/query/project/list?projectType={}&projectRegionId={}&pg={}&pgsz=15'.format(
        projectType, region_id, page)
    headers = {
        'Host': 'jzsc.mohurd.gov.cn',
        'Referer': 'http://jzsc.mohurd.gov.cn/data/project',
        'User-Agent': getUserAgent()
    }
    res = requests.get(url, headers=headers)

    logger.debug('接口:{}'.format(url))
    logger.debug('获取的密文为:{}'.format(res.text))

    with open('./jzsc_mohurd.txt', 'w', encoding='utf-8') as f:
        f.write(res.text)
    decrypt_data()

def decrypt_data():
    """
    解密接口数据
    @param ciphertext:
    @return:
    """
    logger.debug('数据解密...')
    cmd = "node jzsc_mohurd.js"

    with os.popen(cmd) as fp:
        bf = fp._stream.buffer.read()
    try:
        plaintext = bf.decode().strip()
    except UnicodeDecodeError:
        plaintext = bf.decode('gbk').strip()
    logger.debug('解密后的数据为:{}'.format(plaintext))
    return plaintext

8、即可看到结果

附录:工具推荐|一款爬虫界的神兵利器,值得拥有

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值