zoukankan      html  css  js  c++  java
  • Java审计之SQL注入篇

    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 结尾

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

    WX:TG9yaTI1NDgyNjYxNDU= 欢迎各位师傅来一起做技术交流
  • 相关阅读:
    令Django 视图有默认 login_required
    令Django 视图有默认 login_required
    Python 资源
    Python 资源
    小米3 日历 同步google日历
    小米3 日历 同步google日历
    sql语句 case
    DDOSIM安装
    DDos工具tfn2k的编译
    RPM和YUM
  • 原文地址:https://www.cnblogs.com/nice0e3/p/13647511.html
Copyright © 2011-2022 走看看