当前位置: 首页 > news >正文

菲律宾菠菜网站开发足球队世界排名榜

菲律宾菠菜网站开发,足球队世界排名榜,诸城网站建设定制,小型玩具企业网站建设初期阶段任务前言 之前华为商城放出 Mate60 手机时, 想给自己和家人抢购一两台,手动刷了好几天无果后,决定尝试编写程序,直接发送 POST 请求来抢。通过抓包和简单重放发送后,始终不成功。仔细研究,发现 Cookie 中有一个名为 devic…

前言

  • 之前华为商城放出 Mate60 手机时, 想给自己和家人抢购一两台,手动刷了好几天无果后,决定尝试编写程序,直接发送 POST 请求来抢。
  • 通过抓包和简单重放发送后,始终不成功。仔细研究,发现 Cookie 中有一个名为 device_data 的数据比较可疑,看起来是加密后的 base64, 很有可能服务器是使用这些值进行了验证。于是决定研究一下,看是否可以破解并用于秒杀。
  • 最后虽然研究出加密算法,并尝试用于秒杀,但由于仍然有其他的限制,暂时放弃,并将相关信息开源。
  • 华为的兄弟姐妹们需要辛苦更改算法了 😃
    在这里插入图片描述

查找 device_data 的生成位置

通过搜索,定位到名为 cp_20230815/…/ars_event.js 的文件,里面有对 ‘device_data’ 赋值的操作,那么加密算法就在这里了。
补充信息: 最新版本的地址已经是 cp_20231215/…/ars_event.js, 但内容没有改变。
在这里插入图片描述

算法分析

初看 ars_event.js , 是进行过混淆的, 简直和天书一样, 而且以前也没怎么用过 js, 不知道怎么下手。不过好在知道 js 的所有源码都在里面, 只要肯花一点时间, 必然是能解析出来的。

于是开始分析, 此处省略一万字。。。

功夫不负有心人,断断续续经过一两周的时间,总算把算法反推出来,并且编写了 java 代码进行验证和 POST 秒杀。虽然事后证明,服务器还有其他验证方式没有破解(比如 IP、UID 验证?),并发10个线程请求, 有4个给我返回非法请求。。。)

算法解释

  • device_data 的数据分两部分:
    • 最前面的 *2k 常量 + 从 479752 中选出的两个数(间隔 3)
    • 要加密的字符串先 base64, 按 4 个字符进行编码
      • 然后在前面加上 8 个随机字符
      • 最后再按 8 个字符为一组的方式编码.

源码

  • 因为源码是从 js 中反推出来的, 主要是为了满足和原有的算法一致, 命名和写法上就比较乱.
/*** device_data 的加密/解密 算法* https://res.vmallres.com/cp_20230815/js/common/risk/ars_event.js* https://res.vmallres.com/cp_20231215/js/common/risk/ars_event.js*/
@Slf4j
public class ArsEventCrack {//获取华为 function _0x272042 函数中,对字符串加密时采用的位置索引列表public LinkedList<Integer> GetEncodeStringIndexArray(int strLength, int blockSize){//最后4字节保持原样int charArrayLength = strLength - 4;//String[] charArray = strInput.substring(0, strInput.length() - 4).split("");LinkedList<LinkedList<Integer>> tmpArray = new LinkedList<>();for(int i = 0; i < blockSize; i++){tmpArray.add(new LinkedList<>());for(int j = 0; j < charArrayLength; j++){int _tmpVal_1 = j * 2 * (blockSize - 1) + i;int _tmpVal_2 = 0;if (_tmpVal_1 < charArrayLength){tmpArray.get(i).add(_tmpVal_1);}if (i != 0) {_tmpVal_2 = j * 2 * (blockSize - 1) - i;if (_tmpVal_2 < charArrayLength && _tmpVal_2 > 0) {tmpArray.get(i).add(_tmpVal_2);}}if(_tmpVal_1 > charArrayLength || _tmpVal_2 > charArrayLength){break;}}}//log.info("tmpArray={}", tmpArray);//排序和删除重复数据List<List<Integer>> sortedDistinctLists = tmpArray.stream().map(linked -> linked.stream().sorted().distinct().collect(Collectors.toList())).collect(Collectors.toList());LinkedList<Integer> allPositions = new LinkedList<>();sortedDistinctLists.forEach(integers -> allPositions.addAll(integers));return allPositions;}public String EncodeString(String strInput, int blockSize){LinkedList<Integer> allPositions = GetEncodeStringIndexArray(strInput.length(), blockSize);StringBuilder sb = new StringBuilder();for (Integer pos : allPositions) {sb.append(strInput.charAt(pos));}sb.append(strInput.substring(strInput.length() - 4));String result = sb.toString();//log.info("result={}", result);return result;}public String repeatString(String str, int times){if (times <= 1){return str;}StringBuilder sb = new StringBuilder();for (int i = 0 ; i < times; i++){sb.append(str);}return sb.toString();}public String DecodeString(String strInput, int blockSize){//除了最后4个字节的,生成指定长度, 然后获取随机字符串位置索引, 并对应替换.int encodeLength = strInput.length() - 4;char[] chars = repeatString("0", encodeLength).toCharArray();LinkedList<Integer> allPositions = GetEncodeStringIndexArray(strInput.length(), blockSize);int index = 0;for (Integer pos : allPositions) {chars[pos] = strInput.charAt(index);index++;}String strResult = String.copyValueOf(chars) + strInput.substring(encodeLength);return strResult;}//再次调用就会恢复public String BlockString(String strInput, int blockSize){String strResult = "";String strWithoutLast4 = strInput.substring(0, strInput.length()-4);int blockCount = strWithoutLast4.length() / blockSize;for (int i = blockSize; i > 0; i--){String tmp = strInput.substring((i - 1)*blockCount, i*blockCount);strResult += tmp;}strResult += strInput.substring(strInput.length()-4);return strResult;}public String DecodeDeviceDataString(String strEncodedDeviceData){//去除前面的 *2k47 一类的随机开头String remove2KHeader = strEncodedDeviceData.substring(5);//第一次解码String outerDecode = DecodeString(remove2KHeader, 8);//解码出来, 前面8个字节是随机值String firstUnBlock = BlockString(outerDecode, 4);String realFirstBlock = firstUnBlock.substring(8);//再次解码,此时解出来的就是 base64String innerDecode = DecodeString(realFirstBlock, 4);String strOriginal = new String(Base64.getDecoder().decode(innerDecode));return strOriginal;}public String Get2kHeader(){//*2k92String strInput = "479752";int randomIndex = new Random(System.currentTimeMillis()).nextInt(3);return "*2k" + strInput.charAt(randomIndex) + strInput.charAt(randomIndex + 3);}public String EncodeDeviceDataString(String strEncodedDeviceData){String strBase64 = Base64.getEncoder().encodeToString(strEncodedDeviceData.getBytes());String innerEncode = RandomStringUtils.randomAlphanumeric(8) + EncodeString(strBase64, 4);String strBlocked = BlockString(innerEncode, 4);String strEncodeDeviceData = Get2kHeader() + EncodeString(strBlocked, 8);return strEncodeDeviceData;}@Testpublic void testAstEventCrack(){log.info("Get2kHeader={}", Get2kHeader());String strOriginal = "ABCDEFGHIJKLMNOPQRSTWVXYZabcdefghijklmnopqrstuvwxyz123456789";int blockSize = 8;String strEncoded = EncodeString(strOriginal, blockSize);String strDecoded = DecodeString(strEncoded, blockSize);log.info("strEncoded={}, strDecoded={}", strEncoded, strDecoded);Assert.assertEquals(strOriginal, strDecoded);String strBlocked = BlockString(strOriginal, blockSize);log.info("strBlocked={}", strBlocked);String strUnblocked = BlockString(strBlocked, blockSize);log.info("strUnblocked={}", strUnblocked);Assert.assertEquals(strOriginal, strUnblocked);}@Testpublic void TestDeviceData(){if(true){//只解密String strEncodedDeviceData = "*2k75xxxxxx";  // 此处输入通过 F12 或抓包获取的 device_data 字符串,运行后即可解密String strDeviceData = DecodeDeviceDataString(strEncodedDeviceData);log.info("strDeviceData: {}", strDeviceData);}if(false){//加密后再解密String strOriginalData = "";  //输入想要加密的字符串//String strOriginalData = GetDeviceFingerPrint() + "_" + "[object Object]";String strEncode = EncodeDeviceDataString(strOriginalData);String strDecode = DecodeDeviceDataString(strEncode);log.info("strDecode:{}", strDecode);Assert.assertEquals(strOriginalData, strDecode);}}
}
http://www.hkea.cn/news/201347/

相关文章:

  • 东莞百度提升优化优化推广网站推荐
  • 查企业网站有哪些站长统计app软件
  • 做a高清视频在线观看网站济源新站seo关键词排名推广
  • 刚做的网站怎么搜索不出来百度seo收录软件
  • 视频拍摄app站长工具seo综合查询广告
  • 新闻单位建设网站的意义武汉seo推广优化
  • 低价网站公司软文怎么写
  • 东莞市建设公共交易中心网站百度官网首页
  • 如何建立的网站能争钱优化营商环境 助推高质量发展
  • 做百度网站营销型网站建设排名
  • 网站域名被黑国际新闻最新消息战争
  • 苏州网站开发公司济南兴田德润厉害吗网络自动推广软件
  • 广药网站建设试卷株洲最新今日头条
  • 网站建设管理考核办法微信推广平台怎么做
  • 网站新闻模块代码网络推广有哪些常见的推广方法
  • 合肥大型网站如何推广普通话
  • 高端网站制作软件怎么样推广自己的店铺和产品
  • 无障碍浏览网站怎么做关键词seo排名优化推荐
  • wordpress 247seo推广系统
  • 做深圳门户网站起什么名字好泰州seo外包公司
  • 网站视频上传怎么做百度站长平台论坛
  • wordpress农业模板下载小时seo
  • 做网站语言排名2018发帖推广哪个平台好
  • 销氪crmseo入门讲解
  • 蒙阴哪有做淘宝网站的钓鱼网站制作教程
  • 网站如何做导航条下拉菜单怎么做百度网页
  • 网站开发都做什么平台推广精准客源
  • 网站建设共享ip宁波seo搜索引擎优化
  • 学校网站建设必要性搜索引擎排名
  • 哪里有做区块链网站的百度网址大全在哪里找