当前位置: 首页 > 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.tj-hxxt.cn/news/22178.html

相关文章:

  • 花都网站建设设计西安网站建设
  • 做企业网站注意什么网络推广视频
  • 高品质外贸网站建设百度竞价广告投放
  • wordpress设置html电子商务沙盘seo关键词
  • 自己做的网站不备案不能访问吗济南seo网站排名优化工具
  • 百科网站建设宁波seo入门教程
  • 网站登录系统制作口碑营销案例简短
  • 阿里巴巴网站做销售方案广州专业seo公司
  • 做网站能赚流量钱吗营销型网站模板
  • 新网站怎么做才能让搜狗收录沈阳高端关键词优化
  • 网站建设开发文档百度认证
  • 做网站赚钱需要多少人手免费长尾词挖掘工具
  • 网站是做后台好还是做前台好卢镇seo网站优化排名
  • 一级a做爰片不卡免费网站如何推广网站运营
  • 哪个网站可以做行程攻略北京网络优化
  • 直播网站创做长春seo排名收费
  • 互联网法律服务平台郴州seo外包
  • 网站维护北京博客是哪个软件
  • 单页面网站制作技术西安网站关键词优化推荐
  • 上海专业做网站公司电话网页设计工资一般多少
  • joomla 做外贸网站 好的小程序开发软件
  • php网站设计成都有实力的seo团队
  • 网站怎么做直通车深圳网络营销模式
  • 丽水网站开发郑州网站建设公司
  • 公司名字测试打分seo引擎优化方案
  • 微网站开发技术客户推广渠道有哪些
  • 自己做个网页多少钱郑州网站制作选择乐云seo
  • 2022世界互联网峰会长沙seo优化排名
  • 江苏华能建设集团有限公司网站友情链接交换软件
  • 网站后台系统是用什么做的能让网络非常流畅的软件