[TOC]

短信验证码

你说我想怎么输入就可以怎么输入

输入手机号,发送验证码,随便输入6六位数就行

当程序员没有校验验证码的正确性的时候就会出现这个问题。

短信验证码暴力突破

考点:短信验证码爆破

首先查看提示:

image-20251103102157477

可以知道是不会真的发送验证码,需要进行前端代码审计来绕过

所以我们可以随便输个手机号试试就行

image-20251103102312921

这里点击发送后抓包

image-20251103102408694

然后输验证码再抓包

image-20251103102456879

为什么会是这个格式呢?我们看看前端代码

send部分:

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
function sendCode() {
const phone = document.getElementById('phone').value.trim();
if (!validatePhone(phone)) {
showMsg('请输入有效的手机号');
shakeInput('phone');
return;
}
showMsg('');
const btn = document.getElementById('sendCodeBtn');
btn.disabled = true;
btn.innerText = '发送中...';

fetch('/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ phone })
})
.then(response => response.json())
.then(data => {
if (data.success) {
showMsg('验证码已发送,请在输入框输入4位验证码');
startCountdown();
} else {
showMsg(data.msg || '发送失败');
btn.disabled = false;
btn.innerText = '发送';
}
})
.catch(() => {
showMsg('网络错误');
btn.disabled = false;
btn.innerText = '发送';
});
}

login部分:

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
function login() {
const phone = document.getElementById('phone').value.trim();
const code = document.getElementById('code').value.trim();
if (!validatePhone(phone)) {
showMsg('请输入有效的手机号');
shakeInput('phone');
return;
}
if (!/^\d{4}$/.test(code)) {
showMsg('请输入4位验证码');
shakeInput('code');
return;
}
showMsg('登录中...');
fetch('/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ phone, code })
})
.then(response => response.json())
.then(data => {
if (data.success) {
showMsg('登录成功');
setTimeout(() => {
showMsg('');
}, 1500);
} else {
showMsg(data.msg || '登录失败');
}
})
.catch(() => {
showMsg('网络错误');
});
}

可以看到都是post请求相关接口,然后传入json格式的数据。所以就明白了传数据的方式

对code字段进行爆破,从0000-9999,最后爆破出来就能拿到flag

image-20251103102551483

验证码居然会出现这个地方?

考点:短信验证码泄露

image-20251103103407208

依然前端代码审计,找到验证码是六位数:

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
function login() {
const phone = document.getElementById('phone').value.trim();
const code = document.getElementById('code').value.trim();
if (!validatePhone(phone)) {
showMsg('请输入有效的手机号');
shakeInput('phone');
return;
}
if (!/^\d{6}$/.test(code)) {
showMsg('请输入6位验证码');
shakeInput('code');
return;
}
showMsg('登录中...');
fetch('/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ phone, code })
})
.then(response => response.json())
.then(data => {
if (data.success) {
showMsg('登录成功');
// 弹出美化后的flag弹窗
customAlert(data.msg, "登录成功");
} else {
showMsg(data.msg || '登录失败');
}
})
.catch(() => {
showMsg('网络错误');
});
}

随便输入手机号,抓包,在响应包里看到code泄露了

image-20251103103851267

直接登录,拿到flag

短信轰炸-好玩但违法

考点:单手机号短信轰炸漏洞

image-20251103104138398

依然是熟悉的登录界面

这次先直接发送验证码,看到是4位数的验证码

image-20251103104543596

抓包也看不到code泄露,于是我们对/send接口进行测试

抓包进行重放,发现可以无限制地重发,于是我们直接对其进行多次重发,在某次响应包中拿到flag

image-20251103105120279

另一种短信轰炸

考点:多手机号短信轰炸

image-20251103105230707

老规矩,输手机号,发验证码,发现是4位数验证码

抓包,响应包没有验证码泄露

进行重放攻击,发现存在短信轰炸,但是看不到flag

我们进行重放时对手机号进行修改,修改后两位就行(遍历00-99),然后就能看到flag

什么你告诉我短信码没有什么用

考点:验证码可以删除绕过造成的任意用户注册漏洞

这次界面有点不同,可以输入密码,但是大差不差,密码先随便输

image-20251103110158386

老流程走一套

发验证码,是6位数的code

看响应包,没有code泄露

抓包进行重放,发现可以进行重放攻击,但是没有flag,两种短信轰炸都测试,还是没有

现在我们测试/login接口,将请求包的code删除,再发包就能登录,拿到flag

短信验证码验证问题

修改相应包,将false改为true即可校验通过

验证码-偷梁换柱

根据18888888888号码获取到验证码,然后修改手机号,给其它手机号进行验证码登录就能拿到flag

短信轰炸-空格绕过

我的解法:直接输入手机号获取验证码后,进行4位验证码爆破就可以了

官方wp:

点击发送验证码之后抓包,在请求体手机号尾部加上空格,重复多次发包即可获得flag:

image-20251127083433789

短信轰炸-仔细看看你的Cookie

点击获取验证码,抓包,将cookie进行爆破修改,给一个手机号重复发包,达成给一个手机号多次发送成功短信验证码

image-20251127085314976

短信轰炸-参数还能这样子做?

目的依然是需要给一个手机号多次发送成功短信验证码。

抓包发现post的数据不是json格式,直接是参数phone=

重复发包会报错。

使用连接符号&,如phone=10000000000&phone=10000000000像这样,多连几个,就能重复发包

注意:这题中已经发送了包的手机号不能再发包,需要修改手机后

image-20251127090426269

短信轰炸-想我了吗

需要给一个手机号多次发送成功短信验证码。

数据是json格式,用过的手机号不能再发送验证码,空格绕过会报错

点击获取验证码,抓包进行重放攻击,虽然会报错,也会出flag

验证码-你没有用随机种子吗

发送验证码,然后重放/getsend接口,能拿到验证码234791,但是登录却没有用

再次发送验证码,收到的验证码是234792,发现是有规律的。

用不同的手机号发送验证码,验证码为 现在的验证码+1

image-20251127092015257

什么,你生成的验证码居然每次?

验证码不能给其他手机号用,且验证码无规律。

第一次验证码:234765

重开靶场,发现第一次的验证码是一样的,都是234765

然后换其它手机号获取验证码,验证码输入234765,得到flag

image-20251127093231869

注意:真实场景复现,发现某个产品,在每次热修复,或者发版的时候,验证码第一次总会是一样的

太牛了,验证码你都能猜到?

考察知识点:
1.随机数是有一个Seed的,也就是种子。
2.如果种子是固定的,那生成的种子就一定是一样的。

验证码的Seed是88888888

发送验证码,第一次是844931,第二次是144475

用python脚本生成:

1
2
3
4
5
6
7
8
9
10
11
12
13
import random

def generate_random_6_digit():
# 设置种子为88888888
random.seed(88888888)
for i in range (10):
# 生成6位随机数 (从100000到999999)
six_digit_number = ''.join([str(random.randint(0, 9)) for _ in range(6)])
print(f"第{i+1}次生成的6位随机数: {six_digit_number}")

if __name__ == "__main__":
# 生成并打印随机6位数
generate_random_6_digit()

这里不是直接生成6位数的验证码,而是由随机生成的6个数(0,9)组合成的6位数验证码。

生成100个,做成字典

换用不同的手机号,点击获取验证码,然后用上面的字典爆破即可

短信验证码验证问题

使用/api/user/check-username接口进行用户名爆破,在响应包里的exists字段能显示用户是否存在

发现zhangwei用户存在

查看源码,找到重置密码的接口

image-20251208112304671

现在知道username是zhangwei,根据代码,构造json格式的请求包发送。根据提示,需要改成强密码

image-20251208112222420

登录即可。

这样就利用接口绕过了验证码验证

code是在客户端生成的

任务: 用不是 18888888888 的手机号和验证码,实现登录成功。

首先下载/sign.js的文件进行反编译,然后代码审计,理解逻辑

首先/sign接口发送数据包到服务端,服务端会生成一个用手机号(固定188)和验证码加密的编码(a值),和一个用于校验的sign签名,同时以响应包的形式发送到客户端;之后客户端通过/send接口,向服务端发送a值和sign签名,如果匹配,就发送验证码成功了。

至此,逻辑已经搞明白了,那怎么攻击达成目的呢?

没错!那就是需要伪造,思路就是:

发送/sign的数据包后,修改响应包,替换我们构造的a值和签名,然后/send发送我们构造的a值和签名进行校验,因为是我们指定的a值和sign,所以肯定校验成功,就达成了在客户端指定手机号和验证码的目的

首先我们需要写出a值的加密脚本,然后用指定手机号13188888888和验证码111111

然后拦截抓包,响应包里替换a值,再写出sign的加密脚本,用a值和时间戳生成一个sign替换响应包里的原sign就可以了

支付漏洞

充值舍入漏洞

充值0.999

请一口气买101个汉堡

解法一:

用所有的钱买优惠卷,然后退款,发现钱全部退回来了,优惠卷只退一张,用这种方式刷汉堡

解法二:

请一口气买101个汉堡

将session进行解密,可以看到wallet字段表示余额数,然后爆破出密钥,然后伪造session。

可以修改金额数,也可以修改优惠卷数量

替换原来的session,就修改了金额,然后就可以一口气买101个汉堡

请一口气买101个汉堡2

抓取退订的包,放进intruder里并发,发现能退很多钱,刷钱买优惠卷再买汉堡

请一口气买101个汉堡3

退款时并发,没用

申请退款时抓包,将数量改为负数就可以

image-20251215182144779

请一口气买101个汉堡4

退款时退款全部,并发,没用

退款n-1张优惠卷,并发,有用(比如买了52张,退款51张,并发)

image-20251215182737814

这样优惠卷数量会是负数,而钱包金额会增加

刷钱购买

请一口气买101个汉堡5

退款时抓包,修改退款金额

image-20251215185201465

优惠卷漏洞

需要领取到多个优惠卷

在领取优惠卷界面抓包,进行重放攻击

交易所钱包划转存在的逻辑漏洞1

需要让你的USDT多起来,刷新页面之后flag就会出现

先根据合规转0.01,再转1元时抓取合规的转账数据包,放进intruder进行并发

交易所钱包划转存在的逻辑漏洞2

需要让你的USDT多起来

并发不行

抓包修改转账金额,改成负数

image-20251208102446860

某SRC微信小程序购物地址的逻辑缺陷

首先添加收货地址,添加新疆的地址,买东西发现不能发货

于是抓添加地址的包,修改省份id等,改成北京的,能购买,但没有flag

image-20251128105027750

需要将省份id后面加个小数点绕过省份限制

image-20251128105439315

你需要会员

开局4块钱,买超过80天会员

先不支付,直接将只能买一次的新人专享添加进订单,添加4次,再支付

image-20251128110742343

哼哼,难不倒我

4块天崩开局

不能连续添加订单。换个思路,采用并发,同添加订单

image-20251128111629482

就是你在修改我商城的支付金额?

任务是99块购买一个199无线蓝牙耳机

先购买一个99块的降噪蓝牙耳机,支付抓包,修改id为1(199无线蓝牙耳机 )

image-20251128113555229

多个客户端怎么都可以

依旧4块天崩开局,拿会员>80

先直接添加订单支付,然后抓包修改cookie字段,它会Set-cookie,然后将原来的cookie替换成这个再进行订单购买支付,循环到买满80天即可

image-20251128162029258

某门诊挂号系统存在签名复用

某门诊挂号系统未检查支付状态。

预约医生,在支付接口处拦截请求包,同时要拦截响应包,修改返回的code码为0即可

image-20251128165713911

image-20251128165842714

某-旅游景点购物系统存在0元购

某-旅游景点购物系统存在0元购,生成票据的时候没有校验实际的购买状态。

支付接口处,拦截响应包修改“type”为0

image-20251128170323627

忘记密码

忘记密码大家都在用短信验证码,你用的什么?

在”忘记密码“处,只需要输入用户名和手机号后四位,直接爆破

用户名为zhangsan,后四位为5678

某学校-任意用户密码重置

在“忘记密码”处,需要输入信息:张三,学号,手机号,验证码、

学号已知,手机号用自己(靶场)的,收到验证码直接进行重置密码为身份证后六位

登录漏洞

万能密码

‘ or ‘1’=’1

初级暴力破解

用户名是admin,直接爆破密码

你能登录这个系统吗

用户名和密码爆破

咦,教务系统,怎么办,我登录不进去

用户为admin,爆破密码

一般教务系统都存在admin用户

你能进入管理后台吗

爆破用户名和密码,zhangsan/12345678

进入后提示秘密在管理员后台

抓包查看,发现User字段,改成system,登录进后台

image-20251128175809160

信息收集

勇士,你能找到域名背后的IP吗

根据图片找域名,然后再找ip

image-20260113172442719

先Google hacking搜索:

image-20260113172520475

查看发现是freebuf平台,然后根据域名查ip就行

勇士,我想知道一个安全论坛的域名注入日期

根据图片发现是先知社区(https://xz.aliyun.com/),然后找到它的顶级域名:aliyun.com

用whois或者站长之家查到注册时间即可

勇士,你知道什么是备案吗

根据图片直到是亚信科技,找到顶级域名进行备案查询

image-20260113173252729

密码会在哪里呢

用CaA搜集到的Param和路径进行组合。顺序和倒序都组合一次,然后进行爆破得到

image-20251128202913795

隐藏的参数

什么参数能改变页面权限呢?

?is_admin=1

隐藏的接口

在 /news/5 路径下的文章里,点击右下角“获取数据”按钮。然后在响应数据包里看到flag

某博客存在SQL注入

注入点在post_id处,直接sqlmap一把梭

image-20251129161518942

越权

越权获取信息

遍历/api/user/profile?id=接口,越权查看信息,在/api/user/profile?id=3找到

听话,咱们只修改自己的密码

登录lisi普通用户,不能拿flag,意思是需要admin

在修改密码处,抓包修改用户名为admin,修改admin密码,然后登录

image-20251129162105670

你知道unionId吗

知识点:

什么是 unionId?

unionId 是微信小程序用户体系中的唯一标识,用于标记同一个用户在不同小程序、公众号之间的身份,便于业务的数据互通和账号打通。

每个 unionId 唯一对应一个微信用户,无论在多少个小程序或公众号里都是一样的。
通过 unionId,平台可以识别和管理用户,实现跨应用的数据联动和用户身份识别。
只有满足“同主体下的多个应用”且用户完成授权登录后,才会返回 unionId。

示例: oHkFz5aQgvp9cA1l2XkT9D3j4RwA

在“排行榜”里查看源码,拿到admin的unionId

image-20251129163035995

某酒店服务任意用户登录接管

利用一处信息泄露二要素,结合未验证的响应包打出一套有效的任意用户登录接管;

在“我的宾客意见”中的包里发现一个接口

image-20251129164957133

进行越权检测,能找到3个手机号,然后用这三个手机号进行验证

在用官方给的手机号验证时,能看到响应包的情况。里面有一个base64编码。

image-20251129165233468

1
2
3
MDU3MjAzMHwxODg4ODg4ODg4OA==
解码:
0572030|18888888888

于是拦截响应包,替换手机号然后base64编码,放包就能验证成功,查看到别人的会员权益

WebSocket也可以有越权

有两个已连接,而我们是参数2

image-20251208105522685

首先在websocket记录里可以看到

image-20251208105417660

首先是客户端向服务端发送websocket连接请求,其中带有一个参数2。

将这个包发送到重放器,修改参数为1,然后重连,发送包

image-20251208105921160

image-20251208105953178

未授权漏洞

修改密码你不去校验登录吗

image-20260113174742932

直接使用接口修改密码

注意将Content-type修改成json

垂直越权任意添加用户

在登录口查看源码,找到了前端一个添加用户的函数接口

image-20251129170953545

直接浏览器控制台运行该函数添加就行

某-商户注册网站存在响应码绕过(接口未授权)

某-商户注册网站存在响应码绕过(接口未授权),表型显示是响应码,但是实际上是接口未授权。

在“商户信息”处抓取响应包,修改“success”字段为true,就能绕过

在”已录入门店“里搜索“深圳”的,然后在包里找到flag

图片验证码

形同虚设的图形验证码

有时候开发,会写两套图形验证码流程,一套是在生产运行阶段必须使用正确验证码才能通过服务器校验。另外一套是在测试 SIT 环境下,把验证码设置为只要是 null 或者是空都可以登录验证码置为空,提高开发工作效率。还有的时候,将验证码修改为 true 就好了。

把验证码置空即可

image-20251201201434015