Java审计之SQL注入篇

0x00 前言

本篇文章作为Java Web 审计的一个入门文,也是我的第一篇审计文,后面打算更新一个小系列,来记录一下我的审计学习的成长。

0x01 JDBC 注入分析

在Java里面常见的数据库连接方式也就那么几个,分别是JDBC,Mybatis,和Hibernate。

注入常见场景分析

JDBC的连接是比较繁琐的,并且是最原始的连接方式,我们来看看JDBC的最原始的连接代码

Get型注入:



@WebServlet("/demo")
public class domain extends HttpServlet { @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("get访问");
String id = req.getParameter("id"); Connection conn = null; try {
Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/demo", "root", "root");
String sql = "select * from users where id = '"+id+"' "; Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} } @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}

这里编写了一个serlvet获取get的值,连接数据库使用了jdbc的方式进行连接,采用了拼接的方式直接拼接到了sql语句里面去。这样的代码如果在传入前没做过滤直接拼接,就会产生sql注入。

在实际运用当中如果不采用框架使用JDBC的方式,普遍会编写一个工具类来完成这些繁琐的配置,但是具体的实现还是调用这些方法来进行实现,只是进行了一个简单的封装。

在代码审计的时候,如果看到是JDBC的方式进行连接可以跟踪一下他的代码,看他有没有调用自己定义的过滤方法,如果没有的话,就会存在sql注入,当然这是在未使用预编译的情况下。

后面的重复的比较多,都是大致相同,我后面就贴出一些主要的代码进行分析。

POST型注入:

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

GET的注入和POST的其实差不多,只是获取值的地方不一样。

Like型注入:

 String name = req.getParameter("name");
String sql = "select * from users where name like '%'+name+'%'";

Header注入:

String referer = req.getHeader("referer");
String sql = "update user set referer ='"+referer+"'";

以上列了几种方式都是JDBC采用拼接的方式造成SQL注入的代码。

JDBC 预编译

预编译的定义其实就是使用问号先来占位,后面再传入具体的值。

后面传值的时候,程序会把传入的参数,自动转换为spring类型的字符,并不会拼接成sql语句生效。

Connection  conn = JDBCUtils.getConnection();
String sql = "select * from users where username = ? and password = ?";
PreparedStatement pstmt = conn.prepareStatement(sql); //使用预编译传入sql语句
pstmt.setString(1,username); //设置第一个参数为username
pstmt.setString(2,password); //设置第二个参数为password
pstmt.executeQuery();

0x02 Mybatis 注入分析

Mybatis获取值的方式有两种,分别是${}#{}

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

在Mybatis里面一般会采用#{}来进行取值,但是也会有特殊情况。

like注入:

我们这里还是以代码做演示

select id="findlike" resultType="com.test.domain.User" parameterType="string">
select * from user where name like '%#{name}%',
</select>

我们在运行的时候会发现,代码直接就会抛出异常。

正确代码:

select id="findlike" resultType="com.test.domain.User" parameterType="string">
select * from user where name like '%${name}%',
</select>

需要使用${}的方式进行取值。

或者是

<select id="findlike" resultType="com.test.domain.User" parameterType="string">
select * from user where name like #{name}
</select>

测试类:

public void findlike(){
List<User> ming = userDao.findlike("'%'+xiao+'%'");
for (User user1 : ming) {
System.out.println(user1);
} }

另外还有种写法:

<select id="findlike" resultType="com.test.domain.User" parameterType="string">
select * from user where name like concat('%',#{name},'%')
</select>

这里在前面进行加入两个%,再进行传入这样的方式也不会报错,但是使用

#直接拼接%就会报错。

like不能直接使用预编译,如果在没处理好参数的情况下进行传入,也是会产生sql注入的。

in后注入

Select * from news where id in (#{id}),

也是拼接使用预编译这样的代码也会报错。

正确写法:

Select * from news where id in (${id})

order by 注入

Select * from news where title ='#{titlename}' order by #{time} asc

执行会报错

正确写法:

Select * from news where title ='#{titlename}' order by ${time} asc

0x03 CMS 审计

测试环境

IDEA  :2020.1.2 X64 

MYSQL :5.7.26

TomCat:8.0

JDK   :1.8

搭建环境

下载源码

http://down.admin5.com/jsp/132874.html

idea中导入项目,添加pom.xml文件为maven文件。如果Spring注解报错说明Spring的环境还没拉去下来,刷新一下pom.xml文件就好了。

这里配置是82端口,目录就默认就行。

配置tomcat也设置为82端口

这里要注意路径需要根路径,否则加载有一些css资源的时候路径会因为路径问题加载不少。

这样就配置完成了,但是还是会发现有一些get,set的方法会爆红。

项目的说明文档里面给出了解决方法,只需要安装一下lombok插件重启一下就解决了,这里是因为一些代码中并没有实际编写get和set的方法,使用的是插件去提供的。

这些完成后,就可以讲提供好的sql文件导入进去。进行启动

这些都是自己专门踩过的坑,一段操作猛如虎后,启动完成。但是会有一些报错,sql文件在导入的时候,有些执行错误了,几张表没创建成功,在进行操作该表的时候未找到该表,就报错了。

将就一下把!

第一步肯定是先看他的web.xml的配置,看他都使用了哪些框架

确实该cms是一个使用了SSM框架,也就是Spring+Spring Mvc+Mybatis

(哈哈哈,其实是看说明文档知道的。)

审计SQL 注入

文件的划分很细,很清楚看到他的结构,点开dao文件下的任意文件,看看Mybatis是使用了注解开发还是配置文件开发。

点开没发现有Mybatis的注解,那就肯定是使用了配置XML的方式。

映射文件会和dao的接口在同层目录下。

直接就来找$符号吧,看看哪些是直接调用了$来进行取值并且没经过过滤的。

发现deleteArticleByIds使用的是$取值。

找到配置文件对应的dao接口

选中dao接口中deleteArticleByIds,Curl+左键可以看到哪些类调用了该方法。

我这里就跳转到了service层的一个实现类里面。

主要关注service层代码,过滤处理的会从service层去实现。

并没有发现过滤的代码

接下来就可以去找该service对应的Controller,这个可以使用idea的ctrl+Alt+H快捷键去查询调用层次,去看Controller的位置。

查看到了Controller文件,先找他的目录路径

/admin/article

在搜索一下deleteArticleByIds具体在哪里调用和出现,就得到了具体的漏洞位置。

漏洞位置:

http://127.0.0.1:82/admin/article/delete

访问漏洞位置

点击删除进行抓包

扔到sqlmap跑一下

参考文章

https://mp.weixin.qq.com/s?__biz=MjM5OTk2MTMxOQ==&mid=2727827368&idx=1&sn=765d0835f0069b5145523c31e8229850&mpshare=1&scene=1&srcid=0926a6QC3pGbQ3Pznszb4n2q

https://xz.aliyun.com/t/2646#toc-1

0x04 结尾

前面的环境配置了比较久,耽误了不少时间。

Java审计之SQL注入篇的更多相关文章

  1. [转载] 我的WafBypass之道(SQL注入篇)

    我的WafBypass之道(SQL注入篇) Web安全 作者:先知技术社区   2016-11-23  7,566   [本文转自安全脉搏战略合作伙伴先知技术社区 原帖地址  安全脉搏编辑huan97 ...

  2. sql注入篇2

    一.前言 上一篇:sql注入篇1 二.基于回显的注入类型判断 1.有结果的注入 例如下图: (sqlllab less-1)可以看到有正常结果返回,对于的利用方式就是老套路了,先order by查询出 ...

  3. sql注入篇1

    一.前言 学习了感觉很久的渗透,总结一下sql注入,系统整理一下sql注入思路. 二.关于sql注入 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到 ...

  4. Java审计之命令执行篇

    Java审计之命令执行篇 0x00 前言 在Java中能执行命令的类其实并不多,不像php那样各种的命令执行函数.在Java中目前所知的能执行命令的类也就两种,分别是Runtime和 ProcessB ...

  5. [代码审计]某租车系统JAVA代码审计[前台sql注入]

    0x00 前言 艰难徘徊这么久,终于迈出第一步,畏畏缩缩是阻碍大多数人前进的绊脚石,共勉. 系统是租车系统,这个系统是Adog师傅之前发在freebuf(http://www.freebuf.com/ ...

  6. Sql server之sql注入篇

    SQL Injection 关于sql注入的危害在这里就不多做介绍了,相信大家也知道其中的厉害关系.这里有一些sql注入的事件大家感兴趣可以看一下 防范sql注入的方法无非有以下几种: 1.使用类型安 ...

  7. 从Java角度修复SQL注入漏洞

    很多情况因为过滤不严导致很多网站存在sql注入,这里以用户登陆为例,简单举例 首先创建一个测试的数据库 比较基础,不写创建过程了 java代码如下: package cn.basic.jdbc; im ...

  8. Java Filter防止sql注入攻击

    原理,过滤所有请求中含有非法的字符,例如:, & < select delete 等关键字,黑客可以利用这些字符进行注入攻击,原理是后台实现使用拼接字符串,案例:某个网站的登入验证的SQ ...

  9. 我的WafBypass之道(SQL注入篇)

    原帖地址:https://xianzhi.aliyun.com/forum/read/349.html 0x00 前言 去年到现在就一直有人希望我出一篇关于waf绕过的文章,我觉得这种老生常 谈的话题 ...

随机推荐

  1. 【Redis】Redis开篇与如何安装单机版Redis,这次我会了!!

    写在前面 很早之前,就有不少小伙伴微信留言说:冰河,你能不能写一个Redis专栏啊,我最近在学习Redis,看书看不下去,学习视频又觉得视频太长了,还是看你的文章比较给力!哈哈,原来我写的文章能够让小 ...

  2. 2020-08-02:输入ping IP 后敲回车,发包前会发生什么?

    福哥答案2020-08-02: 首先根据目的IP和路由表决定走哪个网卡,再根据网卡的子网掩码地址判断目的IP是否在子网内.如果不在则会通过arp缓存查询IP的网卡地址,不存在的话会通过广播询问目的IP ...

  3. 2020-07-04:tcp三次握手干了啥?time_wait什么时候出现?

    福哥答案2020-07-04:三次握手如下:1.SYN j2.ACK j+1,SYN k3.ACK k+1 time_wait出现在断开连接第四次挥手的时候出现.TIME_WAIT状态存在有两个原因. ...

  4. 2020-03-27:JDK1.8中在数据结构上,对HashMap做了什么样的改进?为什么?

    福哥答案2020-04-04:头插改尾插,解决链表成环的问题.链表改成链表和红黑树.

  5. 2020-04-20:对Java接口代理模式的实现原理的理解?

    静态代理Java中的静态代理要求代理类(ProxySubject)和委托类(RealSubject)都实现同一个接口(Subject).静态代理中代理类在编译期就已经确定,而动态代理则是JVM运行时动 ...

  6. Tensorflow Cpu不支持AVX

    Tensorflow从1.6开始从AVX编译二进制文件,所以如果你的CPU不支持AVX 你需要 从源码编译 下载旧版 从源码编译比较麻烦,如果你是初学的话,我建议使用旧版. 安装旧版: pip3 in ...

  7. STL函数库的应用第一弹——数据结构(队列)

    队列是什么? 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作. 和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除操作的端称为队头 ...

  8. Java中对象和对象引用的区别,引用、指向是什么意思

    Java的变量分为两大类:基本数据类型和引用数据类型. 其中基本类型变量有四类8种:byte short int long float double char boolean,除了8种基本数据类型变量 ...

  9. N46期第一周作业

    1.解释drwx rwx rwx中每个字符表⽰什么? d : 表示目录文件 ①rwx表示UID的读写执行权限  ②rwx表示GID的读写执行权限   ③rwx表示other的读写执行权限   2.li ...

  10. GRMS_README

    基于Hadoop的商品推荐系统 基于特征:基于行为:具有了一定的历史特征. 基于用户: 基于商品: 推荐结果=用户的购买向量*物品的相似度矩阵 物品的相似度:物品的共现次数 1.项目名:GRMS2.添 ...