ctfshow Web入门:SQL注入与HTTP参数篡改实战解析
发布时间:2026/9/15 3:30:52 锦皓数字建站

在ctfshow上刷Web题很多人都是奔着“入门”去的。但真正刷到第二章“web应用安全与防护”这个模块时你会发现难度一下子从“看源码、改请求”跳到了“要理解漏洞原理、能手工构造攻击流量、还得会写点小脚本”的程度。这一章是ctfshow整个Web入门体系里最承上启下的一块几乎把SQL注入、HTTP协议攻击、参数篡改这几类核心考点打包在了一起刷完之后对Web安全的整体认知会清晰非常多。这篇文章我打算把第二章从学习路线、漏洞原理、实操手法到踩坑经验完整拆一遍。内容不追求一次讲完所有题目而是把“做题时需要的那套思路”讲透只要你跟着这套方法论走再回到题目里去实战会发现原来很多题本质上都是同一道题。适合正在刷ctfshow的Web入门选手也适合刚学完基础课程、想通过靶场强化实战能力的同学参考。1. 第二章的学习目标与前置要求1.1 从“看答案”到“看原理”的关键转折第二章放在整个ctfshow Web系列里的位置很有意思。第一章的题目大多是让你了解一个Web页面是怎么组成的源码在哪看、注释里藏着什么、响应头有什么信息只要细心基本都能做出来。但到了第二章题目开始主动构造恶意输入让你去触发服务端的逻辑问题。这时候单纯靠“看”已经不够了你得知道一个请求从浏览器发出后服务器端怎么解析、怎么拼接SQL、怎么处理参数然后才能在Payload里动手脚。所以在刷第二章之前我建议你先确认自己具备三个前置技能能熟练用浏览器开发者工具看请求和响应会最基本的SQL语句SELECT、WHERE、LIMIT、ORDER BY这种程度理解HTTP的请求方法、请求头、Cookie是干什么的。如果不是很熟也不用担心第二章的题本身就是最好的训练场边做边补完全来得及。1.2 这一章真正想让你掌握的四种能力我在刷完这一章之后复盘觉得它其实在反复训练四件事。第一是信息收集很多题的突破口就藏在页面源码、报错信息、响应头甚至文件名里第二是协议理解你能不能区分GET和POST的真正区别能不能想到服务器会怎么处理一个畸形请求第三是漏洞利用SQL注入怎么判断、怎么出数据、怎么绕过滤第四是脚本能力手工试一次两次可以但盲注或批量测试时必须能快速写个Python脚本来完成。这四种能力是串在一起的你缺哪一个做题都会卡住。比如SQL注入的题前面几步靠信息收集找到注入点中间靠漏洞利用构造出Payload最后如果数据太多还得靠脚本自动跑。第二章的题目设置本质上是把你从“单一技能点”往“全流程利用”方向推了一把。2. SQL注入第二章里最硬的骨头2.1 注入类型判断先分清“数字型”和“字符型”SQL注入是第二章绝对的重点。很多新手一上来就背Payload结果换个环境就不会用了根子在于没搞清楚注入点的类型。拿到一个参数比如?id1第一步不是直接上联合查询而是判断它是数字型还是字符型。最简单的判断方法就是构造一个恒真的比较表达式。数字型直接传id1 and 11和id1 and 12页面表现不一样就说明数字型注入如果传1 and 11没反应再试试1 and 11和1 and 12能区分开就是字符型。这是整个SQL注入利用的起点判断错了后面全白搭。我见过很多人在这一步偷懒直接上sqlmap结果工具报“no injection point”其实就是类型判断出了问题。2.2 联合查询注入的完整利用链一旦确认了注入点最优先尝试的就是联合查询UNION SELECT注入。前提是页面上能显示查询结果这样你才能把数据“带”出来。联合查询注入有两条铁律第一前面SELECT的字段数必须和后面SELECT的字段数一致所以要先order by 1、order by 2、order by 3这样不断试探直到页面报错为止第二要让前面的查询结果为空通常是把参数写成不存在的负数比如id-1这样UNION后面的结果才能排在最前面显示出来。字段数确定后就要判断页面显示位。如果一共有三列随便构一个union select 1,2,3看哪个数字出现在页面上那个位置就是你可以“显示数据”的位置。接着把数字换成database()、user()、version()先摸清当前数据库名、权限和版本再通过系统表information_schema.tables逐步拿到表名和列名最后查询目标字段里的数据。整个链条看起来很机械但每一步都需要你理解背后的逻辑因为实际题目里往往会有各种过滤要绕。2.3 报错注入、布尔盲注和时间盲注的取舍联合查询不是什么时候都能用当页面不显示结果时就得换思路。报错注入的思路是让数据库在执行时把报错信息直接输出到页面上常见函数有extractvalue和updatexml原理是向XPath函数传入一个格式错误的字符串让它把字符串内容带进报错信息里。这种方式效率高一条Payload就能出数据但要求页面开启错误回显。如果连报错都不显示只能靠页面真/假来判断那就是布尔盲注。思路是用substr(database(),1,1)a这样的表达式逐字符猜解每一次请求只有对上或不对上两种状态。时间盲注就更极端页面完全不显示任何差异只能让数据库睡几秒钟来做判断依据if(条件,sleep(5),0)这种格式就是干这个用的。这三者的取舍很简单能联合查询就不报错能报错就不盲注盲注里能用布尔就不用时间。用脚本直接跑盲注时要注意把请求频率控制得低一点别把自己的IP封了更别把靶场打崩。3. HTTP协议层面的“花活”与参数篡改3.1 请求方法就是一道隐藏题第二章的HTTP相关题目很多第一关就卡在请求方法上。很多新手默认以为只有GET和POST拿到一个POST提交没反应就不知道怎么继续了。实际上HTTP还有PUT、DELETE、OPTIONS、HEAD、PATCH等方法服务端如果路由设计得不规范就可能对意料之外的方法做出响应。比如我遇到过一道题前端只给了个输入框提交后显示“请求方式不对”。我试了POST没反应随手把请求改成PUT方法结果直接就出了flag。其实原理很简单后端代码是按请求方法分发路由的它定义了一个处理PUT请求的函数但前端表单只用了POST。这类题练的不是“猜”而是你能不能想到去试。做题时如果GET和POST都试过没结果我会打开Burp Suite把方法挨个换一遍每次换完都要记得重新发送因为有些题目会严格校验Content-Type头方法换了头也得跟着改。3.2 请求头、Cookie与来源校验HTTP协议里很多东西都能成为考点最常见的就是请求头和Cookie。有些题会在响应头里给你一点提示比如某个自定义响应头字段的值你要把它放到第二次请求的请求头里才能通过。这类考点考验的是你对HTTP头字段的理解也算信息收集的一种延展。Cookie这关也很容易出题常见玩法是改Cookie里的某个字段来提升权限或者通过Cookie注入口来绕过登录判断。我印象很深的一道题页面显示“只有管理员才能看到”但登录接口又没有任何注册入口。我翻了一下Cookie发现有个userguest字段改成useradmin再刷新页面内容就不一样了。还有些题目会在Cookie里放一个加密字符串看起来是Base64解码改一下再回去提交就过了。记住一点Cookie是客户端可控的数据凡是存了权限信息的Cookie都值得动手改一改。3.3 参数解析差异同一个参数能传几次这一块是第二章里比较进阶的内容也是很容易被忽略但很可能直接决定一道题能不能做出来的点。Web服务器和编程语言对“同一个参数名传多次”的处理方式并不一致比如?id1id2有的后端取第一个有的取最后一个有的会拼成数组。这种差异不是冷知识在CTF题目里经常被用来绕过WAF或逻辑判断。举个典型的例子某个参数既用来做权限判断又用来拼查询服务端代码可能只校验了第一个值但真正执行时用的是第二个值那就可以传id1id2让校验逻辑看到1让SQL执行看到2直接绕过限制。做这类题时我的习惯是在Burp里把请求报文手动改成重复参数的形式去发因为浏览器地址栏不一定能直接处理这种格式。这类题还有一个更隐蔽的变体参数名大小写混用、或者使用Content-Type: application/json时用同名JSON键都可能造成和普通表单参数解析不同的结果。第二章里但凡碰到“提交后没反应”或者“明明条件对了却不通过”的题都可以往参数解析差异这个方向想一想。4. 实战拆解一道典型题目的完整打法和思考路径4.1 第一步信息收集把题目给的所有信息榨干先说一个我在CTF社区里反复看到的现象很多新手拿到题不看页面源码、不抓包、不看响应头上来就直接拿sqlmap扫扫不到就说题有毛病。其实ctfshow的Web入门题在难度设计上是很克制的提示往往就摆在面前只是你没去看。我自己的标准流程是这样的先打开页面用浏览器快捷键查看源代码别放过注释和隐藏域然后用Burp Suite抓一次正常请求完整看一下请求行、请求头、请求体、响应头、响应体最后再根据页面上出现的动态内容判断有没有和数据库交互的参数。这个流程五分钟内能完成但能筛掉一大半的无效操作。之前做一道显示“神秘字符”的题我连着试了好几个Payload都没反应最后随手看了眼响应头发现里面藏着一个提示用的自定义字段顺着那个字段的值再构造请求就出flag了。4.2 第二步构造Payload从通用到定向的递进信息收集做完进入利用阶段Payload的选择也是有顺序的。先试最简单的参数值改成单引号、双引号、数字比较等目的是触发异常响应确认漏洞点。确认后优先用联合查询因为反馈最快最直观联合查询走不通再根据页面有没有报错信息决定要不要转报错注入最后才考虑盲注。构造Payload时要留意题目是否做了过滤。ctfshow的题很爱用关键字过滤当第一层拦截比如把select、union这些词直接替换成空字符串。遇到这种情况可以先手动测试哪个关键字被过滤了再用大小写混写、内联注释、双写绕过等技巧具体用哪个取决于过滤的实现方式。这里有个很重要的细节如果你用Python脚本发请求一定要先把URL编码处理好否则Payload里的特殊字符会被服务器或中间件吃掉你排查半天都找不到原因。4.3 第三步脚本自动化手工到自动化的临界点第二章后面的一些注入题手工操作已经不太现实了尤其是一次只能判断一个字符的盲注题。我在做这类题时会写Python的requests脚本先写好一个请求模板再把需要猜解的部分做成循环。脚本逻辑通常分三层最底层是一个check(payload)函数返回值代表条件真或假中间层是一个猜单字符的函数遍历字符集比如大小写字母、数字和常见符号找到让条件为真的那一个最上层是多个位置拼接从库里第一个字符开始循环猜到位数上限。这里有一个提升效率的小技巧字符集顺序尽量把数字、小写字母、大写字母和{ }_这类符号放到前面因为CTF flag的主要字符通常就集中在这几个类别里能显著减少请求次数。写脚本的时候还有一个特别容易踩的坑SQL语句里的空格如果被过滤了脚本里生成的Payload得使用注释符或%0a之类的替代方案这取决于题目上下文。如果脚本第一次跑没结果先别急着改逻辑把生成的完整URL打印出来检查一遍多半是Payload格式出错了。5. 新手最容易踩的坑与排查技巧5.1 为什么Payload看起来没问题却始终不生效这个问题在群里被问过无数次。最普遍的原因是编码问题浏览器或Burp自动对请求做了URL编码而你在写脚本时没有对、空格、#等字符做处理服务器收到的和你脑子里想的根本不是一回事。还有一个原因是数据库类型搞错了MySQL、SQLite、MSSQL的注入语法差异不小你用MySQL的Payload去打SQLite的题那自然是不出数据的。我建议遇到“Payload不生效”时先做三件事一是把请求包原样复制下来在Burp里重发试试二是把注入点前面查询的字段数确认一遍不要凭感觉填数字三是看看页面有没有报错任何一点报错信息都比瞎猜强。很多时候不是漏洞不存在而是你的Payload根本没到达数据库。5.2 别忘了题目本身就是提示系统ctfshow的题在设计上有一个特点题目标题、描述、页面源码甚至报错信息里都藏着解题线索。比如标题提示是“log in”很可能和日志文件有关描述里提到“只允许本地访问”就要想着用X-Forwarded-For: 127.0.0.1或X-Real-IP这个头如果页面源码里出现了一个奇怪文件名可能就要去访问备份文件。新手做题容易陷入“死磕一个点”的状态怎么看都觉得题目没提示。我的建议是卡住超过20分钟就退出去看看题目里的描述和文件名把整个请求过程从头到尾再看一遍。很多题不是难而是线索分散在几个地方你只盯着参数就没法拼出全貌。5.3 工具用得好不好决定了你能走多快ctfshow的Web入门题有两类一类是那种一眼就能看穿的小题这类题用Burp Suite手动改包就足够了没必要事事都自动化另一类是需要重复几百上千次请求的脚本题这时候手工会让你怀疑人生一定要用脚本。Burp Suite的Repeater和Intruder两个模块是我最常用的Repeater用来手工改包调试Intruder用来做简单枚举复杂逻辑就交给Python。新手学抓包改包最大的障碍其实不是工具本身而是不懂HTTP协议。所以我建议在刷第二章之前先把“请求行、请求头、请求体、Cookie、状态码”这几个概念搞清楚再用Burp的History面板看一遍正常请求的完整报文熟悉了之后就很容易上手了。6. 刷完第二章之后你的能力应该在哪里第二章刷完一个合理的检验标准是给你一个完全不熟悉的Web靶场环境你能独立完成从信息收集、发现注入点、判断类型、构造利用到脚本自动化的完整流程。如果还做不到说明有些环节还需要回去补不要急着刷后面的题。我在带新人刷题时经常说一句话CTF刷题不是把答案背下来而是把“遇到问题时的排查顺序”练成本能。第二章正好是锻炼这种本能的最佳章节它覆盖了Web漏洞利用最核心的基础面把这章吃透了后面再看文件上传、命令执行、反序列化这些考点你会明显感觉有底了。按照我个人的经验刷第二章不用刻意追求一天刷完重要的是每道题做完后复盘一遍我是怎么想到这个利用点的Payload里的每一段在做什么如果过滤再严一点还能怎么绕。带着这些问题去刷下一题进步速度会比闷头刷快很多。等你回头看的时候会发现自己在不知不觉中已经能独立分析一个陌生站点的安全问题了这种掌控感就是刷这一章最大的收获。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。