今天今日校园的脚本挂了,原因是今日校园更改了CpdailyExtension的加密密钥,app又加固了,对于如何获取加密密钥,我就无从下手了。网上一搜,看到有人把加密密钥已经整出来了,不由得惭愧,我好菜啊。
还是好好学技术吧,言归正传。
一、背景 在去年的11月8号,也就是考研备考期间,我收到了一条短信,大致的内容就是我的那张联通卡积分要过期了,赶紧兑换商品。
网页的链接是http://dwz8.cn/OCsGK,点击进去后是http://h5.22b.shop
通过抓包分析,首次访问该网站时,会自动访问https://h5.22b.shop/api/home/user
1 {"code" :200 ,"message" :"操作成功" ,"data" :{"id" :3992308 ,"uuid" :"a53e454f-2e89-468a-90ff-27b898f99e89" ,"score" :6800 ,"createtime" :"2021-01-07T20:03:41.000+00:00" ,"updatetime" :"2021-01-07T20:03:41.000+00:00" ,"status" :0 ,"signdays" :null ,"signstatus" :null ,"expiration" :"2021-01-14T20:03:41.627+00:00" }}
这个就相当于是获取一个账户了,这个账户的用户名就是返回的一个随机uuid。关键是这个账户是有效期的,一周后失效。去年我访问的时候,还是2天失效,可能后来又延长了有效期。
很明显,你下单的东西,一周之后,所有的订单信息都会消失了,到时候,你就算找证据都找不到,很明显是骗子啊。
再看界面,做得这么low,就连学生的课程设计都不如吧?还有测试数据。
这个骗子网站,最秀的不是上面这些,而是他有一个很人性化的客服系统以及微信公众号,关键是还有人在后台帮助你被骗!
之前我还特意找客服说,我要买爱疯12,客服说没有,我把链接 丢给他,他就不鸟我了。
后来才知道,像那种爱疯12的,要付超过3000元,这种的你要是报警的话,是可以立案的,所以他就说没有了,也是考虑到这点吧。
已经确定是个骗子网站了,我又找出了查询订单的接口,https://h5.22b.shop/api/order/select/condition
发现竟然有那么多人被骗!
就想着通过网站备案,找到这个骗子公司。
在域名信息备案系统 中,查到了是深圳市小包菜电子商务有限公司,2020年9月备案。
通过爱企查 ,查到该公司成立与2020年9月1日,目前许可经营项目是无。
我又通过下单的信息,联系了其中一个人,聊天记录放上来吧。内心也想感叹下,做得这么垃圾的平台,比学生的课程设计都low,还是有人上当。果然中国那么多人,人傻钱多的也不少。
很明显啊,这就是个骗子公司啊。
二、轰炸 我是11月8号收到的短信,当时正在做数学题,确定了是骗子网站之后,就开始着手写脚本,顶多也就半个小时吧,就写完了。
那时,我记得他没有姓名唯一验证,也没有uuid唯一验证。当时可以用一个uuid账户提交垃圾数据,疯狂塞他的数据库。因为比较简单,所以完成的较快。
轰炸了一天,大概给他轰了100多万条垃圾数据,第二天一看,脚本凉了,那狗崽子还骂我。特娘的,骗人你还有理了。
之后,我发现他是给数据库加了uuid唯一验证,也就是只能购买一次,原因想想嘛,也挺合理的,毕竟是积分兑换嘛,积分就那么点,你想换多少?
那我就尝试每次请求,向他服务器申请一个uuid,然后继续轰,顺便随机生成姓名和随机生成手机号,代码来源于网络。
NameBuilder.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 import java.util.Random;public class NameBuilder { private static String xings = "赵 钱 孙 李 周 吴 郑 王 冯 陈 褚 卫 " + "蒋 沈 韩 杨 朱 秦 尤 许 何 吕 施 张 " + "孔 曹 严 华 金 魏 陶 姜 戚 谢 邹 喻 " + "柏 水 窦 章 云 苏 潘 葛 奚 范 彭 郎 " + "万俟 司马 上官 欧阳 夏侯 诸葛 闻人 东方 赫连 皇甫 尉迟 公羊" ; private static String mings = "碧凡、夏菡、曼香、若烟、半梦、雅绿、冰蓝、灵槐、平安、书翠、翠风、香巧、代云、" + "友巧、听寒、梦柏、醉易、访旋、亦玉、凌萱、访卉、怀亦、笑蓝、春翠、靖柏、书雪、" + "乐枫、念薇、靖雁、寻春、恨山、从寒、忆香、觅波、静曼、凡旋、新波、代真、新蕾、" + "雁玉、冷卉、紫山、千琴、恨天、傲芙、盼山、怀蝶、冰兰、问旋、从南、白易、问筠、" + "如霜、半芹、寒雁、怜云、寻文、谷雪、乐萱、涵菡、海莲、傲蕾、青槐、冬儿、易梦、" + "惜雪、宛海、之柔、夏青" ; private static Random r = new Random(); public static String build (String xing, int length) { String xingming = xing; Random r = new Random(); while (xingming.length() < length) { int index = r.nextInt(mings.length()); String s = mings.substring(index, index + 1 ); if ("、" .equals(s)) { continue ; } else { xingming += s; } } return xingming; } public static String build (int length) { if (length < 2 ) { System.out.println("姓名不能少于2个字符" ); return null ; } Random r = new Random(); String[] xingArr = xings.split(" " ); int index = r.nextInt(xingArr.length); String xing = xingArr[index]; return build(xing, length); } public static String build () { int length = r.nextInt(2 ) + 2 ; return build(length); } public static void main (String[] args) { System.out.println("\r\n指定姓氏造100个3个字的名字" ); for (int i = 0 ; i < 100 ; i++) { System.out.print(build("廖" , 3 ) + "," ); if ((i + 1 ) % 10 == 0 ) { System.out.println(); } } System.out.println("\r\n不指定姓氏造100个3个字的名字" ); for (int i = 0 ; i < 100 ; i++) { System.out.print(build(3 ) + "," ); if ((i + 1 ) % 10 == 0 ) { System.out.println(); } } System.out.println("\r\n随机造100个名2~3个字的字" ); for (int i = 0 ; i < 100 ; i++) { System.out.print(build() + "\t" ); if ((i + 1 ) % 10 == 0 ) { System.out.println(); } } } }
MobileBuilder.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class MobileBuilder { private static String[] telFirst = "134,135,136,137,138,139,150,151,152,157,158,159,130,131,132,155,156,133,153" .split("," ); public static String getTel () { int index = getNum(0 , telFirst.length - 1 ); String first = telFirst[index]; String second = String.valueOf(getNum(1 , 888 ) + 10000 ).substring(1 ); String third = String.valueOf(getNum(1 , 9100 ) + 10000 ).substring(1 ); return first + second + third; } public static int getNum (int start, int end) { return (int ) (Math.random() * (end - start + 1 ) + start); } }
有了这两个工具类,又有不同的uuid,那么继续轰。
过了一天之后,又出来问题。
我当时一看就反应过来了,这可能是骗子设置的服务器自发的拒绝访问,我当时首先想到的是自己实现一个代理池,但是一想比较麻烦,就放弃了。
直到今天,2021年1月8日,我就想,如何用java伪造ip。
后来发现,原来骗子在服务端的验证ip是通过获取请求头x-forwarded-for的ip来判断的。
至于这个x-forwarded-for跟servlet中的request.getRemoteAddr()获取的是不是一个东西,参考这篇文章
那么我判断ip被封之后,就生成随机ip不就行了。
IpUtil.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import java.util.Random;public class IpUtil { public static String getRandomIp () { int [][] range = { { 607649792 , 608174079 }, { 1038614528 , 1039007743 }, { 1783627776 , 1784676351 }, { 2035023872 , 2035154943 }, { 2078801920 , 2079064063 }, { -1950089216 , -1948778497 }, { -1425539072 , -1425014785 }, { -1236271104 , -1235419137 }, { -770113536 , -768606209 }, { -569376768 , -564133889 }, }; Random rdint = new Random(); int index = rdint.nextInt(10 ); String ip = num2ip(range[index][0 ] + new Random().nextInt(range[index][1 ] - range[index][0 ])); return ip; } public static String num2ip (int ip) { int [] b = new int [4 ]; String x = "" ; b[0 ] = (int ) ((ip >> 24 ) & 0xff ); b[1 ] = (int ) ((ip >> 16 ) & 0xff ); b[2 ] = (int ) ((ip >> 8 ) & 0xff ); b[3 ] = (int ) (ip & 0xff ); x = Integer.toString(b[0 ]) + "." + Integer.toString(b[1 ]) + "." + Integer.toString(b[2 ]) + "." + Integer.toString(b[3 ]); return x; } }
1月7日到1月8日,完美轰炸,看看这个骗子还有啥手段用,哈哈。
正好借此学习技术!
对方数据库已经被轰瘫痪了,其中的需要数据库动态渲染和下单功能都已经瘫痪了。等他修复好了,继续轰!
三、致谢 Java伪造http请求ip地址 x-forwarded-for、x-real-ip、getRemoteAddr()的区别