WEB-无境SRC靶场

​ 小六推荐了这个靶场,好久没玩玩靶场了,扫了一眼,题目都是比较感兴趣的,打一打,顺便总结整理一下平时挖洞时思路与技巧。前段时间心血来潮在看GoF设计模式,花费了很多时间用来学习和练习,看这个进度也是要等好久才能输出关于设计模式的文章了,安卓逆向进度也放一放,慢慢来吧。

​ 既然是SRC,那这个系列就点到为止,尽量不使用自动化工具,手工证明即可,不以拿flag为目标。

支付漏洞

​ 这里的支付漏洞还是相当简单的,也是面试中的常被问到的点。

简单支付漏洞之整数溢出

​ 做这道题之前,需要了解一些基础的数值的数据类型:

类型 符号性 字节数 数值范围
int8 有符号 1 -128 ~ 127
uint8 无符号 1 0 ~ 255
int16 有符号 2 -32768 ~ 32767
uint16 无符号 2 0 ~ 65535
int32 有符号 4 -2147483648 ~ 2147483647
uint32 无符号 4 0 ~ 4294967295
int64 有符号 8 -9223372036854775808 ~ 9223372036854775807
uint64 无符号 8 0 ~ 18446744073709551615

​ 可以参考一下月神的这个科普视频: 【最大值溢出漏洞挖掘科普-月神】

​ 就拿int8来举例子吧,有符号的数是通过补码的最高位来表示正负,1是负数,0是正数,那么int8类型的最大值就是0111 1111,如果在这个基础上+1的话,就变成了1000 0000,就是负数中的最小值,通过补码转换就是-128,所以就会出现,int8类型的127+1=-128,然后还有一种情况,这种是正常的补码运算,就是-1 + 1,也就是1111 1111 + 0000 0001 = 1 0000 0000,进位舍弃,结果为0000 0000,也就是0。所以,整数数值就相当于首尾相连。

​ 来分析分析这个场景吧:

​ 现在我们有1000元,目标商品是2400元,通过金额整数溢出来达成购买商品。

个人中心

订单结算

数据包1

​ 分析一下,这里上传了数量,我们能控制的有用参数貌似只有数量,商品单价是2400,看一下参数有什么限制。

数据包2

​ 这里限制死了,只能上传大于等于0的参数,这里尝试上传一个大数
数据包3

​ 推测这里使用的是int32,月神那个视频里也提及了,微信支付使用的也是int32。反复测试一下,总金额没有超过2147483647,尝试进行刚刚好溢出,可能付款的值就小于当前值,数量为q, 2400*q -> 2147483647+2147483648,计算出q的值取整然后+1。

整数溢出

简单支付漏洞之优惠券数量

​ 这个漏洞比较简单啊,成因是上送了优惠券的个数并进行计算,未对购买者持有优惠券数量进行校验。

优惠券数量更改

简单支付漏洞之金额修改

​ 这个漏洞也比较简单,上送了支付金额,推荐后端开发时,不进行上送利率、金额、总价等,只上送产品的id、个数并进行严格的过滤。

金额修改

订单记录

简单支付漏洞之订单编号

​ 这个的思路也十分的清晰,他的交易逻辑就是先上送产品id和数量,生成订单号,然后通过订单号进行扣费,这里能改的也就是数量,测试一下数量是否做了校验。

订单创建

支付订单

订单信息

简单支付漏洞之四舍五入

​ 感觉没有记录的必要。。。 支付记录

简单支付漏洞之优惠券遍历

​ 有问题啊这个靶场,领不了优惠券,但是可以用订单编号那个过,有点失望。。。

越权漏洞

JS不能分析数据又加密,咋整

​ 很简单啊,id越权,然后解JWT,这算非预期?

jwt

get_profile

简单越权漏洞之ID越权

​ 很简单的一个id越权,简单的洞,但是很常见。

订单查询

简单越权漏洞之JS逆向

​ 本靶场需要进行简单的js逆向,挖掘越权查看他人敏感信息漏洞。

​ 来,让我看看是什么js逆向,我觉得都难不倒我。

加密报文

​ 这里一看就是一个对称加密,找到算法和key就好了。

​ 找到了加密文件:

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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
;(function(_0x2f4d, _0x5b7e, _0x8bf6) {
if(false) return;
var _0x5e6c = function(_0x4d21) {
return function(_0x3a18) {
var _0x7c09 = '', _0x1d0f = _0x3a18.split('');
for (var _0x2e50 = 0; _0x2e50 < _0x1d0f.length; _0x2e50++) {
_0x7c09 += _0x1d0f[_0x2e50];
}
return _0x4d21(_0x7c09);
};
};

var _0x3471 = ['b','t','o','a', 'a','t','o','b'];
var _0x6d91 = String.fromCharCode(98,116,111,97);
var _0x8e76 = String.fromCharCode(97,116,111,98);
var _0x9c54 = _0x5e6c(function(_0x6b2d){ return _0x2f4d[_0x6d91](_0x6b2d); });
var _0x3b92 = _0x5e6c(function(_0x1a43){ return _0x2f4d[_0x8e76](_0x1a43); });

var _0x7f38 = function(_0x2c7e) { return typeof _0x2c7e === 'string' ? _0x2c7e : ''; };

var _0x1da4 = function(_0x4f21, _0x7d39) {
var _0x3c5b = 0;
return function(_0x18d2) {
var _0x4e87 = _0x4f21(_0x18d2);
_0x3c5b++;
return _0x7d39 ? _0x7d39(_0x4e87) : _0x4e87;
};
};

var _0x5c82 = (function() {
var _0x6e3d = '';
var _0x9a47 = [67,48,109,112,108,51,120,95,75,51,121,95,70,48,114,95,48,112,51,110,49,100,95,51,110,99,114,121,112,116,49,48,110];
for (var _0x5f21 = 0; _0x5f21 < _0x9a47.length; _0x5f21++) {
_0x6e3d += String.fromCharCode(_0x9a47[_0x5f21]);
}
return _0x6e3d;
})();

var _0x5f34 = function(_0x2d31, _0x4a7e) {
return _0x2d31 ^ (_0x4a7e || 1);
};

var _0x7a92 = function(_0x9e21) {
return _0x9e21.split('').reverse().join('');
};

var _0x4e72 = function(_0x1c94) {
return function(_0x3d76) {
return _0x1c94(_0x3d76);
};
};

var _0x3c8f = function(_0x6e29) {
return _0x6e29.toString(parseInt('100', 4));
};

// 故意添加混淆代码
var _0x7c32 = [];
for(var _0x2e31 = 0; _0x2e31 < 10; _0x2e31++) {
_0x7c32.push(function() { return Math.random(); });
}

var _0x9c21 = function(_0x3e21) {
if(_0x3e21 % 2 === 0) {
return function(_0x7e21) { return _0x7e21 + 1; };
} else {
return function(_0x7e21) { return _0x7e21 - 1; };
}
};

var _0x4a32 = _0x9c21(Math.floor(Math.random() * 10));

_0x2f4d['encryptOpenid'] = (function() {
var _0x3e21 = _0x7c32[3]();
var _0x7e21 = _0x4a32(100);

return function(_0x5d31) {
if (!_0x5d31) return '';

var _0x2e43 = _0x9c54(_0x7f38(_0x5d31));
var _0x7c82 = _0x7a92(_0x2e43);

var _0x9e32 = '';
var _0x1a52 = 0, _0x6c73 = 0;

// 添加无意义的控制流
if(_0x3e21 > 0.5) {
while (_0x1a52 < _0x7c82.length) {
var _0x8e93 = _0x7c82.charCodeAt(_0x1a52);
var _0x4a21 = _0x5c82.charCodeAt(_0x1a52 % _0x5c82.length);
_0x9e32 += String.fromCharCode(_0x5f34(_0x8e93, _0x4a21));
_0x1a52 = ++_0x6c73;
}
} else {
for(_0x1a52 = 0; _0x1a52 < _0x7c82.length; _0x1a52++) {
var _0x8e93 = _0x7c82.charCodeAt(_0x1a52);
var _0x4a21 = _0x5c82.charCodeAt(_0x1a52 % _0x5c82.length);
_0x9e32 += String.fromCharCode(_0x5f34(_0x8e93, _0x4a21));
}
}

var _0x2c83 = _0x9c54(_0x9e32);

// 使用eval增加混淆
var _0x4e92 = eval("Date[String.fromCharCode(110,111,119)]().toString(36)");
var _0x7a21 = eval("Math[String.fromCharCode(114,97,110,100,111,109)]().toString(36).substring(2, 8)");

return _0x9c54(_0x7a21 + _0x2c83 + _0x4e92);
};
})();

_0x2f4d['decryptOpenid'] = (function() {
var _0x3e21 = _0x7c32[7]();
var _0x7e21 = _0x4a32(50);

return function(_0x3e72) {
if (!_0x3e72) return '';

try {
var _0x9a32 = _0x3b92(_0x7f38(_0x3e72));
var _0x1c83 = _0x9a32.substring(6, _0x9a32.length - 8);
var _0x5e92 = _0x3b92(_0x1c83);

var _0x8c32 = '';

// 添加无意义的控制流
if(_0x3e21 < 0.5) {
for (var _0x4a73 = 0; _0x4a73 < _0x5e92.length; _0x4a73++) {
var _0x6e29 = _0x5e92.charCodeAt(_0x4a73);
var _0x2c74 = _0x5c82.charCodeAt(_0x4a73 % _0x5c82.length);
_0x8c32 += String.fromCharCode(_0x5f34(_0x6e29, _0x2c74));
}
} else {
var _0x4a73 = 0;
while(_0x4a73 < _0x5e92.length) {
var _0x6e29 = _0x5e92.charCodeAt(_0x4a73);
var _0x2c74 = _0x5c82.charCodeAt(_0x4a73 % _0x5c82.length);
_0x8c32 += String.fromCharCode(_0x5f34(_0x6e29, _0x2c74));
_0x4a73++;
}
}

var _0x4e73 = _0x7a92(_0x8c32);

return _0x3b92(_0x4e73);
} catch (_0x9c21) {
(function(_0x6e33) {
_0x2f4d.console[String.fromCharCode(101,114,114,111,114)]('n', _0x6e33);
})(_0x9c21);
return '';
}
};
})();

var _0x2e43 = function() {
var _0x7c82 = [];
for(var i = 0; i < 5; i++) {
_0x7c82.push(function(x) { return x * x; });
}
return _0x7c82;
}();

if(![]) {
_0x2f4d['encryptOpenid'] = function() { return ''; };
_0x2f4d['decryptOpenid'] = function() { return ''; };
}

})(this || window, document, function() { return; });

js逆向

​ 传入的openid是_0x5d31,在78行打断点,然后将其修改成1即可进行越权查询。

逻辑漏洞

简单漏洞之组合环境一

靶场目标:买下会员专属商品

由于需要手机号验证码登录,所以做了一个验证码平台在8081端口

提示:此环境组合了两种手法,包括一种基础的手法与前面的靶场:《有个接口隐藏了,找到它》的练习手法,靶场不存在弱口令与验证码爆破,请勿浪费性能

重要:验证码平台不参与漏洞逻辑,仅提供接码功能,预期解不涉及验证码平台本身,也不根据验证码平台能提供的信息去猜测

​ 这题的信息如上,反正我是没找到隐藏接口,太菜了,这种拼接谁能想到啊,将8081的接口拼到80的api上,我服了。

拼接接口

​ 然后用获取到的糖糖账号,登录,更改获取手机验证码的接口参数。

验证码获取

​ 登录后购买,这谁能想到啊,我要给差评。

getflag

简单-任意用户登录二

简单的任意用户登录

滴滴滴滴,你收到了一个电话,来自13900812231,哦原来是四川成都xx单位的客户,他发给你了一个网站,让你测试有没有漏洞?

登录界面

​ 既然题目都给出了任意用户登录了,我猜应该是响应包文直接替换就能绕过,尝试了一下,替换并不能直接进去,也不存在未授权,那么接下来看一下这个忘记密码功能和注册功能,任意用户登录在这里也容易出现。

​ 确实可以通过修改响应包来实现跨步,直接修改账号的密码。

重置密码

​ 然后我尝试修改了题目中给出的手机号,可以修改,但是登录仍然显示封禁中,在我没有思路的时候,我去看了一眼评论区的提示,手机号可以爆破出可以使用的账号

账号枚举

​ 按照刚才的思路,重置一下这个账号,并进行登录

主页

简单逻辑漏洞之任意用户登录

篡改响应包

篡改响应包

​ 篡改响应包,在请求包中加入主页下方的管理员手机号,别问我为什么这样绕,问出题人棉花糖吧。

getflag

SQL注入

真实报告之sql注入

排序注入

​ 一眼排序注入

排序注入

排序注入2

​ 拿flag的话直接拿sqlmap跑吧,这里证明一下存在注入点就可以走了。

XSS

xss+csrf的简单模拟

圣杯页面

​ 依旧圣杯页,注册一个账号

评论页

​ 这个棉花糖怎么这么不正经。。。

​ 这里说是xss+csrf,接管账号的话,直接去找重置密码接口,看看密码重置接口需要的参数是什么。

重置密码

​ 这里重置密码做的很敷衍啊,很简单,直接开始构造xss吧。

csrf

​ 重新创建一个账号,看看是否存在csrf。确实可以更改

评论区

​ 这里也存在糖糖的账号,直接登录试试。

mht个人中心

​ 也是成功登录上糖糖的账号。

信息泄露

有个接口隐藏了,找到它

​ 直接扫目录,扫到了swagger,拼接接口(这个我是真的想不到得拼接admin,看了评论区才知道要这样整,还是太菜了)

拼接接口

总结

​ 这个SRC靶场就这么打完了,这个靶场还是比较简单的,但有些点确实想不到,多练吧,没别的说的,菜就多练。