本文章中所有內容僅供學習交流,抓包內容、敏感網址、數據接口均已做脫敏處理,嚴禁用於商業用途和非法用途,否則由此產生的一切後果均與作者無關,若有侵權,請聯繫我立即刪除!
逆向目標鏈接進入到網站,會發現先轉會圈才進入到網頁,這裡可能就有個渲染加載的過程,打開開發者人員工具,刷新網頁,往下滑會看到抓包到了數據返回的接口:aHR0cDovL2dnenkuamNzLmdvdi5jbi9wcm8tYXBpLWNvbnN0cnVjdGlvbi9jb25zdHJ1Y3Rpb24vYmlkZGVyL2JpZFNlY3Rpb24vbGlzdA==,GET 請求,從 preview 響應預覽中可以看到當前頁面所有公告的信息:
Query String Parameters 中有些參數信息,各類型什麼含義後文會詳細講解:
pageNum: 當前為第幾頁
pageSize: 頁面大小
informationType: 公告類型
projectType: 項目類型
informationName: 信息類型
接下來隨便點擊一條公告,跳轉到一個新頁面,會發現網頁鏈接變成了這種格式:XXX/index?projectId=XXX&projectInfo=XXX,生成了 projectId 和 projectInfo 兩個加密參數,並且經過測試,同一個公告頁面這兩個加密參數的值是固定的,接下來我們需要嘗試找到這兩個參數的加密位置。
調試分析定位從主頁位置 CTRL + SHIFT + F 全局搜索 projectId 參數,依次對比可以發現,projectId 和 projectInfo 兩個加密參數在 chunk-63628500.eb5f8d30.js 中定義,這裡是個三目運算,若項目類型相同則執行其後的方法,若不同則往後執行:
上文代碼行判斷中出現的 ZFCG、GTGC 是什麼意思呢,CTRL + SHIFT + F 全局搜索 ZBGG 參數,在 chunk-043c03b8.34f6abab.js 文件中我們可以找到相應的定義,以下即各自的含義:
在第 267 行,return t.stop() 處打下斷點進行調試分析,隨便點擊一條公告,會發現斷點斷住,即成功定位,鼠標懸停在 projectId 和 projectInfo 對應的值上,可以知道以下信息:
projectId :項目編號
projectInfo :信息類型
知道了兩個加密參數的具體含義,接下來我們就需要找到其加密位置了,projectId和projectInfo 參數由 a.parameterTool.encryptJumpPage 方法執行,encryptJumpPage 跳轉頁面加密?這不簡直就是明示:
我們將鼠標懸停在 a.parameterTool.encryptJumpPage 上,跟進到方法生成的 js 文件 app.3275fd87.js 中去瞅瞅:
以上我們可以清晰地知道下面兩個參數的具體含義:
query:加密數據( projectId 和 projectInfo)
nextPath:路由跳轉位置
在第 2389 行打斷點進行調試分析,從下圖可以知道,projectId 和 projectInfo 參數在 a 中被加密了:
進一步跟蹤 a 的位置,往上滑可以看到第 2335 行到 2356 行是很明顯的 DES 加密:
但具體是哪個函數部分對 query 中的 projectId 和 projectInfo 參數進行了加密還不得而知,我們繼續打斷點調試分析,在 2341 行打斷點時發現,projectId 參數對應的值 424,projectInfo 參數對應的值 ZBGG,都在 function c(t) 中進行了處理,證明此處就是關鍵的加密位置:
分析這段關鍵的加密代碼:
iv:ivHex 十六進制初始向量
mode:採用 CBC 加密模式,其是一種循環模式,前一個分組的密文和當前分組的明文異或操作後再加密
padding:採用 Pkcs7 填充方式,在填充時首先獲取需要填充的字節長度 = 塊長度 - (數據長度 % 塊長度), 在填充字節序列中所有字節填充為需要填充的字節長度值
ciphertext.toString():將加密後的密文,以十六進制字符串形式返回
這裡直接引用 JS,使用 nodejs 裡面的加密模塊 crypto-js 來進行 DES 加密,調試過程中提示哪個函數未定義,就將其定義部分添加進來即可,改寫後的完整 JS 代碼如下:
varCryptoJS=require('crypto-js');o={keyHex:CryptoJS.enc.Utf8.parse(Object({NODE_ENV:"production",VUE_APP_BASE_API:"/pro-api",VUE_APP_CONSTRUCTION_API:"/pro-api-construction",VUE_APP_DEV_FILE_PREVIEW:"/lyjcdFileView/onlinePreview",VUE_APP_FILE_ALL_PATH:"http://www.lyjcd.cn:8089",VUE_APP_FILE_PREFIX:"/mygroup",VUE_APP_LAND_API:"/pro-api-land",VUE_APP_PREVIEW_PREFIX:"/lyjcdFileView",VUE_APP_PROCUREMENT_API:"/pro-api-procurement",VUE_APP_WINDOW_TITLE:"XXXXXX",BASE_URL:"/"}).VUE_APP_CUSTOM_KEY||"54367819"),ivHex:CryptoJS.enc.Utf8.parse(Object({NODE_ENV:"production",VUE_APP_BASE_API:"/pro-api",VUE_APP_CONSTRUCTION_API:"/pro-api-construction",VUE_APP_DEV_FILE_PREVIEW:"/lyjcdFileView/onlinePreview",VUE_APP_FILE_ALL_PATH:"http://www.lyjcd.cn:8089",VUE_APP_FILE_PREFIX:"/mygroup",VUE_APP_LAND_API:"/pro-api-land",VUE_APP_PREVIEW_PREFIX:"/lyjcdFileView",VUE_APP_PROCUREMENT_API:"/pro-api-procurement",VUE_APP_WINDOW_TITLE:"XXXXXX",BASE_URL:"/"}).VUE_APP_CUSTOM_IV||"54367819")};functionc(t){returnCryptoJS.DES.encrypt(t,o.keyHex,{iv:o.ivHex,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7}).ciphertext.toString()}//測試//console.log(c('ZBGG'))//ff15d186c4d5fa7aVUE_APP_WINDOW_TITLE 對應值內容經過脫敏處理,經測試,不影響結果輸出
完整代碼GitHub 關注 K 哥爬蟲,持續分享爬蟲相關代碼!歡迎 star !
https://github.com/kgepachong/
以下只演示部分關鍵代碼,不能直接運行! 完整代碼倉庫地址:
https://github.com/kgepachong/crawler/
本案例代碼:
https://github.com/kgepachong/crawler/tree/main/ggzy_jcs_gov_cn
#=======================#--*--coding:utf-8--*--#@Author :微信公眾號:K哥爬蟲#@FileName:ggzy.py#@Software:PyCharm#=======================importurllib.parseimportexecjsimportrequestsurl='脫敏處理,完整代碼關注https://github.com/kgepachong/crawler/'defencrypted_project_id(id_enc):withopen('ggzy_js.js','r',encoding='utf-8')asf:public_js=f.read()project_id=execjs.compile(public_js).call('Public',id_enc)returnproject_iddefencrypted_project_info(info_enc):withopen('ggzy_js.js','r',encoding='utf-8')asf:public_js=f.read()project_info=execjs.compile(public_js).call('Public',info_enc)returnproject_infodefget_project_info(info_name,info_type):index_url='脫敏處理,完整代碼關注https://github.com/kgepachong/crawler/'urlparse=urllib.parse.urlparse(index_url)project_info=urllib.parse.parse_qs(urlparse.query)['informationName'][0]returnproject_infodefget_content(page,info_name,info_type):headers={"Connection":"keep-alive","Pragma":"no-cache","Cache-Control":"no-cache","Accept":"application/json,text/plain,*/*","User-Agent":"Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/86.0.4240.198Safari/537.36","Referer":"脫敏處理,完整代碼關注https://github.com/kgepachong/crawler/","Accept-Language":"zh-CN,zh;q=0.9"}url_param="脫敏處理,完整代碼關注https://github.com/kgepachong/crawler/"params={"pageNum":page,"pageSize":"20","releaseTime":"","search":"","informationType":info_type,"departmentId":"","projectType":"SZFJ","informationName":info_name,"onlyCanBidSectionFlag":"NO"}response=requests.get(url=url_param,headers=headers,params=params)returnresponsedefmain():print("脫敏處理,完整代碼關注https://github.com/kgepachong/crawler/")info_name=input("請輸入信息類型:")info_type=input("請輸入公告類型:")page=input("您想要獲取數據的頁數:")get_content(page,info_name,info_type)response=get_content(page,info_name.upper(),info_type.upper())num=int(page)*20print("總共獲取了%d個項目"%num)foriinrange(20):title=response.json()['rows'][i]['content']query_id=response.json()['rows'][i]['projectId']query_info=get_project_info(info_name.upper(),info_type.upper())project_id_enc=encrypted_project_id(str(query_id))project_info_enc=encrypted_project_info(query_info) project_url='%s?projectId=%s&projectInfo=%s'%(url,project_id_enc,project_info_enc)print("第%d個項目:"%(i+1)+"\n"+"項目名稱:%s 項目編號:%d "%(title,query_id)+"\n"+"項目鏈接:%s"%project_url)if__name__=='__main__':main()代碼實現效果: