山东大学软件学院项目实训-创新实训-山大软院网络攻防靶场实验平台(七)
目录
前言
SQL注入概述
1.1 什么叫SQL注入
1.2 SQL注入分类
1.3 SQL漏洞探测
1.4 SQL注入常用函数
1.5 SQL注入防御
环境搭建展示
基于函数报错的SQL注入
防范
前言
这篇文章记录我搭建删除型SQL注入漏洞的环境,以及如何基于报错函数利用该漏洞进行攻击的过程。同时记录学习SQL注入漏洞以及防范措施的过程。
SQL注入概述
1.1 什么叫SQL注入
- 程序不判断和处理用户输入数据的合法性,这使得攻击者能够在管理员不知情的情况下向Web应用程序中的预定义SQL语句添加额外的SQL语句并实施非法操作,从而欺骗数据库服务器执行未经授权的任意查询, 从而进一步获取数据信息。
- 简而言之,SQL注入是将SQL语句包含在用户输入的字符串中,如果在设计不佳的程序中忽略检查,注入的SQL语句将被数据库服务器误认为是正常的SQL语句并运行,攻击者可以执行计划外的命令或访问未经授权的数据。
1.2 SQL注入分类
- 按照注入点类型来分类
(1)数字型注入点
类似结构 http://xxx.com/users.php?id=1 基于此种形式的注入,一般被叫做数字型注入点,缘由是其注入点 id 类型为数字
(2)字符型注入点
类似结构 http://xxx.com/users.php?name=admin 这种形式,其注入点 name 类型为字符类型,所以叫字符型注入点
(3)搜索型注入点
这类注入主要是指在进行数据搜索时没过滤搜索参数,一般在链接地址中有 “keyword=关键字” 有的不显示在的链接地址里面,而是直接通过搜索框表单提交
- 按照数据提交的方式来分类
(1)GET 注入
提交数据的方式是 GET , 注入点的位置在 GET 参数部分。
(2)POST 注入
使用 POST 方式提交数据,注入点位置在 POST 数据部分,常发生在表单中。
(3)Cookie 注入
HTTP 请求的时候会带上客户端的 Cookie, 注入点存在 Cookie 当中的某个字段中。
(4)HTTP 头部注入
注入点在 HTTP 请求头部的某个字段中。比如存在 User-Agent 字段中。严格讲的话,Cookie 其实应该也是算头部注入的一种形式。因为在 HTTP 请求的时候,Cookie 是头部的一个字段。
- 按照执行效果来分类
(1)基于布尔的盲注
即可以根据返回页面判断条件真假的注入。
(2)基于时间的盲注
即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。
(3)基于报错注入
即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。
1.3 SQL漏洞探测
一般来说,SQL 注入一般存在于形如:http://xxx.xxx.xxx/abc.asp?id=XX 等带有参数的 ASP 动态网页中,有时一个动态网页中可能只有一个参数,有时可能有 N 个参数,有时是整型参数,有时是字符串型参数,不能一概而论。总之只要是带有参数的动态网页并且该网页访问了数据库,那么就有可能存在 SQL 注入。
- 1、先加单引号’、双引号"、等看看是否报错,如果报错就可能存在SQL注入漏洞了。
- 2、还有在URL后面加 and 1=1 、 and 1=2 看页面是否显示一样,显示不一样的话,肯定存在SQL注入漏洞了。
- 3、还有就是Timing Attack测试,也就是时间盲注。通过简单的条件语句比如 and 1=2 是无法看出异常的。在MySQL中,有一个Benchmark() 函数,它是用于测试性能的。 Benchmark(count,expr) ,这个函数执行的结果,是将表达式 expr 执行 count 次 。
因此,利用benchmark函数,可以让同一个函数执行若干次,使得结果返回的时间比平时要长,通过时间长短的变化,可以判断注入语句是否执行成功。
1.4 SQL注入常用函数
- Version();当前 mysql 的版本
- Database();当前网站使用的数据库
- User();当前 MySQL 的用户
- system_user(); 系统用户名
- session_user();连接数据库的用户名
- current_user;当前用户名
- load_file();读取本地文件
- length(str) : 返回给定字符串的长度,如 length(“string”)=6
- substr(string,start,length) : 对于给定字符串string,从start位开始截取,截取length长度 ,如 substr(“chinese”,3,2)=“in”
- substr()、stbstring()、mid() 三个函数的用法、功能均一致
- concat(username):将查询到的username连在一起,默认用逗号分隔
- concat(str1,’’,str2):将字符串str1和str2的数据查询到一起,中间用连接
- group_concat(username) :将username数据查询在一起,用逗号连接
1.5 SQL注入防御
- (1)关闭 SQL 错误回显
- (2)前端输入字符白名单验证(长度、类型等)
- (3)对输入的特殊字符使用转义处理
- (4)SQL 操作使用 PreParedStatement
- (5)SQL 服务运行于专门的账号,并且使用最小权限
- (6)限制 SQL 服务的远程访问,只开放给特定开发人员
- (7)代码审计,最有效的检测应用程序的注入风险的方法之一
- (8)使用成熟的WAF
环境搭建展示

输入留言 点击提交


点击删除后拦截包,发现包中有messahe传递留言内容,且是GET方式,猜测是注入点,同时可以注意到传递的是字符串类型 应该是用''闭合的

构造payload
123' or updatexml(1,concat(0x7e,database()),0)#
messahe=后面接上面的playload,用自带的url encode key编码后,空格变成了+


成功爆出数据库名

后台核心代码分析
@RequestMapping("delete1")
public String sqli_delete1(@RequestParam(value = "messahe",required = false) String messahe, Model model) {
try {
Connection connection = dataSource.getConnection();
Statement stmt = connection.createStatement();
sql="delete from messages where message='"+messahe+"'";
System.out.println(sql);
stmt.executeUpdate(sql);
connection.close();
System.out.println("model:"+model);
}catch (SQLException ex){
System.out.println(ex);
error = ex.toString();
model.addAttribute("error",error);
return "sqli_delete1";
}
return "sqli_delete";
}
没有对传入的值进行处理 直接拼接到sql语句中 导致delete型sql注入
基于函数报错的SQL注入



防范
关闭后台的SQL错误回显
