巨潮证券市场JS逆向
一 网站加密特征
目标网址 | http://webapi.cninfo.com.cn/#/marketData |
---|---|
加密类型 | 字符串拼接 |
加密字段 | 报头: mcode |
解密方法 | python复现 |
知识点 | utf8编码 |
js | String.prototype.charCodeAt|charAt |
python | ord |
避坑 | python nan类型无法右移 |
可明文搜索 | True |
二 JS逆向逻辑
2-1 快捷键 ctrl+shift 打开谷歌调试工具DevTools
2-2 快捷键 ctrl+shift+f 打开响应搜索栏输入加密报头 mcode
2-3 定位到报头生成的接口 打上断点
接口中的明文由13位时间戳除1000向下取整转字符串而成,核心加密接口在window对象中,明文算法用python代展示如下:
import time
import math
# 时间戳取整
src = math.floor(time.time())
2-4 刷新网站 根据堆栈回溯到加密代码内部
观察如下解密代码可知:枚举入参中的明文然取ascill码后位移,作为Keystr的索引取字符拼接而成
2-5 经过观察该加密为字符串拼接+ascill编码+位移实现,python代码复现如下
三 python代码复现
import time,math
def encrypt(input):
key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
output = ''
chr1 = ''
chr2 = ''
chr3 = ''
enc1 = ''
enc2 = ''
enc3 = ''
enc4 = ''
i = 0
while i<len(input):
try:
chr1 = ord(input[i])
except:
chr1 = False
i+=1
try:
chr2 = ord(input[i])
except:
chr2 = False
i+=1
try:
chr3 = ord(input[i])
except:
chr3 = False
i+=1
enc1 = chr1 >> 2
enc2 = ((chr1 & 3)<<4)| (chr2>>4)
enc3 = ((chr2 & 15)<<2)|(chr3>>6)
enc4 = chr3 & 63
if(not chr2):
enc3 = enc4 = 64
elif not chr3:
enc4 = 64
output = output + key[enc1] + key[enc2] + key[enc3] + key[enc4]
chr1 = chr2 = chr3 = ''
enc1 = enc2 = enc3 = enc4 = ''
return output
t = str(math.floor(time.time()))
str = encrypt(t)