一、基础知识
1、post的几种发包的方式
2、query string和form data的区别
Query String Parameters:
GET请求时,参数会以url string 的形式进行传递,即?后的字符串则为其请求参数,并以&作为分隔符。(有时候post也可以携带请求参数)
FormData:
当发起一次Post请求,若未指定Content-type,则默认content-type为application/x-www-form-urlencoded,即参数会以FormData的形式进行传递,不会显示出现在请求URL中。
Request Payload:
当发起一次post请求,若Content-Type为application/json,则参数会以Request Payload的形式进行传递(数据格式为json),不会显示出现在请求url中
3、抓包后预览数据包
1)post/get & 请求的网址
2)请求标头,是否携带cookie
3)查询字符串参数
4)表单数据
5)响应/预览 (预览返回的响应数据)
如果没有看到应该看到的内容说明可能是加密数据 / 使用类似protobuf格式进行了编码处理,需要对数据进行解析
二、逆向分析实战
输入要翻译的单词进行抓包
这些参数之后写代码都能直接使用的
我们发现只有参数sign是动态生成的,需要特殊处理,根据经验sign是通过加密生成
根据url的特点:https://ifanyi.iciba.com/index.php?c=trans&m=fy&client=6&auth_user=key_web_new_fanyi&sign=B4oBzjcIE%2FCsviWvuvdQbdRriqVIAJSQ%2BxmfU0q7dIE%3D
不难想象最后需要将加密后的结果拼接到sign=后面,所以我们可以搜索sign=,在附近应该会出现加密的算法
进行全局搜索参数位置:
进行局部搜索,找到关键点所在位置
分析附近的js代码:
var r = u()("6key_web_new_fanyi".concat(s.LI).concat(t.q.replace(/(^\s*)|(\s*$)/g, ""))).toString().substring(0, 16);
return r = (0,
_.$Q)(r),
v("/index.php?c=trans&m=fy&client=6&auth_user=key_web_new_fanyi&sign=".concat(encodeURIComponent(r)), {
baseURL: "//ifanyi.iciba.com",
method: "post",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
data: e
})
发现sign参数来自于r,上面找到r,在这个函数打下断点
这里很明显是取参数特征,作为sign的字符串输入
返回的r="2d1e9a93d434e9da"是一个16位16进制,怀疑是使用md5生成的hash值
不妨在控制台输出一波,发现1对应c4ca4,基本就是md5了,注意:控制台测试的时候要在保护u函数的当前作用域当中进行
如果你实在不放心可以在u内部打断点,然后一路f9进行单步走,直到找到MD5之类的特征
函数关系复杂,这样进入u内部:
这一路上走走停停.....一会就找到了
因此第一步就是对参数字符串:"6key_web_new_fanyi".concat(s.LI).concat(t.q.replace(/(^\s*)|(\s*$)/g, ""))进行md5加密,然后取前16位
但是这并不是我们真正的r,真正的r还进行了一步处理:
我们继续跟进l函数
喵的很明显是使用AES对md5值进行再次加密,直接断点安排上
其实我们发现解密函数就在下面😂😂
调试发现e是明文(md5),r是对称加密的密钥(128位(16B)),AES填充参数:mode: n.mode.ECB、padding: n.pad.Pkcs7
加密之后得到正确的sign:
同时我们发现加密函数都统一放到一个文件当中了,如果你想扣代码,也可
同样的,解密函数就是加密的逆过程了
从返回参数来看,我们已经得到解密之后的结果了
然后接下来就是愉快的代码实现过程了!