起源

2019年年会的到来,当然免不了激动人心的抽奖环节啦,那直接延用上一年的抽奖程序吧,然而Boss希望今年的抽奖程序能够能让所有人都参与进来,一起来抢有限奖品,先到先得,而不是站在那里盯着屏幕。

OK,程序内容大概是这样子,每个人在手机浏览器打开抽奖程序界面,系统会随机给个数字,谁戳屏幕上的圆形最快最准,就能参与抽奖活动,有多少奖品就有多少场battle(仅限手机浏览器打开 & 每人仅限获得一个奖品)

重要的是,年会之前得把程序公布出来,让其他同事想办法作弊,硬件作弊和软件作弊都允许,我们主要分析软件作弊并制定对应防御策略,就像是一场CTF,对方是攻击,我们是防御。

本文有引用他人文章,若有侵权或其它不当,会立即删除。

开发过程

我跟另一个同事完成这个项目,他负责后端,我负责前端,整体采用React+Nodejs+Express+MySQL的架构,这个项目有实时的需求,因此我们用到了socket.io

首先,我们分析了对方作弊的可能:

通过抓包分析,成功伪造点击请求

找到圆形位置,实现高准确率的点击

搞垮其他竞赛者的账号,自己稳步前进

直接搞掉服务器,修改数据库

对于作弊3,账号列表是年会抽奖前10分钟公布的,所以作弊者没有充足的准备时间。

对于作弊4,都是自己人,应该不会那么狠吧...

那么,我们主要针对作弊1和作弊2做了以下防御:

后端防御

校验请求参数是否有效

分析正确点击频率,超过正常点击阀值则作惩罚处理

点击错误次数过多则作惩罚处理

前端防御

使用webpack-obfuscator混淆打包js代码,加大代码分析难度

react-konva画圆形,防止对手轻易获取DOM节点并执行点击事件

圆形的颜色和位置随机,防按键精灵之类的软件

核心websocket请求采用白盒加密

普通请求采用rsa+aes混合加解密

抽奖过程

年会抽奖那天,在大屏幕上面可以看到每个人的点击数,注意到有个同事的按击次数值飚得极快,很明显他作弊成功了,但我想不明白是怎么做到的。于是年会结束后我向他请教,才得知作弊手法。

结果分析

作弊手法如下,非常简单,在手机浏览器的地址栏输入下面一段代码,回车即可执行。跟我一样不知道浏览器地址栏可以执行js代码的童鞋,请看这篇文章浏览器地址栏运行JavaScript代码

javascript:Math.random=function(){return 1;}

由于我在圆形随机位置和随机颜色的设置上用到了Math.random这个方法,此时,他的按击圆形就定死在同一个位置,众人皆动我独静,而且都是正常点击请求,必须赢呀!

// 修改前

function getRandomNumber(min, max) {

const range = max - min;

const random = Math.random();

const num = min + range * random;

return num;

}

代码修补

找到问题所在,很明显我需要找个随机函数方法替换Math.random,于是我google了几篇文章,都提到线性同余生成器(LCG, Linear Congruential Generator),貌似所有运行库都是采用这种算法生成伪随机数,我就把getRandomNumber函数改成下面的模样,问题得到了暂时的解决。

// 修改后

const getRandomNumber = (function() {

let seed = Date.now();

function random() {

//线性同余生成器(LCG, Linear Congruential Generator)

seed = (seed * 9301 + 49297) % 233280;

return seed / (233280.0);

};

return function rand(min,max) {

const range = max - min;

const random_num = random();

const num = min + range * random_num;

return num;

};

})();

经验分享

但是,getRandomNumber的代码功能还是非常容易改,毕竟混淆过的js依旧是裸奔着的,这一点是避免不了的。

比如说,我们都知道知乎可以设置文章的权限,例如禁止转载之类的,有一次我看到这篇知乎文章应对流量劫持,前端能做哪些工作?,想复制代码下来运行下却被告知禁止转载,打开chrome控制台查看代码块内容,可惜代码内容变成富文本内容形式,于是我另寻法子,直接在js上面修改。

首先,定位到复制功能触发的文件和代码段。

第二步,在控制台Sources->Overrides下,打勾Enable Local Overrides

第三步,在控制台下面Sources->Page下,找到刚刚定位到的代码文件,右键Save for overrides

第四步,直接把handleCopy的处理逻辑注释掉,在控制台的Overrides下直接修改,或者在选定保存的本地文件夹中修改。

最后,保存修改后的代码,刷新页面,即可复制成功。

var SriPlugin = require('webpack-subresource-integrity');

var HtmlWebpackPlugin = require('html-webpack-plugin');

var ScriptExtInlineHtmlWebpackPlugin = require('script-ext-inline-html-webpack-plugin');

var ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');

var path = require('path');

var WebpackAssetsManifest = require('webpack-assets-manifest');

var writeJson = require('write-json');

Reference

java公司年会抽奖流程图文件流_年会抽奖程序的一些总结相关推荐

  1. java中的常用的文件流_Java 基础(四)| IO 流之使用文件流的正确姿势

    image.png 一.什么是 IO 流? 想象一个场景:我们在电脑上编辑文件,可以保存到硬盘上,也可以拷贝到 U 盘中.那这个看似简单的过程,背后其实是数据的传输. 数据的传输,也就是数据的流动.既 ...

  2. java 读取浏览器_JAVA读取文件流,设置浏览器下载或直接预览操作

    最近项目需要在浏览器中通过URL预览图片.但发现浏览器始终默认下载,而不是预览.研究了一下,发现了问题: // 设置response的Header,注意这句,如果开启,默认浏览器会进行下载操作,如果注 ...

  3. 接收大文件流_一文搞定 Node.js 流 (Stream)

    stream(流)是一种抽象的数据结构.就像数组或字符串一样,流是数据的集合. 不同的是,流可以每次输出少量数据,而且它不用存在内存中. 比如,对服务器发起 http 请求的 request/resp ...

  4. java开发微信如何维护登录状态_微信小程序中做用户登录与登录态维护的实现详解...

    总结 大家都知道,在开发中提供用户登录以及维护用户的登录状态,是一个拥有用户系统的软件应用普遍需要做的事情.像微信这样的一个社交平台,如果做一个小程序应用,我们可能很少会去做一个完全脱离和舍弃连接用户 ...

  5. java的sdk在哪个文件夹_我的计算机中的Java SDK文件夹在哪里? Ubuntu 12.04

    我知道它的安装,因为当我键入: $java -version 我得到: OpenJDK Runtime Environment (IcedTea6 1.12.5) (6b27-1.12.5-0ubun ...

  6. java按行读取txt文件内容_对txt文件中的内容进行排序

    如果您的文件中每行都有单词或术语,则可能需要对其进行排序.Java Arrays.sort是执行此操作的常用功能.Collections.sort()是另一个不错的说法.这是一个示例和代码. 在文件E ...

  7. java中bin和src文件夹_编译src中的所有文件?

    这是我得到的: /myjava/compile.cmd /myjava/src/a/HelloWorld.java /myjava/src/b/Inner.java /myjava/src/b/Inn ...

  8. h5页面怎么处理文件流_一种H5页面效果生成视频文件的方法及系统与流程

    本发明涉及计算机技术领域,尤其涉及一种H5页面效果生成视频文件的方法及系统. 背景技术: 现有的视频合成方法均是将视频需要合成的各个元素拆分出来,针对每个元素进行合成视频,复杂度高,一旦需要添加新的动 ...

  9. angular8 获取文件流_基于PG12.2实现主从异步流复制及主从切换教程(上)

    概述 今天主要分享一下PG主从异步流复制搭建相关的一些理论内容,仅供参考. 一.PostgreSQL通过WAL日志构建高可靠性原理 PostgrepSQL在数据目录的子目录pg_xlog子目录中维护了 ...

  10. php输出PDF的文件流_怎么用PHP在HTML中生成PDF文件

    译文:使用PHP在html中生成PDF 译者:dwqs 利用PHP编码生成PDF文件是一个非常耗时的工作.在早期,开发者使用PHP并借助FPDF来生成PDF文件.但是如今,已经有很多函数库可以使用了, ...

最新文章

  1. js map遍历 修改对象里面的值_求职季之你必须要懂的原生JS(上)
  2. abaqus最大应力准则怎么用_ANSYS与ABAQUS对比,你选择那个?
  3. 互联网1分钟 |1121
  4. ORACLE TEXT FILTER PREFERENCE(二)
  5. 转 abap中sy-index和sy-tabix使用的时候有什么区别
  6. POJ - 1321 棋盘问题
  7. matlab将满足某一条件的矩阵元素置零
  8. h1、h2、h3标签及strong标签对页面seo的影响
  9. 【网络】SSH本地/远程/动态端口转发
  10. 下拉框value ,selectedIndex
  11. 为什么说:“你不合适学Python?”醍醐灌顶!
  12. 大赛响锣、Call 你来战……对面的开发者看过来!
  13. mmap 系统调用 的使用
  14. [Everyday Mathematics]20150112
  15. C++中this与*this的区别
  16. Account locked due to 10 failed logins
  17. iphone日历怎么跳转日期_苹果手机日历怎么指定日期提醒?
  18. 创建Image图像的几种方法
  19. gb28181协议流媒体实现为rtp荷载ps流,将h264流打包成ps流。
  20. 碰到数学归纳法,一点感受

热门文章

  1. STM32F0xx系列 基于LL库的Flash模拟EEPROM
  2. 《数字图像处理》空间滤波学习感悟1:空间滤波原理
  3. React antd的table表格之嵌套表格
  4. 天涯论坛--只看楼主
  5. 苹果Mac突然没有声音,3 种方法快速检测
  6. c++ 11/14新特性
  7. Pda 数据库同步问题
  8. cmd关闭计算机指令,取消CMD自动关机的命令是什么
  9. imagenet2012 对应 label
  10. 机器学习之ROC曲线绘制