Java審計之SQL注入篇

Java審計之SQL注入篇

0x00 前言

本篇文章做爲Java Web 審計的一個入門文,也是個人第一篇審計文,後面打算更新一個小系列,來記錄一下個人審計學習的成長。css

0x01 JDBC 注入分析

在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注入的代碼。

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

前面的環境配置了比較久,耽誤了很多時間。

相關文章
相關標籤/搜索