通過某大學生的的畢業設計複習java-sql審計

2022-01-14 合天網安實驗室
黑客極客技術、信息安全熱點
安全研究分析
等安全相關的技術文章

sql注入原理:業務端代碼從客戶端接收到惡意payload之後沒有進行過濾直接進行sql語句拼接並且執行造成sql注入

本人正在拜讀一本代碼審計的書感覺非常的棒,剛剛好室友在挑戰自己,就順便整理一下知識點!


1.原生jdbc連接無過濾造成sql注入

我們看下面這段代碼,首先從客戶端接收傳進來的id的值拼接成sql語句,然後Statement去編譯拼接的sql語句,將結果傳給rs之後讀出,這裡沒有對傳進來的值進行任何過濾,嘗試去構造sql語句造成注入

String sql = "select * from user where id ="+req.getParameter("id");       PrintWriter out = resp.getWriter();       out.println("Statement Demo");       out.println("SQL: "+sql);       try {           Statement st = conn.createStatement();           ResultSet rs = st.executeQuery(sql);           while (rs.next()){               out.println("<br>Result: "+ rs.getObject("name"));          }      } catch (SQLException throwables) {           throwables.printStackTrace();      }

正常訪問


構造測試payload進行測試,可以看到這邊是執行了構造過的payload,返回了開發者不想讓我們看到的內容


2.原生jdbc預編譯開發失誤導致sql注入

上面第一種存在sql注入的情況是因為每次執行都會將sql語句進行編譯在資料庫中執行,為了防止sql注入,可以使用prepareStatement進行預編譯sql語句,使用?佔位符來傳可改變的值,但是因為sql語句已經編譯過,所以按道理來說這裡傳進來的值只會被當作字符串數據處理不作為sql語句的一部分,傳進來的值不參與編譯也就是不會在sql裡執行,但是開發者也可能出錯就是在使用prepareStatement時仍然使用sql拼接而不是用佔位符或者在預編譯之後再次執行sql語句!

我們首先看一下不存在sql注入的代碼,使用問號佔位符,預編譯sql語句,從下面第二張圖可以看到這時候sql語句是一個問號而我們傳進去的值不在資料庫中運行並且沒有返回結果的!可以比較好的防止sql注入,這時候我們來講講為什麼預編譯可以防止sql注入,當我們sql執行的時候大致會經歷幾個階段分別是編譯--優化--緩存--執行,當使用prepareStatement時,他是將上述的步驟已經執行過了,將結果放到了緩存當中,用戶的輸入只作為數據進行填充而不是sql的一部分,然後伺服器從緩存中獲得已經編譯之後的語句,替換掉用戶輸入的數據執行以達到防止sql注入的目的!

String sql = "select * from user where id = ?";       PrintWriter out = resp.getWriter();       out.println("prepareStatement Demo");       out.println("SQL: "+sql);       try {           PreparedStatement pst = conn.prepareStatement(sql);           pst.setString(1,req.getParameter("id"));           ResultSet rs = pst.executeQuery();           while (rs.next()){               out.println("<br>Result: "+ rs.getObject("id"));          }
image-20211107193812360


看了安全代碼,我們看以下預編譯依舊存在問題的代碼

雖然使用預編譯但是sql語句依舊是拼接的!就會造成sql注入,看第一行,開發者忘記使用佔位符導致sql語句依舊是拼接進去的

  String sql = "select * from user where id ="+req.getParameter("id");       PrintWriter out = resp.getWriter();       out.println("prepareStatement Demo");       out.println("SQL: "+sql);       try {           PreparedStatement pst = conn.prepareStatement(sql);           ResultSet rs = pst.executeQuery();           while (rs.next()){               out.println("<br>Result: "+ rs.getObject("id"));          }      } catch (SQLException throwables) {           throwables.printStackTrace();      }


3.分析mybatis框架類sql注入的情況

使用mybatis的好處是將sql整合到一個地方避免代碼中出現大量的sql語句並且其接近原生sql。比較靈活,但是當xml裡的sql語句是用$做佔位符時,sql語句依舊是拼接而成的,這時候便會存在sql注入

select * from user1 where name = ${name}

下圖可以看到傳進來的值已經被執行了


4.審計室友的畢業設計

搭好室友的畢業設計之後,簡單看了一下,這是一個商城後臺管理系統,SSM框架的,然後找了一下入口點,發現只有登錄界面是開放的入口。其他的地方權限都做了token驗證,然後看他登錄是怎麼寫的

 @RequestMapping("/login")   public String login(User user)  {       if (userService.login(user)==1)      {
return "head"; } else { return "login"; } }

看看上面寫的,就很簡單粗暴,然後就跟進去看server層裡看看寫了什麼判斷邏輯沒有。

  @Override   public int login(User user) {       return userMapper.login(user);  }

看了一下也沒問題,繼續往下走,發現室友mybatis裡的sql全部是使用$拼接的!這不就成了麼

 <!--    登陸驗證-->   <select id="login" parameterType="user" resultType="java.lang.Integer">       select count(*)       from user       where user_name = '${userName}'         and password = '${password}'   </select>

根據一開始controller裡寫的,是判斷返回值等於1,然後就可以登錄後臺,這時候就可以構造sql讓返回值等於1!

然後他所有的sql都是使用$,存在大量的sql注入,以此說明了讀書還是要認真!不要老聽老頭過時的技術!自己要有思考!

推薦實操:SQL注入進階

PC端練習地址:http://mrw.so/6eK95U

在掌握了基本的注入手段後。我們嘗試繞過各種針對SQL注入的防護,並繼續注入。

相關焦點

  • Java代碼審計 -- SQL注入
    收錄於話題 #代碼審計:admin' and 1=1#
  • 技術分享 | Java代審4:SQL 注入-JDBC復現
    攻擊者可通過SQL注入直接獲取資料庫信息,造成信息洩漏。在開始審計一個項目,我們需要對項目的結構進行分析,了解項目的結構便於我們針對功能點與模塊進行分析。快速定位漏洞。下面是項目的基本結構。使用框架的話會有一些目錄結構發生變化,在這裡不進行探討。
  • 計算機畢業設計選題大全
    一般來說,計算機專業包含了很多程式語言,比如有java,php,vb.net,vc++,asp,asp.net,vc等等;資料庫內有sql server,mysql,Access等等,而且每個程式語言使用的技術都是不一樣的。
  • java.util.Date 與 java.sql.Date 相關知識點解析
    問:java.sql.Date 和 java.util.Date 有什麼區別?
  • java中有沒有類似sql的group by的功能呢
    我們現在做的很多系統都是離不開資料庫的,所以經常會使用到sql語句做數據增刪改查,而其中查詢使用的應該也是最多的。在sql查詢中有一個分組查詢的功能,就是通過「group by」將數據進行分組處理。那java中有沒有類似這樣的分組功能呢。
  • Java從零開始學-第54天:動態SQL,這麼多種你都會?
    上面這種寫法相對於java代碼看起來是不是清爽了很多,也更方便維護,大家注意一下sql中有個WHERE 1=1,如果沒有這個,上面單通過if元素就不好實現了,mybatis也有解決方案,稍後會說明。sql4在sql4後面追加trim中suffix指定的值,得到最終需要拼接的sql5了解了這個過程之後,說明可以通過trim來代替where和set,我們使用trim來改造一下案例1,如下:<select id="getList1" resultType="com.javacode2018.chat05.demo8.model.UserModel"
  • |sql|mysql|數據源|java|...
    Driver接口  java.sql.Driver  此接口是提供給資料庫廠商實現的。比如說MySQL的,需要依賴對應的jar包。  package  com.mysql.cj.jdbc;  public  class  NonRegisteringDriver  implements  java  .  sql  .
  • java面試真題分享34-36
    int是java提供的8種原始數據類型之一,Java為每個原始類型提供了封裝類,Integer是java為int提供的封裝類。35.java.sql.Date和java.util.Date的聯繫和區別1) java.sql.Date是java.util.Date的子類,是一個包裝了毫秒值的瘦包裝器,允許 JDBC 將毫秒值標識為 SQL DATE 值。毫秒值表示自 1970 年 1 月 1 日 00:00:00 GMT 以來經過的毫秒數。
  • 像寫SQL一樣編寫Java數據應用
    第一步:定義POJO[java] view plaincopypublic class Custom { private String id; private String name; private int age; public String getId() { return
  • 資料庫設計:使用PD16創建常用目錄欄並生成sql語句實例!
    創建模型文件新增模型選model types下的Conceptual Diagram,也就是概念模型CDM模型,模型名稱可以填你需要的名字構建模型選擇右邊的表格新建實體設計目錄欄Attributes一般採用下換線命名法這裡目錄欄是這麼設計的id是唯一ID號Code是目錄的編碼,我們採用1001|0011|0010這樣子的模式進行編碼,這種目錄的方式是,很容易通過like』0001』就可以查詢它的子菜單,比如0001
  • nutz-sqltpl 1.3.RELEASE 發布,「解決java拼接sql」
    簡單介紹    1、使用 xml 對 sql 片段進行管理,類似 mybatis
  • 學好java,掌握java編程思想很重要!學習java分三步
    浮雲我是一個剛剛畢業的大學生,專業是學的java,但是由於在大學時期貪玩,打遊戲,導致專業技術不過關,因此,在做了一番思想鬥爭過後,我決定了在我所在的城市找了一個培訓學校,所以我也就從頭學習java了。
  • Java程式設計師開發必備 MyBatis高級應用之逆向工程自動生成SQL語句
    MyBatis的一個主要的特點就是需要程式設計師自己編寫sql,那麼如果表太多的話,難免會很麻煩,所以mybatis官方提供了一個逆向工程,可以針對單表自動生成mybatis執行所需要的代碼,一般在開發中,常用的逆向工程方式是通過資料庫的表生成代碼。
  • SQL注入攻擊詳解
    在軟體體系架構設計中,分層式結構是最常見,也是最重要的一種結構被應用於眾多類型的軟體開發。3、Sql注入產生原因及威脅剛剛講過當我們訪問動態網頁時, Web 伺服器會向數據訪問層發起 Sql 查詢請求,如果權限驗證通過就會執行 Sql 語句。
  • java中資料庫:JDBC的使用
    JDBC是java中提供的一套資料庫編程API,它定義了一套用來訪問資料庫的標準Java類庫(位於java.sql和javax.sql
  • 【超詳細乾貨】【收藏向】【Java面試必備】一文搞定Java資料庫基礎JDBC
    通過連接對象得到語句對象statement = conn.createStatement();//3. 通過語句對象發送 SQL 語句給伺服器//4.package com.lqg;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Statement;/*** 向學生表中添加 4 條記錄,主鍵是自動增長*/public class Demo5DML {public
  • JAVA-新手入門:JAVA資料庫基本操作指南
    java 資料庫基本操作  1、java資料庫操作基本流程  2、幾個常用的重要技巧:  ·可滾動、更新的記錄集  ·批量更新  ·事務處理java資料庫操作基本流程:取得資料庫連接 - 執行sql語句 - 處理執行結果 - 釋放資料庫連接基礎視頻有挺多的你是看你的學習欲望!!!!
  • 8千字java反射乾貨|java反射精講
    反射的應用示例反射機制的概念:在運行狀態中,對於任意一個類,都能夠獲取到這個類的所有屬性和方法,對於任意一個對象,都能夠調用它的任意一個方法和屬性(包括私有的方法和屬性),這種動態獲取的信息以及動態調用對象的方法的功能就稱為java語言的反射機制。反射被視為動態語言的關鍵。簡單來說反射就是java的各種成分映射成對應的java類。
  • SQL 語句中 where 條件後 寫上 1=1 是什麼意思
    2020-04-01 11:47:21 來源: java進階架構師 舉報
  • 【Flink】小白級入門,Flink sql 的基礎用法
    Flink sql 是什麼❝sql 的誕生就是為了簡化我們對數據開發,可以使用少量的 sql 代碼,幫助我完成對數據的查詢,分析等功能❞聲明式 & 易於理解對於用戶只需要表達我想要什麼,具體處理邏輯交給框架,系統處理,用戶無需關心,對於一些非專業的開發人員有了解 sql,並且 sql 相對我們學習 java,c 等語言更簡單