Java代码审计sql注入(java sql注入防范措施)

  本篇文章为你整理了Java代码审计sql注入(java sql注入防范措施)的详细内容,包含有javasql注入检测 java sql注入防范措施 java sql审核平台 java 代码注入 Java代码审计sql注入,希望能帮助你了解 Java代码审计sql注入。

   时间过了好久,其实一直都有在学习,笔记只是记在了本地,但是前段时间因为图床的原因,我的笔记截图图片都没有了,所以这个时候我重新搞了一个图床然后才开始更新java这个系列,我就没有那些java漏洞基础的分析文章了,我用的是一个java_sec_code这个项目直接开始用上面的java代码去审计这些基础的漏洞同时也在学习cc链

  
该项目也可以叫做Java Vulnerability Code(Java漏洞代码)。

  每个漏洞类型代码默认存在安全漏洞(除非本身不存在漏洞),相关修复代码在注释里。具体可查看每个漏洞代码和注释。

  由于服务器到期,在线的Demo网站已不能使用。

  登录用户名密码:

  

admin/admin123

 

  joychou/joychou123

  

 

  写这个呢是因为我在前面学java的基础漏洞审计的时候,我自己在Typora中的笔记因为图床的问题,做的笔记截图全部都不见了,所以前面的笔记就作废了,然后在做这个项目的漏洞的时候再网上没有找到完整的做题笔记,我就想着自己也做嘛就写一个笔记下来记录自己的java学习过程

  项目地址JoyChou93/java-sec-code: Java web common vulnerabilities and security code which is base on springboot and spring security (github.com)

  less-1

  

@RequestMapping("/jdbc/vuln")

 

   public String jdbc_sqli_vul(@RequestParam("username") String username) {

   StringBuilder result = new StringBuilder();

   try {

   Class.forName(driver);

   Connection con = DriverManager.getConnection(url, user, password);

   if (!con.isClosed())

   System.out.println("Connect to database successfully.");

   // sqli vuln code

   Statement statement = con.createStatement();

   String sql = "select * from users where username = " + username + "";

   logger.info(sql);

   ResultSet rs = statement.executeQuery(sql);

   while (rs.next()) {

   String res_name = rs.getString("username");

   String res_pwd = rs.getString("password");

   String info = String.format("%s: %s\n", res_name, res_pwd);

   result.append(info);

   logger.info(info);

   rs.close();

   con.close();

  
第一关是一个很基础的sql注入漏洞就是

  

String sql = "select * from users where username = " + username + "";

 

   logger.info(sql);

   ResultSet rs = statement.executeQuery(sql);

  

 

  这一段代码,就是基础的就是一个正常数数据库拼接,然后我的数据库里面有admin这个用户直接拼接上去是这样的效果

  闭合语句

  

" + username + "====admin union select 1,version(),user()--+

 

  还是很简单就简单说一下,从字符串中的admin union select 1,2,3--+

  修复方式:预编译修复

   String sql = "select * from users where username = ?";

   PreparedStatement st = con.prepareStatement(sql);

   st.setString(1, username);

  

 

  less-2

  

@GetMapping("/mybatis/vuln01")

 

   public List User mybatisVuln01(@RequestParam("username") String username) {

   return userMapper.findByUserNameVuln01(username);

  

 

  mybatis注入,这是一个存在注入语句的

  这里可以直接看出来它是一个通过username这个字段去寻找参数值的,但是数据库查询肯定会存在sql语句的执行不可能不存在,这个时候我们追究其原理

  直接追踪找到接口

  

@Select("select * from users where username = ${username}")

 

   List User findByUserNameVuln01(@Param("username") String username);

  

 

  我们发现它是用的$符号去活得参数值,这种方式的话是注解配置方案是springboot和spring里面常见的配置方式

  Mybatis获取值的方式有两种,分别是${} 和 #{}。这是关于用ssm组合写的框架会存在的sql注入

  动态 sql 是 mybatis 的主要特性之一,在 mapper 中定义的参数传到 xml 中之后,在查询之前 mybatis 会对其进行动态解析。mybatis 为我们提供了两种支持动态 sql 的语法:#{} 以及 ${}。

  

 在下面的语句中,如果 username 的值为 zhangsan,则两种方式无任何区别:

 

   select * from user where name = #{name};

   select * from user where name = ${name};

   其解析之后的结果均为

   select * from user where name = zhangsan;

  

 

   但是 #{} 和 ${} 在预编译中的处理是不一样的。#{} 在预处理时,会把参数部分用一个占位符 ? 代替,变成如下的 sql 语句:

  

select * from user where name = ?;

 

  而 ${} 则只是简单的字符串替换,在动态解析阶段,该 sql 语句会被解析成

   select * from user where name = zhangsan;

  以上,#{} 的参数替换是发生在 DBMS 中,而 ${} 则发生在动态解析过程中。

  

 

  

#{}:解析的是占位符问号,可以防止SQL注入,使用了预编译。

 

  ${}:直接获取值

  

 

  还是拼接就i行了

  

admin union select 1,@@version,3 --+

 

  

 

  修复方案就是用#{},不要使用${}

  less-3

  # 是通过prepareStatement的预编译的,会对自动传入的数据加一个单引号。
 

  如:order by #{orderBy},如果传入的时间是 ,则会被解析为 order by ‘update_time’ (这样排序是无效的,这也是为什么不能用#号传参的原因)。

  

@GetMapping("/mybatis/vuln02")

 

   public List User mybatisVuln02(@RequestParam("username") String username) {

   return userMapper.findByUserNameVuln02(username);

  

 

  还是老规矩先追下去看

  发现没有方法再想一想往上看一看发现一个注解@Mapper注解这个注解的意思就是它有一个映射文件反手翻一翻

  然后就发现了这个select语句

  

 select id="findByUserNameVuln02" parameterType="String" resultMap="User" 

 

   select * from users where username like %${_parameter}%

   /select

  

 

  追到后面发现一个like,like是模糊查询的意思

  简单的插播一下like注入的原理

  

 like查询时,如果用户输入的值有"_"和"%",则会出现这种情况:用户本来只是想查询"abcd_",查询结果中却有"abcd_"、"abcde"、"abcdf"等等;用户要查询"30%"(注:百分之三十)时也会出现问题。

 

   然后:_parameter是Mybatis的内置参数,代表整个参数

   我们还是直接拼接就可以了

  
 

 

  考点

  通过配置文件的映射直接追踪过来是没有select语句的

  less-4

  

@GetMapping("/mybatis/orderby/vuln03")

 

   public List User mybatisVuln03(@RequestParam("sort") String sort) {

   return userMapper.findByUserNameVuln03(sort);

  

 

  传入的值变了是个sort,sort是短的,还是追踪sql源码来看看

  

 select id="findByUserNameVuln03" parameterType="String" resultMap="User" 

 

   select * from users

   if test="order != null"

   order by ${order} asc

   /if

   /select

  

 

  看到了是order by 然后后面有asc代表的是升序排布,desc是降序排布因为是

  拼接语句选择用updataxml吧直接and拼接起来就实现了

  

**http://localhost:8080/sqli/mybatis/orderby/vuln03?sort=id and (updatexml(1,concat(0x7e,(select version()),0x7e),1)) #

 

  

 

  报错语句中就会看到

  以上就是Java代码审计sql注入(java sql注入防范措施)的详细内容,想要了解更多 Java代码审计sql注入的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: