SQL注入-java代码复现

g1870412862   ·   发表于 2021-08-07 20:12:05   ·   技术文章

0x00:前言的前言

本人最近正在学习java代码审计,纵观国内Java安全的文章,目前在java方面还是相当少的,其中力推P牛的知识星球,虽然进入要199但是个人感觉还是相当划算的。

0x01:前言

这个系列文章,将会以java为主语言,讲述owasptop10漏洞的原理与防御。更新时间不定期,如有错误或者不当之处,望各位师傅指正。

0x02:SQL_inject原理

对于sql注入已经是老生常谈的问题了,也几乎是每一个白帽子入门学习的第一个漏洞,官方的解释是这样的:SQL注入即是指 web应用程序 对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的 SQL语句 ,在管理员不知情的情况下实现非法操作,以此来实现欺骗 数据库服务器 执行非授权的任意查询,从而进一步得到相应的数据信息。
我对于sql注入的理解就只有一句话,用户输入的内容被当作的sql代码执行。

Java环境复现:

环境准备:

1.JDK1.8
2.IDEA
3.maven(方便导入jar包)
4.mysql

创建项目:

配置POM文件:


配置完依赖,就会发现需要的jar包已经全部导入了,这就是maven的好处,不用一个一个去官网下载导入。
配置mybatis配置文件:
这边持久层框架选择了mybatis,这是项目上最常见的持久层框架之一,具体的细节就不在本篇文章中写出了,开发的文章一找一大堆。

创建实体类:

Dao接口:

测试类:

从代码分析漏洞的成因:
首先我们看Dao包中的userDaoImp接口中的findbyname方法;

这边由于使用的是${name},所以name传入的参数会原封不动的拼接在sql语句中,比如name传入zhangsan,那么这边执行的sql语句为:
select from user where name = ‘zhangsan’ //在user表中查询张三的所有字段内容
那么当我们给name赋值为 zhangsan’ or 1=1 — + 时,语句为:
select
from user where name = ‘zhangsan’ or 1=1 — +’
因为在mysql中 — +(横横空)为注释,所以这边讲最后面的单引号注释掉了,配合我们写在zhangsan后面的单引号与前半个闭合,成功使得 or 1=1 部分逃逸成为sql语句代码执行

这是user表内的内容:

我们来看注入语句执行的效果

这边报错了,但是可以看出来查出了三个值,修改一下代码,更直观的看出运行结果

果然,程序执行了我们构造的注入语句。至于注入的姿势本篇文章将不会过多讲述,小伙伴们可以移步百度,自行学习盲注,报错注入,dnslog注入等各种姿势。

0x03防御方式

预编译:

防御sql注入,我们可以从本质上出发,把用户输入的内容全部当作字符串,阻止拼接即可。最常使用的方法是预编译,这样不管传入什么,参数始终都会被视为字符串。实现方式是使用#{}代替${}。

修改之后我们测试一下案例:

既然#{}可以防止注入,那是不是只要开发全部使用这个不就可以避免了?
开发小伙伴应该都知道,像模糊查询使用的like,除此还有order by这样常用的函数,那我们就不得不使用${}了,如果过滤不严谨,那么就会导致注入:

所以,一般开发都会这样写:
LIKE "%"#{name}"%" AND name LIKE CONCAT(CONCAT('%',#{name},'%'))

防御方法总结一下,虽然使用了预编译,但是还是得严格过滤参数,这样不仅仅可以预防sql注入,还可以预防rce(由于文章面向小白,所以后面会说明rce是什么,本篇不过多赘述)。

附加知识:

JPA & Hibernate:
这里有一个误区,使用了 ORM 框架,就不会有 SQL 注入。而实际上,在 Hibernate 中,支持 HQL 和 native sql 查询,前者存在 HQL 注入,后者和之前 JDBC 存在相同的注入问题。

HQL:

Query<User> query = session.createQuery("from User where name = '" + name + "'", User.class); User user = query.getSingleResult();
可以看出参数可控的话依然是可以实现拼接语句的。

Native SQL:

String sql = "select * from user where name = '" + name + "'"; // deprecated // Query query = session.createSQLQuery(sql); Query query = session.createNativeQuery(sql);

用户名金币积分时间理由
owl 5.00 0 2021-09-01 15:03:58 一个受益终生的帖子~~
Track-聂风 95.00 0 2021-09-01 15:03:59 一个受益终生的帖子~~

打赏我,让我更有动力~

0 Reply   |  Until 1个月前 | 347 View
LoginCan Publish Content
返回顶部 投诉反馈

掌控者 © 2016 - 2021. All Rights Reserved. 掌控者

Powered by 掌控者