一、網(wǎng)站分析
- 三年前的案例,我的原始文章
-
網(wǎng)站 ,如圖我們直接點(diǎn)擊標(biāo)題進(jìn)入到詳情頁,鏈接會(huì)發(fā)生跳轉(zhuǎn),且與我們?cè)谠斍榭吹降逆溄樱c在列表頁看到的鏈接完全不一樣,如果拿列表頁的鏈接直接新建標(biāo)簽頁打開的話,詳情頁也是403,
而只有觸發(fā)點(diǎn)擊的模式才能拿看到真實(shí)的詳情鏈接
-
假詳情鏈接
http://ggzy.zwfwb.tj.gov.cn:80/jyxxcggg/1025448.jhtml -
真詳情鏈接
http://ggzy.zwfwb.tj.gov.cn/jyxxcggg/Hw5fFNS%5EhnOR3wD5T5hxxA.jhtml
二、定位監(jiān)聽
- 谷歌瀏覽器點(diǎn)中a標(biāo)簽
- 火狐瀏覽器有自帶的event事件監(jiān)聽
三、熟悉AES-ECB
- 1、分析前,需要熟悉下aes加密是什么,熟悉的可能是md5加密,md5加密是哈希算法,不可逆不能從結(jié)果推出明文;
而aes是對(duì)稱加密算法,區(qū)別之一可加密可解密,即可反推明文
- 2、
AES的ECB模式,只需要找到key密鑰,就可以加密解密了
,在線調(diào)試AES加密解密 - 3、AES加密解密代碼
四、調(diào)試分析
-
以谷歌瀏覽器為例子
-
開始添加斷點(diǎn),嗯~ 在定義變量這里打個(gè)斷點(diǎn)試試,然后在點(diǎn)擊列表鏈接,會(huì)發(fā)現(xiàn)js停在了斷點(diǎn)處,然后咱們就一步一步的往下調(diào)試,會(huì)發(fā)現(xiàn)列表的url是如何加密的了,而其中最核心的加密算法,其實(shí)是用了CryptoJS的對(duì)稱加密AES加密,并且使用的是ECB模式,Pkcs7填充,密鑰在調(diào)試這部分的時(shí)候可以看到是何值
文章來源:http://www.zghlxwxcb.cn/news/detail-611444.html
-
摳出js:將整個(gè)js文件全部復(fù)制下來,在console面板可直接運(yùn)行,以下是將關(guān)鍵js扣出來并在新建js腳本運(yùn)行后的結(jié)果,大功告成,下面我用python來還原
文章來源地址http://www.zghlxwxcb.cn/news/detail-611444.html
五、node運(yùn)行js
- 前端定義的CryptoJS我并沒有直接復(fù)制,而是通過本地的node直接導(dǎo)入CryptoJS庫,此時(shí)只需要將關(guān)鍵代碼扣出來即可;
- 本地需安裝node環(huán)境,然后再安裝crypto-js庫:
npm install crypto-js -g
-
重要參數(shù)
:key是密鑰;指定模式默認(rèn)ECB模式;padding是用來填充數(shù)據(jù)的,如果需要加密的數(shù)據(jù)的字節(jié)碼的長度不是塊大小的整數(shù)倍就需要填充 - 方式1:扣js,缺啥補(bǔ)啥
var CryptoJS = require('crypto-js'); var req = function(hh) { var s = "qnbyzzwmdgghmcnm"; var ee = "_blank"; 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]*$/; if (r.test(ccc) && cccc.indexOf('jhtml') != -1) { var srcs = CryptoJS.enc.Utf8.parse(ccc); 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; } } console.log(req("http://ggzy.xzsp.tj.gov.cn:80/jyxxcggg/948547.jhtml"));
- 方式2:js自帶的模塊CryptoJS,加理解的邏輯
var CryptoJS = require("crypto-js"); var encrypt_req = function(key,text) { var l = CryptoJS.enc.Utf8.parse(text); var e = CryptoJS.enc.Utf8.parse(key); var a = CryptoJS.AES.encrypt(l, e, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }) return a.toString() // 此方式返回base64 // return a.ciphertext.toString() // 返回hex格式的密文 } // ECB模式加密base64 console.log(encrypt_req('qnbyzzwmdgghmcnm', '1025528'));
六、Python執(zhí)行js
- python調(diào)用js三種方式:
- 要么用python現(xiàn)有的模塊替換js相同的邏輯,即python還原
- 要么通過execjs/ py_mini_racer等執(zhí)行
- 要么通過node部署服務(wù)開接口執(zhí)行
- python的execjs庫調(diào)用js
"""通過execjs執(zhí)行js""" import execjs # pip install execjs from loguru import logger list_url = 'http://ggzy.zwfwb.tj.gov.cn:80/jyxxcgjg/1025528.jhtml' with open('./aes.js', "r", encoding='utf-8') as f: ctx = execjs.compile(f.read()) true_url = ctx.call('req', list_url) logger.info(f"詳情的url:{list_url} >真實(shí)的url: {true_url}") #######分割線####### import execjs # pip install execjs from loguru import logger list_url = 'http://ggzy.zwfwb.tj.gov.cn:80/jyxxcgjg/1025528.jhtml' ccc = list_url.split('/')[-1].rstrip('.jhtml') with open('./aes.js', "r", encoding='utf-8') as f: ctx = execjs.compile(f.read()) suffix = ctx.call('encrypt_req', 'qnbyzzwmdgghmcnm', '1025528').replace('/', '^')[:-2] true_url = f"http://ggzy.zwfwb.tj.gov.cn:80/jyxxcgjg/{suffix}.jhtml" logger.info(f"詳情的url:{list_url} >真實(shí)的url: {true_url}")
- python自帶的aes庫還原邏輯:
pip install pycryptodome
from loguru import logger from Crypto.Cipher import AES from Crypto.Util.Padding import pad import base64 def aes_ecb_encrypt_text(decrypt_text: str, key: str) -> str: """ 加密AES_ECB明文 :param decrypt_text: 待加密的字符串 :param key: 密鑰 :return: 加密后的數(shù)據(jù) """ aes2 = AES.new(key.encode('utf-8'), AES.MODE_ECB) encrypt_text = aes2.encrypt(pad(decrypt_text.encode('utf-8'), AES.block_size, style='pkcs7')) encrypt_text = str(base64.encodebytes(encrypt_text), encoding='utf-8').replace("\n", "") return encrypt_text list_url = 'http://ggzy.zwfwb.tj.gov.cn:80/jyxxcgjg/1025528.jhtml' ccc = list_url.split('/')[-1].rstrip('.jhtml') decrypt_str = ccc key_str = "qnbyzzwmdgghmcnm" encrypt_str = aes_ecb_encrypt_text(decrypt_str, key_str).replace('/', '^')[:-2] true_url = list_url.replace(decrypt_str, encrypt_str) logger.info(f"詳情的url:{list_url} >真實(shí)的url: {true_url}")
七、知識(shí)星球-時(shí)光漫漫
- web端查看如下
- app端查看如下
到了這里,關(guān)于爬蟲小白-如何調(diào)試列表頁鏈接與詳情鏈接不一樣并三種方式j(luò)s逆向解決AES-ECB的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!