某站webpack打包JS逆向,keyCipher、keySM2Cipher参数分析

文章目录

  • 前言
  • 一、抓包分析
  • 二、参数解析
    • 1.加密定位
    • 2.参数分析
  • 三、响应解密
    • 1.加密定位
  • 总结


前言

今天来水一篇文章,某站webpack打包类型,登录、数据解密参数keyCipher、keySM2Cipher。本文章仅供学习研究,如若侵犯到贵公司权益请联系229456906@qq.com第一时间进行删除;各位朋友切忌用于一切非法途径,否则后果自行承担!


地址:地址就不放了,主要讲思路。。。

一、抓包分析

老规矩,打开登录框输入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模拟登录,看是否能正常返回响应,登录代码实现:

# -- coding: utf-8 --
# @Time : 2021/9/12 12:35
# @Author : JaJa
# @Email: 229456906@qq.com
# @sinaemail: angelesclippers@sina.com
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
    # print(res)
    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()
    # loginNo, loginPassword, vcode, sessionId

    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:OneSisxoc 【注明来意】
QQ交流群:735418202
喜欢作者的朋友扫下方二维码关注微信公众号,一起学习 UP! :在这里插入图片描述

*注:本文为原创文章,转载文章请附上本文链接!否则将追究相关责任,请自重!谢谢!

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值