言成言成啊 | Kit Chen's Blog

与骗子之间的对招

发布于2021-01-08 03:41:51,更新于2021-01-09 03:46:09,标签:life hacker  文章会持续修订,转载请注明来源地址:https://meethigher.top/blog

今天今日校园的脚本挂了,原因是今日校园更改了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();

/**
* 使用指定的姓氏,用xings里面的字,随机生成姓名
*
* @param xing 指定姓氏
* @param length 指定名字总长度
* @return
*/
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);
// 如果s是顿号,就重新再取一次(使用常量比变量,这是推荐的方式)
if ("、".equals(s)) {
continue;
} else {
// 将名 加到 姓名中取
xingming += s;
}
}
return xingming;
}

/**
* 使用xings里面姓氏,用xings里面的字,随机生成姓名
*
* @param length 指定名字总长度
* @return
*/
public static String build(int length) {
// 判断姓名的长度必须大于 2
if (length < 2) {
System.out.println("姓名不能少于2个字符");
return null;
}
/**
* 因为有些姓氏不能拆分(如:复姓),因此选姓氏不能像选名字那样一个一个字选 因此要将xings转成数组
*/
// 先随机选姓氏
Random r = new Random();
String[] xingArr = xings.split(" ");
int index = r.nextInt(xingArr.length);
String xing = xingArr[index];

// 有了姓氏,再调用上面的选名字的方法,就OK了
return build(xing, length);
}

/**
* 随机生成2~3个字的名字
*
* @return
*/
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() {
// ip范围
int[][] range = { { 607649792, 608174079 }, // 36.56.0.0-36.63.255.255
{ 1038614528, 1039007743 }, // 61.232.0.0-61.237.255.255
{ 1783627776, 1784676351 }, // 106.80.0.0-106.95.255.255
{ 2035023872, 2035154943 }, // 121.76.0.0-121.77.255.255
{ 2078801920, 2079064063 }, // 123.232.0.0-123.235.255.255
{ -1950089216, -1948778497 }, // 139.196.0.0-139.215.255.255
{ -1425539072, -1425014785 }, // 171.8.0.0-171.15.255.255
{ -1236271104, -1235419137 }, // 182.80.0.0-182.92.255.255
{ -770113536, -768606209 }, // 210.25.0.0-210.47.255.255
{ -569376768, -564133889 }, // 222.16.0.0-222.95.255.255
};

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日,完美轰炸,看看这个骗子还有啥手段用,哈哈。

正好借此学习技术!

对方数据库已经被轰瘫痪了,其中的需要数据库动态渲染和下单功能都已经瘫痪了。等他修复好了,继续轰!

三、致谢

  1. Java伪造http请求ip地址
  2. x-forwarded-for、x-real-ip、getRemoteAddr()的区别
发布:2021-01-08 03:41:51
修改:2021-01-09 03:46:09
链接:https://meethigher.top/blog/2021/vs-cheat/
标签:life hacker 
付款码 打赏 分享
Shift+Ctrl+1 可控制工具栏