前言
今天来水一篇文章,某站webpack打包类型,登录、数据解密参数keyCipher、keySM2Cipher。本文章仅供学习研究,如若侵犯到贵公司权益请联系229456906@qq.com第一时间进行删除;各位朋友切忌用于一切非法途径,否则后果自行承担!
地址:gov地址就不放了,主要讲思路。。。
一、抓包分析
老规矩,打开登录框输入138****8888,1111111点击登录按钮进行抓包。
当点击登录后,看第一条请求:
看响应即可一目了然,当然,他的POST参数和响应如上图,参数没有名称,今天的任务就是找到post参数以及解密响应的数据,接下来寻找加密位置。
二、参数解析
1.加密定位
今天不一样,使用js搜索技巧——加密关键字“encrypt”搜索:
进入js文件找到疑似加密位置,打上断点:
重新抓包: 断住了,这里传入了五个参数,现在追到上一个堆栈看看: 发现参数o, u, c, t, f在这里可以全部找到: 打印一下n: 大概就是这个位置了,下面看看参数。
2.参数分析
打上断点,分析参数 u、c为固定值: o、f也是固定值:false 看一下t:
这里的处理逻辑:传入一个对象,转化成字符串,通过window.DCSAPPClientAPI.parseUtf8StringToArray处理得到最终的t值(数组)。 这里可以发现t的处理函数和n的处理函数在同一文件的window.DCSAPPClientAPI中,so,进去拿出来就好,这里县不急去扣js。因为e.data中可以看到loginPassword值是加密值,经过多次刷新断点,只有loginPassword会变化,所以先搞loginPassword的生成逻辑。
全局搜索一下loginPassword,两个位置,都打上断点: 重新抓包: 这里是对密码‘1111111’进行了加密,单步执行,进入函数内部: 加密算法是AES-ECB模式,并且key也有,所以可以直接搞定: 本地执行结果: 网页结果: 本地 == 网页,结束!
接下来去搞今天的最终任务,post参数: 进入这个js文件: 发现有webpack特征 所以,简单的把JS扣完,处理一下,最终结果:
Python模拟登录,看是否能正常返回响应,登录代码实现:
import execjs
import re
import time
import requests
import ddddocr
from JaJa.Tools import getJSCode
session = requests.session()
jscode = getJSCode('shanxi.js')
def txnCommCom():
headers = {
"Host": "xxx.gov.cn",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"
}
gettxnurl = 'https://xxx.gov.cn/'
res = session.get(url=gettxnurl, headers=headers).text
path = re.search(r'</script><script src="(.*?)"', res).group(1)
url = gettxnurl + path
headers['Referer'] = gettxnurl
res = session.get(url, headers=headers).text
txn = re.search(r'use strict";t\["a"\]=(.*?)\)', res).group(1)
print(txn)
txn1 = re.search(r'txnIttChnlCgyCode:"(.*?)"', res).group(1)
txn2 = re.search(r'txnIttChnlId:"(.*?)"', res).group(1)
print(txn1, txn2)
return txn1, txn2
def getSessionId():
url = 'https://xxx.gov.cn/sysauthserver/getSessionId'
res = session.get(url).json()
print(res['sessionId'])
return res['sessionId']
def vcodeId():
headers = {
"Host": "xxx.gov.cn",
"Referer": "https://xxx.gov.cn/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"
}
t = int(time.time()*1000)
url = 'https://xxx.cn/gsp/uc90001?vcodeId={}'.format(t)
res = session.get(url, headers=headers).content
with open('code.png', 'wb') as file:
file.write(res)
file.close()
return getCode(t)
def getCode(t, file='code.png'):
ocr = ddddocr.DdddOcr()
with open(file, 'rb') as f:
img_bytes = f.read()
res = ocr.classification(img_bytes)
res = {
'response': 1,
'code': res.upper(),
't': t,
'msg': 'success!'
}
print(res)
return res
def getFromdata(user, pwd):
vcode = vcodeId()
txn1, txn2 = txnCommCom()
sessionId = getSessionId()
url = 'https://xxx.gov.cn/gsp/uc10002'
head = execjs.compile(jscode).call('headers')
data = execjs.compile(jscode).call(
'getEncrypt',
user,
pwd,
vcode['code'],
sessionId,
txn1,
txn2,
vcode['t']
)
print(data)
headers = {
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'sec-ch-ua': '"Google Chrome";v="93", " Not;A Brand";v="99", "Chromium";v="93"',
'C-Dynamic-Password-Foruser': 'false',
'sec-ch-ua-mobile': '?0',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',
'Content-Type': 'Application/json',
'C-App-Id': 'DCS_APP_001',
'Accept': 'application/json, text/plain, */*',
'client_id': '000000001',
'C-Business-Id': head['C-Business-Id'],
'C-Timestamp': head['C-Timestamp'],
'C-Tenancy-Id': '610000000000',
'sec-ch-ua-platform': '"Windows"',
'Origin': 'https://xxxx.gov.cn',
'Sec-Fetch-Site': 'same-site',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': 'https://xxx.gov.cn/',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
}
res = session.post(url, data=data['keySM2Cipher'], headers=headers).text
print(res)
if __name__ == '__main__':
user = '13888888888'
pwd = '1111111'
getFromdata(user, pwd)
模拟登录:
三、响应解密
1.加密定位
这里使用解密关键字“decrypt”搜索: 打断点,追到上一个堆栈: 打印输出结果: 可以发现这里也是使用了window.DCSAPPClientAPI中的函数进行解密处理,所以接下来找到传入的参数就OK了。
看下o, u, d, t, f参数值:
o, f 固定值:false u在上步骤中发现也是定值:kcn071805buj05k313ql 这里的d参数就是我们提交登录时生成的keyCipher t呢? t = atob(e.data), 看看e.data: e.data是登录的响应返回值,通过atob方法转换成t
参数准备完毕,python调用一下看看:
decres = execjs.compile(jscode).call('getDecrypt', res, data['keyCipher'])
print('响应解密:', decres)
结果:
成了。今天就到这里。
总结
总结:good good xuexi,day day up,少掉头发。
码字不易,如果本篇文章对你有帮助请动动小手点个赞8,谢谢~ 合作及源码获取vx:tiebanggg 【注明来意】 QQ交流群:735418202 喜欢作者的朋友扫下方二维码关注微信公众号,一起学习 UP! :
*注:本文为原创文章,转载文章请附上本文链接!否则将追究相关责任,请自重!谢谢!
|