本篇文章做为Java Web 审计的一个入门文,也是个人第一篇审计文,后面打算更新一个小系列,来记录一下个人审计学习的成长。css
在Java里面常见的数据库链接方式也就那么几个,分别是JDBC,Mybatis,和Hibernate。html
JDBC的链接是比较繁琐的,而且是最原始的链接方式,咱们来看看JDBC的最原始的链接代码java
Get型注入:mysql
@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注入。web
在实际运用当中若是不采用框架使用JDBC的方式,广泛会编写一个工具类来完成这些繁琐的配置,可是具体的实现仍是调用这些方法来进行实现,只是进行了一个简单的封装。spring
在代码审计的时候,若是看到是JDBC的方式进行链接能够跟踪一下他的代码,看他有没有调用本身定义的过滤方法,若是没有的话,就会存在sql注入,固然这是在未使用预编译的状况下。sql
后面的重复的比较多,都是大体相同,我后面就贴出一些主要的代码进行分析。数据库
POST型注入:tomcat
String sql = "select * from users where username = '"+username+"' and password = '"+password+"' ";
GET的注入和POST的其实差很少,只是获取值的地方不同。mybatis
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注入的代码。
预编译的定义其实就是使用问号先来占位,后面再传入具体的值。
后面传值的时候,程序会把传入的参数,自动转换为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();
Mybatis获取值的方式有两种,分别是${}
和 #{}
。
#{}:解析的是占位符问号,能够防止SQL注入,使用了预编译。 ${}:直接获取值
在Mybatis里面通常会采用#{}
来进行取值,可是也会有特殊状况。
咱们这里仍是以代码作演示
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注入的。
Select * from news where id in (#{id}),
也是拼接使用预编译这样的代码也会报错。
正确写法:
Select * from news where id in (${id})
Select * from news where title ='#{titlename}' order by #{time} asc
执行会报错
正确写法:
Select * from news where title ='#{titlename}' order by ${time} asc
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
(哈哈哈,实际上是看说明文档知道的。)
文件的划分很细,很清楚看到他的结构,点开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
前面的环境配置了比较久,耽误了很多时间。