AES链接加密逆向

本文分析http://ggzy.zwfwb.tj.gov.cn/网站

展示的是url加密(列表页源码中对应的url和详情页对应的url不同)
在这里插入图片描述
对应的详情页url是http://ggzy.zwfwb.tj.gov.cn/jyxxcggg/Dn+BswYsE55CV9r1AJrIgg.jhtml

梳理本案例中的反爬策略:
1.列表页响应的源码包含详情页的地址。
2.点击详情页链接,转跳加密,出现新的地址。
3.原地址直接报403访问问题。
4.用简单的静态搜索没有找到有用的生成逻辑,通过Initiator堆栈调式也没有找到有用的生成逻辑。
解决方法:
跳转加密逻辑,不是请求逻辑,所以它的加密逻辑一定是在前端 JS 文件中实现的(经验问题),此时我们可以基于网页元素事件绑定,跟踪加密逻辑。
新手可以先观察DOM事件监听是怎样的。
(在开发者工具中,直接检查 DOM 元素的所有事件,其中重点关注的是单击操作(因为基于上文分析,是单击之后跳转地址发生了变化。)
观察下面几张图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

点击 第一张图中对应的VM 之后,直接跳转到 JS 代码页面,将源码格式化之后,发现非常短小。
发现加密是AES
在这里插入图片描述
通过断点调试知道密钥是s
在这里插入图片描述

修改对应的js

// npm install crypto-js

var CryptoJS = require("crypto-js");

function lx(hh) {
    var aa = hh.split("/");
    var aaa = aa.length;
    var bbb = aa[aaa - 1].split('.');
    var ccc = bbb[0];
    var cccc = bbb[1];
    var r = /^\+?[1-9][0-9]*$/;

    var srcs = CryptoJS.enc.Utf8.parse(ccc);
    var s = "qnbyzzwmdgghmcnm";
    var k = CryptoJS.enc.Utf8.parse(s);
    var en = CryptoJS.AES.encrypt(srcs, k, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });
    var ddd = en.toString();
    ddd = ddd.replace(/\//g, "^");
    ddd = ddd.substring(0, ddd.length - 2);
    var bbbb = ddd + '.' + bbb[1];
    aa[aaa - 1] = bbbb;
    var uuu = '';
    for (i = 0; i < aaa; i++) {
        uuu += aa[i] + '/'
    }
    uuu = uuu.substring(0, uuu.length - 1);
    return uuu;
}

python调用js

import execjs

js = '''
// npm install crypto-js

var CryptoJS = require("crypto-js");

function lx(hh) {
    var aa = hh.split("/");
    var aaa = aa.length;
    var bbb = aa[aaa - 1].split('.');
    var ccc = bbb[0];
    var cccc = bbb[1];
    var r = /^\+?[1-9][0-9]*$/;

    var srcs = CryptoJS.enc.Utf8.parse(ccc);
    var s = "qnbyzzwmdgghmcnm";
    var k = CryptoJS.enc.Utf8.parse(s);
    var en = CryptoJS.AES.encrypt(srcs, k, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });
    var ddd = en.toString();
    ddd = ddd.replace(/\//g, "^");
    ddd = ddd.substring(0, ddd.length - 2);
    var bbbb = ddd + '.' + bbb[1];
    aa[aaa - 1] = bbbb;
    var uuu = '';
    for (i = 0; i < aaa; i++) {
        uuu += aa[i] + '/'
    }
    uuu = uuu.substring(0, uuu.length - 1);
    return uuu;
}
'''

hh="http://ggzy.zwfwb.tj.gov.cn:80/jyxxcgjg/970369.jhtml"
url = execjs.compile(js).call('lx',hh)
print(url)

可以将对应的js修改成python

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad

import base64

def encrypt_text(text, key):
    aes = AES.new(key.encode('utf-8'), AES.MODE_ECB)
    encrypt_str = aes.encrypt(pad(text.encode('utf-8'), AES.block_size, style='pkcs7'))
    encrypt_str = str(base64.encodebytes(encrypt_str), encoding='utf-8')
    return encrypt_str

if __name__ == '__main__':
    key = 'qnbyzzwmdgghmcnm'

    es = encrypt_text("1013331", key)
    es.replace("\n", "")  # 去掉后面的换行
    es = es.replace('/', '^')[:-2]  # 去掉最后的 ==
    print(es)

完整代码
完整获取url,加密url,获取详情页数据

import requests,re
from bs4 import BeautifulSoup
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import base64

def get_urlid():

    list_urls = []
    for i in range(1,2):
        list_url=[]
        if i==1:
            url = 'http://ggzy.zwfwb.tj.gov.cn/jyxx/index.jhtml'
        else:
            url = 'http://ggzy.zwfwb.tj.gov.cn/jyxx/index_{}.jhtml'.format(i)
        r = requests.get(url).text
        soup = BeautifulSoup(r, 'lxml')
        books = soup.find_all(class_='article-list3-t')
        # print(books)

        for book in books:
            url_list = book.find(name='a')['url']
            list_url.append(url_list)
        list_urls.append(list_url)
    return list_urls


def encrypt_text(text, key):
    aes = AES.new(key.encode('utf-8'), AES.MODE_ECB)
    encrypt_str = aes.encrypt(pad(text.encode('utf-8'), AES.block_size, style='pkcs7'))
    encrypt_str = str(base64.encodebytes(encrypt_str), encoding='utf-8')
    return encrypt_str

def get_content(url,url_id):
    r = requests.get(url).text
    soup = BeautifulSoup(r, 'lxml')
    books = soup.find(class_='content-article')
    # print(books)
    contents = books.find(id='content').find_all(name='p')
    s=''
    for content in contents:
        con = content.text
        s=s+'\n'+con
        print(con)


    with open('{}.txt'.format(url_id),'w',encoding='utf-8') as f:
        f.write(s)


if __name__ == '__main__':
    key = 'qnbyzzwmdgghmcnm'

    urlids=get_urlid()
    id_lists = []
    for urlid in urlids:
        for id_url in urlid:
            id_es = []
            list_id = id_url.split('/')[-1].split('.')[0]
            id_es.append(list_id)
            es = encrypt_text(list_id, key)
            es=es.replace("\n", "")  # 去掉后面的换行
            es = es.replace('/', '^')[:-2]  # 去掉最后的 ==
            es = es.replace("^", "%5E")
            id_es.append(es)
            url=id_url.replace(list_id, es)
            print(id_url,url)
            get_content(url,list_id)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值