
简介一份围绕SQL注入攻防的完整大作业资料包面向网络安全方向学生、数据库初学者以及想动手搭建漏洞靶场的开发者。资源以自建简易SQL注入漏洞平台为主线覆盖报错注入、布尔盲注、时间盲注、联合查询等常见类型系统讲解注入点探测、参数化查询、输入验证、最小权限等防御手段适合作为课程设计报告或实战入门素材。压缩包共15个文件包含5个PHP示例脚本、5个XML配置、1个school.sql数据库备份、1份DOC实验报告、1份PPT攻防演示整体大小6.67MB。PHP脚本模拟了存在注入漏洞的查询接口SQL文件提供含学生、课程信息的练习数据库便于进行盲注与联合查询等实操DOC报告详细记录实验过程与防护总结PPT以图文形式拆解攻击步骤和防御方案。已有301人学习下载可帮助学习者在动手操作中理解SQL注入原理并掌握可迁移到实际开发的防护技能。1. SQL注入大作业报告一套能跑通攻击链和修复链的本地靶场SQL注入是数据库和网络安全课程里的大作业常客原理层面人人都会讲但真到动手阶段十个人里有八个卡在环境起不来、SQL语句报错、回显对不上。这份SQL注入大作业报告.zip里装着school.sql数据库备份、sql1.php到sql5.php五个注入点脚本、一份SQL大作业报告.doc和一份SQL注入攻防演示.pptx正好凑齐攻击演示—实验报告—答辩PPT的完整闭环。它解决的不只是能看懂原理而是让你在本地把五个PHP文件部署好之后逐个演示字符型注入、数字型注入、盲注、登录点注入和过滤绕过再对照文档里的修复方案改代码。适合三类人要交数据库大作业的在校生、准备安全岗面试想自己搭靶场的求职者、还有要在团队里做内部安全分享但不想从零写Demo的从业者。边界也得提前说清这套东西只建议跑在自己电脑的本地环境里用来学习和做防御验证别拿去套真实业务系统。2. 先把攻击面理清五个PHP脚本分别对应哪类SQL注入拿到资源先别急着配置环境花半小时把sql1.php到sql5.php这五个文件过一遍后面调参数会顺手很多。自建靶场的价值就在这每个文件是一个独立的注入点攻击类型不重样报告里也好编排章节。我从文件命名和摘要里的描述反推了一下这套靶场的设计思路大概率是一个页面一个漏洞类型下面逐个拆。2.1 sql1.php与sql2.php字符型union注入和数字型注入的边界sql1.php是最典型的字符型GET注入点代码结构通常是接收id参数拼进WHERE子句然后把查询结果直接回显到页面上。常见写法长这样?php // sql1.php —— 字符型 GET 注入点直接拼接用户输入结果回显 $id $_GET[id]; $conn mysqli_connect(localhost, root, root, school); $sql SELECT * FROM student WHERE id $id; $result mysqli_query($conn, $sql); if ($result) { while ($row mysqli_fetch_assoc($result)) { echo $row[name] . - . $row[class]; } } ?关键在第二行和第五行$_GET[id]原样取参第六行用单引号把变量包起来拼SQL。mysqli_connect的参数依次是主机、用户名、密码、库名这套靶场的默认配置大概率就是root/root后面章节会讲怎么改成你自己的环境。攻击时在URL里传id1 and 11单引号会先闭合掉原来的字符串注入点立刻暴露。sql2.php则换成了数字型$id (int)$_GET[id]这类写法也可能是直接WHERE id $id意味着你不用考虑引号闭合直接拼数字和union即可。这两个文件的对照价值大于单独价值同一个页面结构一个加了引号一个没加正好给报告里的字符型注入与数字型注入的区别当实验素材。测试时先用id1看是否报错再用id1 order by 5--逐字段数试探回显正常就说明字段数大于等于5为后面的union查询做准备。2.2 sql3.php到sql5.php盲注、POST登录注入和简单过滤sql3.php设计成盲注场景的概率很高。它不会把查询结果直接回显只返回查询成功或无记录这类布尔状态甚至干脆不返回任何内容。判断是否存在注入点要靠id1 and 11与id1 and 12两个请求的页面差异来猜这在报告里属于基于布尔的盲注工作量比sql1大不少。适合放结论能回显的union注入好测盲注才考验耐心。sql4.php则是POST型登录注入页面里一般有一个账号密码表单提交逻辑是SELECT * FROM user WHERE username$name AND password$pass。这类注入点用浏览器地址栏测不了得靠Burp Suite抓包或curl命令构造POST请求。注意sql4.php查的表和sql1.php不同school.sql里要同时有student表和user表日志里才会好看。sql5.php是加了过滤但仍可绕过的典型代表。我估计过滤逻辑是用preg_replace把select、union、and等关键词替换为空字符串或者用addslashes转义单引号。这类代码在报告里的写法最有意思需要补充说明为什么过滤了不等于防御了——比如SELECT被删掉之后SELSELECTECT经过一次替换就变回SELECT。这就是热搜里常说的SQL注入绕过虽然经典但面试官爱考。?php // sql5.php —— 带简单过滤的注入点用于演示黑名单过滤的绕过原理 $id $_GET[id]; $id str_ireplace(array(select, union, and, or), , $id); $sql SELECT * FROM student WHERE id $id; // 后续查询与回显逻辑同 sql1.php ?这段代码的说明点在注释里str_ireplace是大小写不敏感替换看起来把危险词都滤了但你输入selselectect时第一次替换把中间的select删掉剩下的部分又拼成select黑名单直接失效。报告里可以拿这个当为什么推荐白名单校验和参数化查询的引子。2.3 从文件名反推整套靶场的设计思路五个PHP文件同一目录、school.sql统一管理数据说明这个靶场设计时考虑了上课演示的连贯性先从sql1.php教最基本的回显注入再逐步加难度最后用sql5.php引出过滤绕过。配合SQL大作业报告.doc里的实验记录每章正好对应一个文件。如果你接触过dvwa或pikachu靶场会发现这里的逻辑高度相似只是dvwa的SQL注入模块分得更细sqlilab平台则把关卡拆成了SQLi-Labs那样有序渐进的结构。这套自建靶场相当于把最核心的几关抽出来塞进一份能交作业的文档里。判断五个文件与报告章节的对应关系时打开doc看目录结构比猜更准。3. 把环境搭起来school.sql导入与PHP连接配置的完整步骤这章是很多新手第一次翻车的地方。SQL注入原理说得头头是道结果PHP环境起不来或者数据库导入后中文乱码一下午就耗在环境上。我先给一套我自己反复用过的组合Windows PHPStudy或WAMP二选一Apache MySQL PHP 7.x数据库管理工具用phpMyAdmin。这套组合拿来做靶场演示足够不必上宝塔或Docker。3.1 环境选型PHP版本为什么不能太高biggest坑是PHP版本。网上很多旧靶场代码还在用mysql_connect函数写这套资源里已经是mysqli_connect说明原作者至少考虑了兼容性但PHP 8.0以上对动态特性和隐式类型转换的收严仍可能导致某些写法在严格模式下直接抛警告或致命错误。我建议装PHP 7.4或7.3长期支持版兼容性最好。如果你的机器里只有PHP 8.x不用急着换先跑一遍看报错通常改一两处写法就能解决。Apache端口默认80如果本机被IIS或其它服务占用启动前先改httpd.conf里的Listen字段不然服务起不来。下面是环境参数参考表按我自己的使用习惯整理组件推荐配置说明PHP7.3 或 7.4兼容mysqli写法避开PHP 8的严格类型问题Web服务器Apache 2.4PHPStudy自带无需额外配置MySQL5.7 或 8.0school.sql在这两个版本下均测试可用数据库管理phpMyAdmin导入sql文件省事可视化3.2 导入school.sql命令行和phpMyAdmin两种方式拿到school.sql后第一步是建库并导入。phpMyAdmin里操作最简单登录后点导入选择sql文件执行即可。但如果你习惯命令行建议直接用以下命令速度更快报错也更直观mysql -u root -p -e CREATE DATABASE IF NOT EXISTS school DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; mysql -u root -p school school.sql第一行创建数据库并强制指定utf8mb4字符集第二行将备份文件导入。-p参数会提示输入密码注意root密码必须和PHP连接配置一致。导入完成后用命令查看表结构确认数据正常mysql -u root -p -e USE school; SHOW TABLES; SELECT COUNT(*) FROM student;看到student表且行数不为0说明数据库侧已就绪。如果报了Unknown database或Table doesnt exist多半是导入顺序或库名不一致删掉库重来一遍即可。3.3 连接配置把数据库账号统一写进一个文件sql1.php到sql5.php里如果每个文件都写了一遍连接参数改密码时就得改五个地方很容易漏。第二个方案是抽一个公共配置文件比如叫config.php五个脚本统一include它。资源包里没明确列这个文件但按工程习惯我会自己建一个?php // config.php —— 统一数据库连接配置所有注入点脚本共用 $host 127.0.0.1; $port 3306; $user root; $pass root; $db school; mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); $conn mysqli_connect($host, $user, $pass, $db, $port); mysqli_set_charset($conn, utf8mb4); ?mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)这一行作用是把SQL错误从静默返回改成直接抛异常开发阶段能看到具体错误排错效率高。上线演示时如果不想暴露报错信息可以注释掉这行。mysqli_set_charset($conn, utf8mb4)解决乱码问题很多人在网页里看到问号或空白就是少了这一步。然后把sql1.php里的连接代码替换成require config.php;其他文件同理。3.4 用curl验证第一个注入点环境配好后打开浏览器访问http://localhost/sql1.php?id1正常回显一条学生记录就说明部署成功。接下来验证注入点是否真实存在用curl比浏览器更稳因为能直接看到响应头和完整请求curl http://localhost/sql1.php?id1 curl http://localhost/sql1.php?id1 order by 5-- curl http://localhost/sql1.php?id-1 union select 1,2,3,4,5--第一条命令应该在页面里触发SQL语法错误或异常回显第二条命令如果请求时长和返回内容与正常id1有差异说明order by生效第三条命令的union select会尝试把第2、3、4、5列的数据回显到页面。参数说明--是URL编码后的空格加注释符把后面的SQL语句注释掉避免闭合错误。若curl探测不成功优先检查config.php里的连接信息再确认Apache根目录是否指向了这套PHP文件所在文件夹。4. 把报告和PPT用起来从实验记录到答辩演示的复现流程包里的SQL大作业报告.doc和SQL注入攻防演示.pptx不是摆设但直接用原文件交作业容易翻车——里面大概率带着原作者的环境信息、截图和实验数据。正确用法是拿它当提纲按自己的环境重新跑一遍替换截图和数据。4.1 报告结构拆解实验目的、攻击过程、修复方案三块这份报告我拆下来大概是三大部分先讲SQL注入定义和危害再按sql1到sql5的顺序记录攻击过程最后给出参数化查询、输入验证、最小权限等防御措施。前一部分是凑字数的理论基础真正值钱的是中间的攻击记录和最后的修复代码对照。建议你在doc里找实验结果或测试用例段落照着那里的SQL语句在本地靶场重新跑把回显结果截图替换成你自己的数据量不大个把小时能搞定。下面用表格把资源内文件与实验报告章节的对应关系列一下方便你规划改动范围文件对应报告章节实际操作school.sql实验环境与数据准备导入本地MySQL确认表和记录sql1.php / sql2.php字符型与数字型union注入用curl复现报错与union回显sql3.php盲注与布尔判断对比正常与异常请求页面差异sql4.phpPOST型登录注入Burp Suite抓包改参sql5.php过滤绕过与缺陷分析大小写绕过或双写关键字验证4.2 演示PPT的使用方式先跑代码再补截图PPT大概率是原作者答辩时用的版本里面讲攻击步骤时配的截图如果和你的环境不一致答辩时老师一问就露馅。更稳的做法是把自己跑出来的页面截图替换掉对应PPT页攻击请求报文用Burp Suite重放录一份新的。对你来说这是把别人的作业变成自己的作品最关键的一步。演示流程我建议按这条线走先用sql1.php展示union注入拿到全部数据再用sql5.php做过滤绕过演示最后切到修复版代码跑同一个payload页面不再回显敏感数据。这个流程12分钟内能讲完节奏也符合答辩场景。如果你之前用过CTFHub或靶场平台练过题会发现这套流程里的思路和真题基本一致只是数据换成了学校库讲起来更贴近课程背景。4.3 把修复方案写进报告参数化查询与最小权限报告最后一定要有防御部分这部分写得越具体越加分。最常见的修复方式是预处理语句也就是把SQL模板和参数分开传避免拼接。下面是针对sql1.php的修复版示意?php // sql1_fixed.php —— 使用预处理语句参数与SQL模板分离 $id $_GET[id]; $conn require config.php; $stmt $conn-prepare(SELECT * FROM student WHERE id ?); $stmt-bind_param(i, $id); $stmt-execute(); $result $stmt-get_result(); while ($row $result-fetch_assoc()) { echo htmlspecialchars($row[name] . - . $row[class]); } ?bind_param(i, $id)里的i表示整数类型如果你处理的是字符串字段就换成s。htmlspecialchars做输出转义防止XSS串扰。报告里写这段时我建议附一张改造前后的对比表同一payload在sql1.php和sql1_fixed.php下的响应差异一页纸讲清攻击原理和防御机制这个结构答辩时很讨喜。5. 本地靶场翻车排查五个高频踩坑点与修复方式下面五条踩坑记录来自我自己在Windows和macOS上反复搭建这类靶场的血泪经验每条都按现象、原因、解决三步写基本覆盖新手会撞上的大部分问题。5.1 页面白屏或报mysqli_connect(): Access denied for user现象浏览器访问sql1.php完全白屏或者直接显示数据库连接失败。原因PHPStudy自带的MySQL默认用户名可能不是root或者root密码不是root和config.php里的参数对不上。另一个隐藏坑是MySQL 8.0默认用caching_sha2_password认证而PHP 7.3以下的mysqli客户端不支持这种加密方式连接直接被拒。解决先用mysql -u root -p命令行验证账号密码是否能登录能登录就修改config.php里的$pass。验证不了就重置MySQL密码或者在phpMyAdmin里把用户认证插件改成mysql_native_password。改完记得重启服务连接池不会自动刷新。5.2 中文乱码页面显示问号或空白现象student表里的姓名和班级字段在数据库工具里看是正常的页面上却显示成????或直接缺失。原因school.sql导出的字符集和PHP页面声明的字符集不一致。典型情况是sql文件里是latin1而页面用了UTF-8输出。解决运行SHOW VARIABLES LIKE character_set%;查看当前库字符集。如果不是utf8mb4在导入前先执行ALTER DATABASE school CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;然后确保config.php里有mysqli_set_charset($conn, utf8mb4)。phpMyAdmin导入时下拉框里选utf8mb4别让它自动猜。5.3 union注入总是差一列报错the used SELECT statements have a different number of columns现象sql1.php上执行union select 1,2,3,4报列数不一致换成2、3就报语法错误。原因union查询要求前后两个SELECT的列数严格相等student表有5列你按4列写就会翻车。很多新手直接在id后面拼数字猜列数忽略了回显位只显示其中特定列。解决先用order by N逐次递增N从1开始加到报错为止记录最大正常值这个值就是列数。然后把union select后面的数字改成对应个数比如5列就写union select 1,2,3,4,5--再根据页面回显位置替换成database()、user()等函数拿数据。5.4 sqlmap扫靶场能通手工注入却毫无反应现象用Burp Suite重放参数手工构造 or 11页面回显和正常请求一样没有任何异常。原因sql4.php是POST型注入点参数在请求体里而不是URL查询字符串。用id1这种GET式探测方法当然无效。另外sql4.php可能把密码字段做了MD5加密你只注入了用户名密码校验仍失败整体登录逻辑不成立。解决用Burp Suite拦截登录请求确认POST参数名是username和password然后在username字段里构造admin or 11 -- -password随便填。如果不行就用post数据重放curl -d usernameadminpassword1 http://localhost/sql4.php看返回包和正常登录的差异。5.5 演示PPT和报告截图与本地环境完全对不上现象按PPT里的步骤操作页面样式、报错信息、数据内容都和截图不一致。原因源资源作者的MySQL版本、PHP版本、数据内容和你本地不同步。school.sql里可能还残留他测试时插入的脏数据。解决把school.sql重新导入一遍确保数据干净。之后每做一个实验就截一张图当场替换PPT里的旧图。归属于自己环境的实验记录才经得起追问。截图时用Burp Suite的Repeater窗口把请求包和响应包同时截进去一眼就能看出注入参数和回显位置。6. 让作业多点技术含量万能密码验证、盲注脚本与修复回归这章做三件事用万能密码在sql4.php登录点做本地验证写一个Python脚本在sql3.php上跑布尔盲注把手工猜测变成自动化输出最后用修复版代码做回归测试确认同一个payload不再生效。做完这三步你这份大作业的技术深度就比大多数交原理稿的同学高一个身位了。万能密码的实验点在sql4.php本地环境里输入admin or 11 -- -和任意密码如果能直接登录说明拼接漏洞确实存在。这招在真实系统里早被各种防护拦截了但在本地靶场验证防御原理依然有效。我一般这样设计实验记录先展示万能密码登录成功再展示修复版代码下同一串输入返回登录失败形成对照组。注意payload里的-- -末尾的空格不能省否则注释符后面跟的内容会破坏SQL结构。盲注脚本用来验证sql3.php。既然页面不回显数据就按布尔差异逐字符猜database名import requests url http://localhost/sql3.php charset abcdefghijklmnopqrstuvwxyz0123456789_ dbname for i in range(1, 20): for c in charset: payload f1 AND SUBSTRING(database(), {i}, 1) {c}-- r requests.get(url, params{id: payload}) if 真 in r.text: # 根据sql3.php回显内容改成实际判断词 dbname c print(当前库名:, dbname) break else: break print(最终database:, dbname)脚本思路很简单外层循环逐个字符位置取SUBSTRING(database(), i, 1)内层循环挨个试字符页面返回正常状态码且包含特定回显词时说明字符猜中。payload里的--是注释符的URL编码写法Python requests会原样传给服务端。跑通后会打印类似school的库名。这个脚本参数是可调的range(1, 20)控制猜库名最大长度charset按实际字符集扩展。把判断词从真改成sql3.php里特有的返回文案即可。最后做回归测试把sql1.php换成sql1_fixed.php后重放之前成功的union selectpayload页面不再回显数据说明修复生效。再试sql4.php登录点的万能密码同样被拦截。这个攻击成功→修复→攻击失效的闭环记录放进报告结论里很有说服力。这套流程走完你就把一份静态的资源包变成了自己手写代码、自己跑数据、自己截图记录的完整项目。有一次我给公司内部做安全分享临时借用类似靶场演示因为我提前把修复版代码和攻击版脚本都准备齐全现场没翻车。从那以后我每次拿到一套靶场资源都会强制先跑一遍攻击链路再跑一遍修复回归确认两条路都通才敢拿去讲给别人听。希望帮到你。本文还有配套的精品资源点击获取