js加密,js混淆机制
- 分析:
- 1.当我们修改页面的查询条件后,点击查询按钮,在抓包工具会捕获两个一样的数据包,我们只要破解其中一个就可以逐个击破
- 请求地址:https://www.aqistudy.cn/apinew/aqistudyapi.php
- 请求方式:POST
- 请求参数:d:加密数据
- 返回相应数据:加密
- 2.点击查询按钮,页面没有刷新,说明是ajax请求:
- 请求地址:https://www.aqistudy.cn/apinew/aqistudyapi.php
- 请求方式:POST
- 请求参数:d:加密数据
- 返回相应数据:加密
- 前台页面中显示的是原文数据
- 原因:响应回来的数据进行了解密
- 在该网站的相关数据包中是存在解密方案,我们只需要将其解密方法获取,对密文进行解密,即可
- 3.请求方式和请求可以从抓包工具捕获
- 携带请求参数:可以从ajax的代码中获取
- 请求回来的数据对应的回调函数
- 函数的参数就是请求到的响应数据(加密的密文数据),该函数会对拿到的密文数据进行解密,将解密后的原文动态显示前台页面中
- 重点:只要能够找到点击查询按钮对于的ajax请求代码后,就可以知道动态变化且加密的请求参数如果生成,就可以获取相应的密文数据,然后通过回调函数的操作获取解密方案,使用该方案的响应进行解密即可
- 操作:找ajax代码
- 获取搜索按钮对应的点事件:
- getData();绑定的点击事件
- 有价值的信息:
- type == "HOUR"查询时间是以小时为单位
- 发现函数内部调用了另外两个函数getAQIData(); getWeatherData();
- ajax代码的实现一定实在上述的两个函数内部
- 这这两个函数内部没有发现ajax 代码的实现
- 调用了一个叫做getServerData()函数,
- getServerData的参数:
- method :GETDETAIL 字符串
- param:字典,有四组键值对
param.type = type;
param.startTime = startTime;
param.endTime = endTime; - 回掉函数:
- 0.5
- 进入 getServerData的函数内部找ajax代码:
- 这个函数没有存在当前文件中需要在抓包工具里面进行全局搜索
- 通过全局搜索找到了getServerData在jquery文件中,是密文
- js混淆:
- 在网站的后后台,关键的重要的js函数的实现为了保密,一般会对这些js函数代码进行混淆(加密),所以我们需要进行解密(反混淆)
- 反混淆网址:http://www.bm8.com.cn/jsConfusion/
- 分析getServerData函数中的ajax代码:
- 动态变化加密的请求参数:
- var param = getParam(method, object);
- method = GETDETAIL
- object = param 字典
- decodeData(data);将data这个响应数据进行解密
- 需要调用这两个函数就可以进行发生请求了
- 总结:
- 调用getParam后就可以获取加密变化的请求参数
- 调用decodeData就可以将响应数据进行解密
- 问题:python调用js
- js逆向:
- 可以将js代码改写成 python代码
- 使用相关模块进行js逆向 pip3 install PyExecJS
- PyExecJS的使用:
- 1.需要接待执行,的js函数的全部定义存到text.js中
- 2.模拟执行js源文件中的js函数
- 加载js源文件js代码
- 将js源文件中的代码进行编译
import requests
import execjs
# 实例化一个对象
node = execjs.get()
# Params
method = "GETDETAIL"
city = '北京'
type = "HOUR"
start_time = "2018-01-25 00:00:00"
end_time = "2018-01-25 23:00:00"
# Copile javascript
file = "./text.js" # 待加载编译的js源文件
ctx = node.compile(open(file,encoding='utf-8').read())
# 调用getPostParamCode
js = 'getPostParamCode("{0}","{1}","{2}","{3}","{4}")'.format(method,city,type,start_time,end_time)
# eval表示模拟进行编译好的js函数
params = ctx.eval(js)
# print(params) # 返回是加密变化的请求参数
# 发起post请求
url = "https://www.aqistudy.cn/apinew/aqistudyapi.php"
response_text = requests.post(url=url,data={'d':params}).text
# print(response_text) # 返回加密的数据
# 模拟执行decodeData进行解密
jes = 'decodeData("{0}")'.format(response_text)
decrypted_data = ctx.eval(jes)
print(decrypted_data)
print("我结束了")
多任务线程池
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import time
from multiprocessing.dummy import Pool
import requests
#同步代码
# urls = [
# 'http://127.0.0.1:5000/bobo',
# 'http://127.0.0.1:5000/jay',
# 'http://127.0.0.1:5000/tom'
# ]
# def get_request(url):
# page_text = requests.get(url).text
# print(len(page_text))
#
# if __name__ == "__main__":
# start = time.time()
# for url in urls:
# get_request(url)
# print('总耗时:',time.time()-start)
#基于线程池的异步效果
urls = [
'http://127.0.0.1:5000/bobo',
'http://127.0.0.1:5000/jay',
'http://127.0.0.1:5000/tom'
]
def get_request(url):
page_text = requests.get(url).text
return len(page_text)
if __name__ == "__main__":
start = time.time()
pool = Pool(3) #启动了三个线程
#参数1:回调函数
#参数2:可迭代的对象,alist
#作用:可以将alist中的每一个元素依次传递给回调函数作为参数,然后回调函数会异步
#对列表中的元素进行相关操作运算
#map的返回值就是回调函数返回的所有结果
page_text_len_list = pool.map(get_request,urls)
print(page_text_len_list)
print('总耗时:',time.time()-start)