| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> Mybatis在Java代码审计中的审计方法及修复方法 -> 正文阅读 |
|
[Java知识库]Mybatis在Java代码审计中的审计方法及修复方法 |
前置知识:了解Mybatis框架映射关系 mapper定位java代码 id定位方法 List<User> findByUserNameVuln02(String username); ? 定位到UserMapper.xml中的id ? <select id="findByUserNameVuln02" parameterType="String" resultMap="User"> ? ? ? select * from users where username like '%${_parameter}%' ? </select> Mybatis中两种数据库拼接方法 ${}是直接拼接 #{}预处理后拼接 mybatis有两种写法,一种是使用@Param 注解: @Mapper public interface CategoryMapper { ? ?@Select("select * from category_ where name= '${name}' ") ? ?public CategoryM getByName(@Param("name") String name); } 1、${}直接拼接,类似jdbc中的直接拼接审计方法 http://localhost:8080/sqli/mybatis/vuln01?username=joychou ? ?/ * http://localhost:8080/sqli/mybatis/vuln01?username=joychou' or '1'='1 ? ? */ ? ?@GetMapping("/mybatis/vuln01") public List<User> mybatisVuln01(@RequestParam("username") String username) { ? ? ? ?return userMapper.findByUserNameVuln01(username); ? } ? 这里使用的是mybatis来进行SQL查询,获取参数username后使用userMapper.findByUserNameVuln01(username)来进行查询。 ? 来看一下findByUserNameVuln01。MyBatis支持两种参数符号,一种是#,另一种是$。这里的参数获取使用的是${username},而不是#{username},而${username}是直接将参数拼接到了SQL查询语句中,就会造成SQL注入。 ? @Select("select * from users where username = '${username}'") List<User> findByUserNameVuln01(@Param("username") String username); 注入语句: http://localhost:8080/sqli/mybatis/vuln01?username=joychou' or '1'='1 ${}修复方法 采用#{},也就是预处理的形式 http://localhost:8080/sqli/mybatis/sec01?username=joychou @Select("select * from users where username = #{username}") User findByUserName(@Param("username") String username); 2、Mybatis中like审计方法 访问路径: http://localhost:8080/sqli/mybatis/vuln02?username=admin 这里使用的是findByUserNameVuln02(String username);来进行查询,来看一下UserMapper.xml,也就是他的XML映射文件。 List<User> findByUserNameVuln02(String username); ? UserMapper.xml: <select id="findByUserNameVuln02" parameterType="String" resultMap="User"> ? ?select * from users where username like '%${_parameter}%' </select> ? ? ? ? _parameter是Mybatis的内置参数,代表整个参数 ? 这里传入未过滤的username后,插入到SQL语句中,就成了:select * from users where username like '%username%',${}直接拼接字符串,而且这里在like的后面不能使用#{}预编译,不然就会产生报错。 注入语句: http://localhost:8080/sqli/mybatis/vuln02?username=admin' or '1'='1' %23 修复建议: 可以使用like concat('%',#{username}, '%')就可以避免注入了。 http://localhost:8080/sqli/mybatis/vsec02?username=joyc ? java代码: List<User> findByUserNameVsec02(String username); ? Mybatis配置: ? ?<select id="findByUserNameVsec02" parameterType="String" resultMap="User"> ? ? ? ?select * from users where username like concat('%',#{_parameter}, '%') ? ?</select> 验证: http://localhost:8080/sqli/mybatis/vsec02?username=joychou' or '1'='1' %23 同理不同数据库的修复代码快: Mysql数据库: SELECT * ?FROM user ?WHERE name like CONCAT('%',#{name},'%') ? Oracle数据库: SELECT * ?FROM user ?WHERE name like CONCAT('%',#{name},'%') 或 SELECT * ?FROM user ?WHERE name like '%'||#{name}||'%' Sqlserver数据库: SELECT * ?FROM user ?WHERE name like '%'+#{name}+'%' ? DB2数据库: SELECT * ?FROM user ?WHERE name like '%'+#{name}+'%' ? 或 SELECT * ?FROM user ?WHERE name like '%'||#{name}||'%' 3、Mybatis中order by审计方法 访问链接: http://localhost:8080/sqli/mybatis/orderby/vuln03?sort=1 这里使用的是findByUserNameVuln03(@Param("order") String order)来进行查询,同样也是去看UserMapper.xml。 <select id="findByUserNameVuln03" parameterType="String" resultMap="User"> ? ?select * from users ? ?<if test="order != null"> ? ? ? ?order by ${order} asc ? ?</if> </select> 可以看到我们输入的参数在order by之后,也是${order}直接拼接起来了,与like相同,在这也是无法使用预编译,只能使用${}。由于没有过滤就直接拼接,很显然存在注入。 注入语句: http://localhost:8080/sqli/mybatis/orderby/vuln03?sort=1 and (updatexml(1,concat(0x7e,(select version()),0x7e),1)) 修复代码: 1、当order排序能不让用户输入就不让用户输入,后台直接写死,不传递参数到后端: http://localhost:8080/sqli/mybatis/sec03 Java代码块: User OrderByUsername(); ? Mysql配置: <select id="OrderByUsername" resultMap="User"> ? ? ? ?select * from users order by id asc limit 1 ? ?</select> 2、当order必须要从外界获取参数到后端代码进行拼接时候,那就先对参数进行过滤,过滤后再使用: http://localhost:8080/sqli/mybatis/orderby/sec04?sort=1 Java代码块: @GetMapping("/mybatis/orderby/sec04") public List<User> mybatisOrderBySec04(@RequestParam("sort") String sort) { ? ?String filter_order = SecurityUtil.sqlFilter(sort); ? ?return userMapper.findByUserNameVuln03(filter_order); } ? //sqlFilter private static final Pattern FILTER_PATTERN = Pattern.compile("^[a-zA-Z0-9_/\\.-]+$"); public static String sqlFilter(String sql) { ? ?if (!FILTER_PATTERN.matcher(sql).matches()) { ?//严格限制用户输入只能包含a-zA-Z0-9_-. ? ? ? ?return null; ? } ? ?return sql; } ? Mysql配置: ? ? <select id="findByUserNameVuln03" parameterType="String" resultMap="User"> ? ?select * from users ? ?<if test="order != null"> ? ? ? ?order by ${order} asc ? ?</if> </select> |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
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/24 12:00:56- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |