免责声明
本文章所提到的技术仅用于学习用途,禁止使用本文章的任何技术进行发起网络攻击、非法利用等网络犯罪行为,一切信息禁止用于任何非法用途。若读者利用文章所提到的技术实施违法犯罪行为,其责任一概由读者自行承担,与作者无关。

0x01 前言

研究飞猪旅行HTML5端sign签名过程,以复刻sign签名过程为手段,以查询酒店价格为目标,以学习技术要点、思路以及如何防范为宗旨,展开对飞猪H5端API接口sign签名的研究。

0x02 寻突破口

捕获目标API请求数据包

使用浏览器F12开发者工具开启设备模拟器模式,访问酒店搜索页面,随便搜索一家酒店并进入酒店的详情页面,详情页面请求将全部被捕获于开发者工具的NetWork(网络)选项卡中。

使用Ctrl+F查找页面中对应价格的数字,定位到请求数据包位置。

分析数据包Payload

除了sign签名的一串看似md5密文但实际上又不是md5密文的字段以外,其他字段都很好理解。但如果除了sign签名字段以外的其他字段修改后,sign签名也必须跟着改动,并且是以一个固定的加密规则进行运算后得出来的sign签名字符串,故当务之急需要找到sign签名的位置并把它运算的函数复刻下来,验证加密函数的可用性。

字段 盲猜意义
type originaljson 应该是指请求源类型是json
api mtop.trip.hotel.hotelDetail 告诉服务器需要调用的api服务
v 1.0 API协议版本
params [object Object] 不懂,估计是传值的时候把整个对象传给params了
ttid 201300@travel_h5_3.1.0 应该也是api所属版本号
appKey 12574478 顾名思义,具体用处可以查看淘宝的API开放文档
t 1641821310356 时间戳
sign bb6db2ea281d6422409d820d8223147 经过一系列加密后的sign签名
data(BODY) 一大串JSON文本 这就是真正要传的请求数据文本

定位sign签名位置

需要找到sign签名的运算函数,首先得找到sign签名字符串在哪里赋的值。定位某个请求参数赋值的方法有很多种,有做hook的、有Ctrl+Shift+F的、有用XHR断点的,等等非常多的方法,而且有一些复杂的网站往往需要将这些方法组合使用才能找到某个参数的赋值位置,而在本项目,直接使用Ctrl+Shift+F大法即可。

尝试使用Ctrl+Shift+F大法解决问题是一件性价比很高的事情,前提是你需要猜测网站js源代码参数组合逻辑背后的过程。
本项目例子:URL的sign签名参数,可猜测网站js源代码拼接该参数时使用了"&sign=""sign=""sign"
!!此方法不一定适用于任何网站,若js源码混淆严重,失去了字符串原本的意义,则无法使用该方法查找(往后若有项目可演示其他搜索方法)

现在,尝试使用全局搜索"sign="字符串,马上能定位到可疑的sign签名赋值的代码语句。

可以看到有三条疑似给sign签名赋值的三个js文件,这时候需要根据逆向经验去猜测源码应该会使用哪个去进行sign签名的赋值和加密。但如果没有逆向经验的判断,也可以对搜索出来的三个js文件可疑的代码段进行同时断点,逐个查看分析。

其实可以在Network(网络)选项卡的请求项中查看Initiator里的Request call stack,往往最后出现最多次的js文件,即是请求加密所执行的js文件。在这里,出现最多次的是seed-min.js文件,我们锁定它,然后进行代码段的断点。

8548行做一个断点,重新刷新页面,让前端重新请求一个数据包并把它断点截获。

0x03 顺藤摸瓜寻加密入口

断点被捕获后,在Sources(源)选项卡中,查看被断点后时的Scope(本地变量)CallStack(调用栈),通过这两个信息顺藤摸瓜到加密函数的入口处。

显然,这里的变量e就是我们要找的sign签名字符串,于是我们从这里开始顺藤摸瓜,找到加密入口的地方。

分析方法y(i.data, m, S.a, v)

以下代码段很显然,变量e是由方法y(i.data, m, S.a, v)运算以后得来的,所以我们得进入y的函数内部。

y(i.data, m, S.a, v).then((function(e) {d.push("sign=" + e),n({originPath: f,search: d})
}))

把光标放在方法名上,会显示方法所在位置,点击可以进入到对应的方法的定义位置。

方法y(e, t, n, r)内仍然几个值得断点查看的方法_(n)、方法d([n, t, r, e].join("&"))以及变量n

分析方法_(n)

显然该方法是用来获取cookies内的_m_h5_tk的值,并且执行方法v(n),将_m_h5_tk的值用下划线"_"分割,取左边部分。

分析方法d([n, t, r, e].join("&"))

通过对方法d([n, t, r, e].join("&"))处的断点,查看以下4个变量的值。

参数名 解释
n af5ea7aa071afc99d96745743d3634d0 _m_h5_tk值的左边
t 1641959319288 时间戳
r 12574478 appKey
e {"_fli_newpage":"1","hid":"0","adultNum":2,"shid":1002342 ...... 真正要传的请求数据文本

使用.join("&")将四个变量的值用"&"连接在一起,传送给方法d()

使用单步执行进入方法d()内部,发现其传参变量为e,其内容为:

“af5ea7aa071afc99d96745743d3634d0&1641959319288&12574478&{”_fli_newpage":“1”,“hid”:“0”,“adultNum”:2,“shid”:1002342 …
由于篇幅问题,不将变量e的值全部展开查看,但可以发现,确实是由以上表格的四个值用"&"拼接起来的。

// 方法d()的内部
d = (r = function(e, t) {return e << t | e >>> 32 - t
}
,
i = function(e, t) {var n, r, i, o, a;return i = 2147483648 & e,o = 2147483648 & t,a = (1073741823 & e) + (1073741823 & t),(n = 1073741824 & e) & (r = 1073741824 & t) ? 2147483648 ^ a ^ i ^ o : n | r ? 1073741824 & a ? 3221225472 ^ a ^ i ^ o : 1073741824 ^ a ^ i ^ o : a ^ i ^ o
}
,
o = function(e, t, n, o, a, s, c) {return e = i(e, i(i(function(e, t, n) {return e & t | ~e & n}(t, n, o), a), c)),i(r(e, s), t)
}
,
a = function(e, t, n, o, a, s, c) {return e = i(e, i(i(function(e, t, n) {return e & n | t & ~n}(t, n, o), a), c)),i(r(e, s), t)
}
,
s = function(e, t, n, o, a, s, c) {return e = i(e, i(i(function(e, t, n) {return e ^ t ^ n}(t, n, o), a), c)),i(r(e, s), t)
}
,
c = function(e, t, n, o, a, s, c) {return e = i(e, i(i(function(e, t, n) {return t ^ (e | ~n)}(t, n, o), a), c)),i(r(e, s), t)
}
,
u = function(e) {var t, n = "", r = "";for (t = 0; t <= 3; t++)n += (r = "0" + (e >>> 8 * t & 255).toString(16)).substr(r.length - 2, 2);return n
}
,
function(e) {var t, n, r, l, p, f, d, h, g, m;for (e = function(e) {e = e.replace(/\r\n/g, "\n");for (var t = "", n = 0; n < e.length; n++) {var r = e.charCodeAt(n);r < 128 ? t += String.fromCharCode(r) : r > 127 && r < 2048 ? (t += String.fromCharCode(r >> 6 | 192),t += String.fromCharCode(63 & r | 128)) : (t += String.fromCharCode(r >> 12 | 224),t += String.fromCharCode(r >> 6 & 63 | 128),t += String.fromCharCode(63 & r | 128))}return t}(e),t = function(e) {for (var t, n = e.length, r = n + 8, i = 16 * ((r - r % 64) / 64 + 1), o = new Array(i - 1), a = 0, s = 0; s < n; )a = s % 4 * 8,o[t = (s - s % 4) / 4] = o[t] | e.charCodeAt(s) << a,s++;return a = s % 4 * 8,o[t = (s - s % 4) / 4] = o[t] | 128 << a,o[i - 2] = n << 3,o[i - 1] = n >>> 29,o}(e),d = 1732584193,h = 4023233417,g = 2562383102,m = 271733878,n = 0; n < t.length; n += 16)r = d,l = h,p = g,f = m,d = o(d, h, g, m, t[n + 0], 7, 3614090360),m = o(m, d, h, g, t[n + 1], 12, 3905402710),g = o(g, m, d, h, t[n + 2], 17, 606105819),h = o(h, g, m, d, t[n + 3], 22, 3250441966),d = o(d, h, g, m, t[n + 4], 7, 4118548399),m = o(m, d, h, g, t[n + 5], 12, 1200080426),g = o(g, m, d, h, t[n + 6], 17, 2821735955),h = o(h, g, m, d, t[n + 7], 22, 4249261313),d = o(d, h, g, m, t[n + 8], 7, 1770035416),m = o(m, d, h, g, t[n + 9], 12, 2336552879),g = o(g, m, d, h, t[n + 10], 17, 4294925233),h = o(h, g, m, d, t[n + 11], 22, 2304563134),d = o(d, h, g, m, t[n + 12], 7, 1804603682),m = o(m, d, h, g, t[n + 13], 12, 4254626195),g = o(g, m, d, h, t[n + 14], 17, 2792965006),h = o(h, g, m, d, t[n + 15], 22, 1236535329),d = a(d, h, g, m, t[n + 1], 5, 4129170786),m = a(m, d, h, g, t[n + 6], 9, 3225465664),g = a(g, m, d, h, t[n + 11], 14, 643717713),h = a(h, g, m, d, t[n + 0], 20, 3921069994),d = a(d, h, g, m, t[n + 5], 5, 3593408605),m = a(m, d, h, g, t[n + 10], 9, 38016083),g = a(g, m, d, h, t[n + 15], 14, 3634488961),h = a(h, g, m, d, t[n + 4], 20, 3889429448),d = a(d, h, g, m, t[n + 9], 5, 568446438),m = a(m, d, h, g, t[n + 14], 9, 3275163606),g = a(g, m, d, h, t[n + 3], 14, 4107603335),h = a(h, g, m, d, t[n + 8], 20, 1163531501),d = a(d, h, g, m, t[n + 13], 5, 2850285829),m = a(m, d, h, g, t[n + 2], 9, 4243563512),g = a(g, m, d, h, t[n + 7], 14, 1735328473),h = a(h, g, m, d, t[n + 12], 20, 2368359562),d = s(d, h, g, m, t[n + 5], 4, 4294588738),m = s(m, d, h, g, t[n + 8], 11, 2272392833),g = s(g, m, d, h, t[n + 11], 16, 1839030562),h = s(h, g, m, d, t[n + 14], 23, 4259657740),d = s(d, h, g, m, t[n + 1], 4, 2763975236),m = s(m, d, h, g, t[n + 4], 11, 1272893353),g = s(g, m, d, h, t[n + 7], 16, 4139469664),h = s(h, g, m, d, t[n + 10], 23, 3200236656),d = s(d, h, g, m, t[n + 13], 4, 681279174),m = s(m, d, h, g, t[n + 0], 11, 3936430074),g = s(g, m, d, h, t[n + 3], 16, 3572445317),h = s(h, g, m, d, t[n + 6], 23, 76029189),d = s(d, h, g, m, t[n + 9], 4, 3654602809),m = s(m, d, h, g, t[n + 12], 11, 3873151461),g = s(g, m, d, h, t[n + 15], 16, 530742520),h = s(h, g, m, d, t[n + 2], 23, 3299628645),d = c(d, h, g, m, t[n + 0], 6, 4096336452),m = c(m, d, h, g, t[n + 7], 10, 1126891415),g = c(g, m, d, h, t[n + 14], 15, 2878612391),h = c(h, g, m, d, t[n + 5], 21, 4237533241),d = c(d, h, g, m, t[n + 12], 6, 1700485571),m = c(m, d, h, g, t[n + 3], 10, 2399980690),g = c(g, m, d, h, t[n + 10], 15, 4293915773),h = c(h, g, m, d, t[n + 1], 21, 2240044497),d = c(d, h, g, m, t[n + 8], 6, 1873313359),m = c(m, d, h, g, t[n + 15], 10, 4264355552),g = c(g, m, d, h, t[n + 6], 15, 2734768916),h = c(h, g, m, d, t[n + 13], 21, 1309151649),d = c(d, h, g, m, t[n + 4], 6, 4149444226),m = c(m, d, h, g, t[n + 11], 10, 3174756917),g = c(g, m, d, h, t[n + 2], 15, 718787259),h = c(h, g, m, d, t[n + 9], 21, 3951481745),d = i(d, r),h = i(h, l),g = i(g, p),m = i(m, f);return (u(d) + u(h) + u(g) + u(m)).toLowerCase()
})

至此,加密入口已暴露出来了,即方法d

0x04 验证加密方法可用性

sign签名方法已经拿到手,接下来当然是要验证它是否可用。

Sources(源代码)选项卡左侧的Snippets(代码片段)Tab页中新增一个代码片段,将sign签名方法复制到里面将其保存,并且复制将4个关键参数传入到方法中,然后点击运行(Ctrl+Enter)

重新发送一个请求,然后将H5端真实发送的四个参数的值分别复制到自定义参数中,查看H5端生成的sign值是否与自己新建的代码片段运行的值是一致的,若是一致的则表示该sign签名函数可被使用。

可以看见飞猪H5端产生的sign值与自定义产生的sign值是一致的,都是fd232f8836d8713c277215d71f43820c,说明我们找到的sign签名加密函数是正确的。

0x05 作者的一些话

该篇讲述如何使用浏览器F12开发者工具对一个加密函数的定位与寻找思路,作者强烈反对大家使用该技术进行实质性地爬虫以及其他形式的利用。

请时刻牢记:谁把法律当儿戏,谁就必然亡于法律。

对飞猪H5端API接口sign签名逆向实验相关推荐

  1. 魔方APP项目-01-移动端开发相关概念、移动端自适配、元信息(meta)、开发准备、移动端项目搭建(模拟器调试)、APICloud(APICloud 前端框架,获取服务端API接口)

    一.移动端开发相关概念 1.APP类型 ①.Native APP Native APP又称原生APP,就是我们平时说的手机应用软件. 原生APP 是针对IOS.Android.Windows等不同的手 ...

  2. 酷狗音乐web端API接口数据

    酷狗音乐web端API接口数据 发表于 2017-07-16 | 分类于 api 酷狗音乐web端API接口数据分析 酷狗音乐Web端音乐API接口数据整理,以下接口数据已整理封装在我的基于Node. ...

  3. 移动端API接口优化的术和结果

    最近一直在忙工作的事情,所以文章写得有些少. 有3-5篇文章都是写到一半然后被别的事情给打断了,所以,我得找个时间好好补补. 最近一直在关注移动端接口API的可用性问题,在移动时代这个做这个优化能产生 ...

  4. Android客户端与PHP服务端API接口Token安全验证

    Android客户端: 1.写一个生成token的算法 /*** 生成api接口的token* @param map* @param apikey* @return*/public static St ...

  5. 上传图片-服务端-Api接口定义

    API接口 模型类 系统的文件信息(图片.文档等小文件的信息)在mongodb中存储,下边是文件信息的模型类. 1) 模型如下: package com.learn.framework.domain. ...

  6. php api接口验证签名错误,API常用签名验证方法(PHP实现)

    使用场景 现在越来越多的项目使用的前后端分离的模式进行开发,后端开发人员使用API接口传递数据给到前端开发进行处理展示,在一些比较重要的修改数据接口,涉及金钱,用户信息等修改的接口如果不做防护验证,经 ...

  7. 百度云 php api接口调用 签名计算

    本文介绍百度智能云 计算签名 公共头 调用api接口调用: post请求示例 require "auth.php"; //此文件是百度云官网提供实例,下方可直接粘贴使用. // 第 ...

  8. 常见加密分类以及接口sign签名

    参考文档: 各种加密方式运作原理以及sign签名参考视频 对称加密及RSA非对称加密的原理参考视频1 RSA非堆成加密的原理参考视频2 各种加密方式在线测试网站 参考demo 常见的加密有:对称加密, ...

  9. 调用快递鸟API接口DataSign 签名加密技术文档

    2.1 关于签名 快递鸟和第三方电子商务公司系统进行对接,有一定的安全机制.采用 IP 认证加签名 的方式对接,具体方案如下: 1. 防止数据被篡改 在 POST 请求中会传递 5 个必须 (R) 参 ...

  10. 高德h5地图api接口_html5通过腾讯地图、高德地图、百度地图开发api接口获取坐标对应的周边信息...

    在通过 geolocation 获取到当前的 GPS 坐标后,需要通过"逆地理位置解析"才能得到街道对应的街道.建筑物.周边等相关信息. 下面我使用国内的三家主要的地图厂商(腾讯地 ...

最新文章

  1. python的学习笔记/002-1(2018-5-18 )
  2. Loj 6485. LJJ 学二项式定理
  3. 7 Steps for becoming Deep Learning Expert
  4. 计算机网络第4版潘爱民_学术活动 钱江会计实务精英讲坛预告(第84期)| 何继昌 : 战略视角下之财务分析应用实践 兼选股案例分享...
  5. looper message handler之间的关系
  6. java 数据库连接实例,Java连接各种数据库的实例
  7. Unity Application Block 发布
  8. 周鸿祎评互联网大佬的编程能力:我能排前三,谁排第一?
  9. 3778. 平衡数组-AcWing题库
  10. CC2530之ADC
  11. 服务器系统如何设置屏幕保护,在windows中要设置屏幕保护程序可以使用控制面板的什么功能?_网站服务器运行维护,windows,屏幕保护程序,控制面板...
  12. 全网整合营销能力训练要点
  13. AddressSanitizer: heap-buffer-overflow on address 0x602000000534 at pc 0x00000040699d bp 0x7ffce0afd
  14. IBM副总裁胡世忠:数据是新的自然资源
  15. 如何做好提升领导力培训PPT课件?
  16. 专接本 微机原理简答题 更新
  17. 我的Windows工具之文件查重工具——DuplicateCleaner
  18. 何为非侵入式负荷分解
  19. leetcode526 优美的排列
  20. 拓嘉辰丰电商:拼多多开店绑定的身份证能不能改?

热门文章

  1. 外汇EA黄金外汇避险抗膨胀
  2. 现金流量表补充资料的编制公式
  3. 基于51单片机的多线程操作系统设计
  4. 给Edge添加chrome主题
  5. FPGA自动白平衡实现步骤详解
  6. 【DataBase Notation(1/3)】Notation_Chen, Crow‘s Foot and UML
  7. 社会心理学书籍《别做正常的傻瓜》全书精彩语句摘录
  8. 银耳椰椰——Alpha冲刺Day03
  9. html表格数据按公式自动计算,Word表格怎么自动填充和计算数据
  10. 使用 NVIDIA Kaolin Wisp 重建3D场景