JS解密+混淆破解
爬取的網站:https://www.aqistudy.cn/html/city_detail.html
更清晰的查看博客:博客地址:https://www.cnblogs.com/bobo-zhang/p/11243138.html
分析:
-
1.修改查詢條件(城市的名稱+時間范圍),點擊查詢按鈕,捕獲點擊按鈕后發起請求對應的數據包。點擊查詢按鈕后,發起的是ajax請求。該請求就會將指定查詢條件對應的數據加載到當前頁面中。(我們要爬取的數據就是該ajax請求請求到的數據)
-
2.分析捕獲到的數據包
- 提取出請求的url:https://www.aqistudy.cn/apinew/aqistudyapi.php - 請求方式:post - 請求參數:d:動態變化一組數據(且加密) - 響應數據:是加密的密文數據 - 問題:該數據包請求到的是密文數據,為何在前台頁面顯示的缺失原文數據? - 原因:請求請求到密文數據后,前台接受到密文數據后使用指定的解密操作(js函數)對密文數據進行了解密,然后將原文數據顯示在了前台頁面。 - 下一步工作的步驟: - 首先先處理動態變化的請求參數,動態獲取該參數的話,就可以攜帶該參數進行請求發送,將請求到的密文數據捕獲到。 - 將捕獲到的密文數據找到對應的解密函數對其進行解密即可。 - 【重點】需要找到點擊查詢按鈕后對應的ajax請求代碼,從這組代碼中就可以破解動態變化的請求參數和加密的響應數據對應的相關操作。 - 3.找ajax請求對應的代碼,分析代碼獲取參數d的生成,和加密的響應數據的解密操作 - 基於火狐瀏覽器定位查詢按鈕綁定的點擊事件。從getData函數實現中找尋ajax請求對應的代碼 - 在該函數的實現中沒有找到ajax代碼,但是發現了另外兩個函數的調用 - getAQIData();getWeatherData();ajax代碼一定是存在於這兩個函數實現內部 - type == ’HOUR‘:查詢時間是以小時為單位 - 分析getAQIData();getWeatherData():找到ajax代碼 - 沒有找到ajax請求代碼 - 發現了另一個函數調用:getServerData(method,param,func,0.5) - method = 'GETCITYWEATHER' or 'GETDETAIL' - params = {city,type,startTime,endTime}:查詢條件 - 分析getServerData,找尋ajax代碼: - 基於抓包工具做全局搜索對getServerData加密的實現進行解密
- JS混淆:對核心JS代碼進行加密
- JS反混淆:對js加密代碼進行解密
- 暴力破解:https://www.bm8.com.cn/jsConfusion/
- 終於看到了ajax實現的代碼
- 分析結論
- data:加密的響應數據
- decodeDate(data)將加密的響應數據進行解密
- 參數data:加密的響應數據‘
- param:動態變化且加密的請求參數
- getParam(method.object)返回動態變化的請求參數
- 參數method:method = 'GETCITYWEATHER' or 'GETDETAIL'
- 參數object: {city,type,startTime,endTime}:查詢條件
- getParam(method.object)返回動態變化的請求參數
- data:加密的響應數據
js逆向
- 現在只需要調用兩個js函數(decodeData,getParam)返回結果即可。在python程序中如何調用js函數。
- js逆向:在python中調用js函數
- 方式1:
- 手動的將js函數改寫稱為python函數
- 方式2:
- 使用固定模塊實現自動逆向(推薦)
- PyExecJS 庫來實現模擬JavaScript代碼執行獲取動態加密的請求參數,然后再將加密的響應數據帶入decodeData進行解密即可!
- pip install PyExecJS
- 在本機安裝好nodejs的環境
- 方式1:
#模擬執行decodeData的js函數對加密響應數據進行解密
import execjs
import requests
node = execjs.get()
# Params
method = 'GETCITYWEATHER'
city = '北京'
type = 'HOUR'
start_time = '2018-01-25 00:00:00'
end_time = '2018-01-25 23:00:00'
# Compile javascript
file = 'jsCode.js' 這是JS源文件,你所模擬執行的JS函數需要在源文件中
ctx = node.compile(open(file,encoding='utf-8').read())
# Get params
js = 'getPostParamCode("{0}", "{1}", "{2}", "{3}", "{4}")'.format(method, city, type, start_time, end_time)
params = ctx.eval(js) #請求參數d
#發起post請求
url = 'https://www.aqistudy.cn/apinew/aqistudyapi.php'
response_text = requests.post(url, data={'d': params}).text#加密的響應數據
#對加密的響應數據進行解密
js = 'decodeData("{0}")'.format(response_text)
decrypted_data = ctx.eval(js)#返回的是解密后的原文數據
print(decrypted_data)
#執行會報錯:目前頁面中沒有數據。解密函數只是針對頁面中原始的數據進行解密。
移動端數據的爬取
利用工具,fiddler
參考博客- https://www.cnblogs.com/bobo-zhang/p/10068994.html
-
https的加密原理:證書秘鑰加密。
https參考知乎:https://www.jianshu.com/p/4764825fb916
