Sql注入攻擊基本原理

2021-02-15 JAVA技術之家
1、什麼是Sql注入攻擊

SQL注入攻擊通過構建特殊的輸入作為參數傳入Web應用程式,而這些輸入大都是SQL語法裡的一些組合,通過執行SQL語句進而執行攻擊者所要的操作,它目前是黑客對資料庫進行攻擊的最常用手段之一。

本文將帶你從介紹 Web 應用運行原理開始,一步一步理解 Sql 注入的由來、原理和攻擊方式。

2、Web程序三層架構

三層架構(3-tier architecture) 通常意義上就是將整個業務應用劃分為:

界面層(User Interface layer)

業務邏輯層(Business Logic Layer)

數據訪問層(Data access layer)。

區分層次的目的即為了「高內聚低耦合」的思想。在軟體體系架構設計中,分層式結構是最常見,也是最重要的一種結構被應用於眾多類型的軟體開發。

3、Sql注入產生原因及威脅

剛剛講過當我們訪問動態網頁時, Web 伺服器會向數據訪問層發起 Sql 查詢請求,如果權限驗證通過就會執行 Sql 語句。這種網站內部直接發送的Sql請求一般不會有危險,但實際情況是很多時候需要結合用戶的輸入數據動態構造 Sql 語句,如果用戶輸入的數據被構造成惡意 Sql 代碼,Web 應用又未對動態構造的 Sql 語句使用的參數進行審查,則會帶來意想不到的危險。

Sql 注入帶來的威脅主要有如下幾點

猜解後臺資料庫,這是利用最多的方式,盜取網站的敏感信息。
繞過認證,列如繞過驗證登錄網站後臺。
注入可以藉助資料庫的存儲過程進行提權等操作

4、判斷Sql注入點4.1 判斷是否存在sql注入漏洞

通常情況下,可能存在 Sql 注入漏洞的 Url 是類似這種形式 :http://xxx.xxx.xxx/abcd.php?id=XX對 Sql 注入的判斷,主要有兩個方面:

判斷該帶參數的 Url 是否存在 Sql 注入?
如果存在 Sql 注入,那麼屬於哪種 Sql 注入?
可能存在 Sql 注入攻擊的 ASP/PHP/JSP 動態網頁中,一個動態網頁中可能只有一個參數,有時可能有多個參數。有時是整型參數,有時是字符串型參數,不能一概而論。總之只要是帶有參數的 動態網頁且此網頁訪問了資料庫,那麼就有可能存在 Sql 注入。如果程式設計師沒有足夠的安全意識,沒有進行必要的字符過濾,存在SQL注入的可能性就非常大。

最為經典的單引號判斷法:在參數後面加上單引號,比如:

1

http://xxx/abc.php?id=1'

如果頁面返回錯誤,則存在 Sql 注入。原因是無論字符型還是整型都會因為單引號個數不匹配而報錯。(如果未報錯,不代表不存在 Sql 注入,因為有可能頁面對單引號做了過濾,這時可以使用判斷語句進行注入,因為此為入門基礎課程,就不做深入講解了)

4.2 判斷Sql注入漏洞的類型

通常 Sql 注入漏洞分為 2 種類型:

數字型
字符型

其實所有的類型都是根據資料庫本身表的類型所產生的,在我們創建表的時候會發現其後總有個數據類型的限制,而不同的資料庫又有不同的數據類型,但是無論怎麼分常用的查詢數據類型總是以數字與字符來區分的,所以就會產生注入點為何種類型。

4.2.1 數字型判斷

當輸入的參 x 為整型時,通常 abc.php 中 Sql 語句類型大致如下:select * from <表名> where id = x 這種類型可以使用經典的 and 1=1 和 and 1=2 來判斷:

Url 地址中輸入 http://xxx/abc.php?id= x and 1=1 頁面依舊運行正常,繼續進行下一步。
Url 地址中繼續輸入 http://xxx/abc.php?id= x and 1=2 頁面運行錯誤,則說明此 Sql 注入為數字型注入。
原因如下:當輸入 and 1=1時,後臺執行 Sql 語句:

1

select * from <表名> where id = x and 1=1

沒有語法錯誤且邏輯判斷為正確,所以返回正常。

當輸入 and 1=2時,後臺執行 Sql 語句:

1

select * from <表名> where id = x and 1=2

沒有語法錯誤但是邏輯判斷為假,所以返回錯誤。我們再使用假設法:如果這是字符型注入的話,我們輸入以上語句之後應該出現如下情況:

1
2

select * from <表名> where id = 'x and 1=1'
select * from <表名> where id = 'x and 1=2'

查詢語句將 and 語句全部轉換為了字符串,並沒有進行 and 的邏輯判斷,所以不會出現以上結果,故假設是不成立的。

4.2.2 字符型判斷

當輸入的參 x 為字符型時,通常 abc.php 中 SQL 語句類型大致如下:select * from <表名> where id = 『x』 這種類型我們同樣可以使用 and 『1』=』1 和 and 『1』=』2來判斷:

Url 地址中輸入 http://xxx/abc.php?id= x』 and 『1』=』1 頁面運行正常,繼續進行下一步。
Url 地址中繼續輸入 http://xxx/abc.php?id= x』 and 『1』=』2 頁面運行錯誤,則說明此 Sql 注入為字符型注入。
原因如下:當輸入 and 『1』=』1時,後臺執行 Sql 語句:

1

select * from <表名> where id = 'x' and '1'='1'

語法正確,邏輯判斷正確,所以返回正確。

當輸入 and 『1』=』2時,後臺執行 Sql 語句:

1

select * from <表名> where id = 'x' and '1'='2'

語法正確,但邏輯判斷錯誤,所以返回正確。同學們同樣可以使用假設法來驗證。

5、Sql注入實例5.1 繞過登陸

我們正常的登陸是輸入用戶名密碼到後臺資料庫判斷用戶名密碼是否正確,看看後臺代碼是如何實現的

1

select * from user where username = '$name' and password = '$pwd'"

用戶名密碼都輸入123,實際執行的sql語句是:

1

select * from users where username='123' and password='123'

我們嘗試在用戶名中輸入 123』 or 1=1 #, 密碼同樣輸入 123』 or 1=1 #顯示登陸成功,為什麼會登錄成功呢,我們來看看實際執行的sql語句

1

select * from users where username='123' or 1=1 #' and password='123' or 1=1 #'

按照 Mysql 語法,# 後面的內容會被忽略,所以以上語句等同於(實際上密碼框裡不輸入任何東西也一樣):

1

select * from users where username='123' or 1=1

由於判斷語句 or 1=1 恆成立,所以結果當然返回真,成功登錄。我們再嘗試不使用 # 屏蔽單引號,採用手動閉合的方式:我們嘗試在用戶名中輸入 123』 or 『1』=』1, 密碼同樣輸入 123』 or 『1』=』1 (不能少了單引號,否則會有語法錯誤):此處輸入圖片的描述 此處輸入圖片的描述 實際執行的 Sql 語句是:

1

select * from users where username='123' or '1'='1' and password='123' or '1'='1`

看到了嗎?兩個 or 語句使 and 前後兩個判斷永遠恆等於真,所以能夠成功登錄。

還有通過sql語句注入來獲取隱私信息,所以sql注入需要引起程式設計師們的注意。

 6、預防Sql注入的方法

下面我針對JSP,說一下應對方法: 

(1)(簡單又有效的方法)PreparedStatement 

採用預編譯語句集,它內置了處理SQL注入的能力,只要使用它的setXXX方法傳值即可。 

使用好處: 

(1).代碼的可讀性和可維護性. 

(2).PreparedStatement盡最大可能提高性能. 

(3).最重要的一點是極大地提高了安全性. 

原理: 

sql注入只對sql語句的準備(編譯)過程有破壞作用 

而PreparedStatement已經準備好了,執行階段只是把輸入串作為數據處理, 

而不再對sql語句進行解析,準備,因此也就避免了sql注入問題.

(2) 使用正則表達式過濾傳入的參數 

要引入的包: 

import java.util.regex.*; 

正則表達式: 

private String CHECKSQL = 「^(.+)\sand\s(.+)|(.+)\sor(.+)\s$」; 

判斷是否匹配: 

Pattern.matches(CHECKSQL,targerStr); 

下面是具體的正則表達式: 

檢測SQL meta-characters的正則表達式 : 

/(\%27)|(\』)|(–)|(\%23)|(#)/ix 

修正檢測SQL meta-characters的正則表達式 :/((\%3D)|(=))[^\n]*((\%27)|(\』)|(–)|(\%3B)|(:))/i

典型的SQL 注入攻擊的正則表達式 :/\w*((\%27)|(\』))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix

檢測SQL注入,UNION查詢關鍵字的正則表達式 :/((\%27)|(\』))union/ix(\%27)|(\』) 

檢測MS SQL Server SQL注入攻擊的正則表達式: 

/exec(\s|+)+(s|x)p\w+/ix 

等等…..

(3) 字符串過濾 

比較通用的一個方法: 

(||之間的參數可以根據自己程序的需要添加) 

public static boolean sql_inj(String str)
{
String inj_str = 「』|and|exec|insert|select|delete|update|
count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,」;
String inj_stra[] = split(inj_str,」|」);
for (int i=0 ; i < inj_stra.length ; i++ )
{
if (str.indexOf(inj_stra[i])>=0)
{
return true;
}
}
return false;
}

(4) jsp中調用該函數檢查是否包函非法字符

防止SQL從URL注入: 

sql_inj.java代碼:

package sql_inj;
import java.net.*;
import java.io.*;
import java.sql.*;
import java.text.*;
import java.lang.String;
public class sql_inj{
public static boolean sql_inj(String str)
{
String inj_str = 「』|and|exec|insert|select|delete|update|
count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,」;

String[] inj_stra=inj_str.split(「\|」);
for (int i=0 ; i < inj_stra.length ; i++ )
{
if (str.indexOf(inj_stra[i])>=0)
{
return true;
}
}
return false;
}
}

(5) JSP頁面判斷代碼:

使用javascript在客戶端進行不安全字符屏蔽 

功能介紹:檢查是否含有」『」,」\」,」/」 

參數說明:要檢查的字符串 

返回值:0:是1:不是 

函數名是 

function check(a) {
return 1;
fibdn = new Array (」『」 ,」\」,」/」);
i=fibdn.length;
j=a.length;
for (ii=0; ii<i; ii++)
{ for (jj=0; jj<j; jj++)
{ temp1=a.charAt(jj);
temp2=fibdn[ii];
if (tem』; p1==temp2)
{ return 0; }
}
}
return 1;


}

總的說來,防範一般的SQL注入只要在代碼規範上下點功夫就可以了。
凡涉及到執行的SQL中有變量時,用JDBC(或者其他數據持久層)提供的如:PreparedStatement就可以 ,切記不要用拼接字符串的方法就可以了。

歡迎關注

相關焦點

  • Java最新SQL注入原因以及預防方案(易理解)
    前沿在現有的框架中sql防注入已經做得很好了,我們需要做的就是儘量不要使用sql拼接調用java sql注入原因以及預防方案(易理解)SQL注入1.1 原理SQL注入是通過客戶端的輸入把SQL命令注入到一個應用的資料庫中,從而執行惡意的SQL語句。1.2 演示1.2.1 案例1有一個登錄框,需要 輸入用戶名和密碼 ,然後我們的密碼輸入 'or '123' = '123 這樣的。
  • 滲透基礎之SQL注入
    SQL 注入是WEB安全領域中的一種常見的攻擊方式。
  • PHP如何防止XSS攻擊與XSS攻擊原理
    XSS又稱CSS,全稱Cross SiteScript(跨站腳本攻擊), XSS攻擊類似於SQL注入攻擊,是Web程序中常見的漏洞,XSS屬於被動式且用於客戶端的攻擊方式,所以容易被忽略其危害性。其原理是攻擊者向有XSS漏洞的網站中輸入(傳入)惡意的HTML代碼,當用戶瀏覽該網站時,這段HTML代碼會自動執行,從而達到攻擊的目的。
  • Mybatis的sql組裝詳解
    上一篇分析了SqlSession執行sql的過程,其中並沒有分析sql是從哪裡來的,今天就來仔細分析下。Sql來源從上一篇的最後一步執行sql那裡倒推sql的來源,源碼主要過程如下圖:可以看到最後是通過BoundSql直接獲取的sql,然後往前倒推最後發現是通過MappedStatement的getBoundSql方法返回的。
  • HTTP Flood攻擊的原理以及防禦原理
    首先我們要了解下HTTP Flood攻擊的原理:是指攻擊者通過代理或殭屍主機向目標伺服器發起大量的HTTP報文,請求涉及資料庫操作的URI(Universal Resource Identifier)或其它消耗系統資源的URI,造成伺服器資源耗盡,無法響應正常請求。
  • sqltoy-orm-4.16.11 發版,部分功能優化
    的十四個關鍵特點:1、最簡最直觀的sql編寫方式(不僅僅是查詢語句),採用條件參數前置處理規整法,讓sql語句部分跟客戶端保持高度一致2、sql中支持注釋(規避了對hint特性的影響,知道hint嗎?搜oracle hint),和動態更新加載,便於開發和後期維護整個過程的管理3、支持緩存翻譯和反向緩存條件檢索(通過緩存將名稱匹配成精確的key),實現sql簡化和性能大幅提升4、支持快速分頁和分頁優化功能,實現分頁最高級別的優化,同時還考慮到了cte多個with as情況下的優化支持5、支持並行查詢6、根本杜絕sql注入問題,以後不需要討論這個話題7、支持行列轉換
  • 極致性能 sqltoy-orm-4.12.9 發版 - OSCHINA - 中文開源技術交流...
    具有JPA模式的CRUD功能(即CRUD無需寫sql),無需寫Dao,sqltoy提供了SqlToyLazyDao,同時提供了quickvo從資料庫生成POJO。 根本上杜絕了sql注入問題 最科學的sql編寫方式* sqltoy的sql編寫(支持嵌套)select *from sqltoy_device_order_info t where #[
  • sqltoy-orm-4.16.16 發版,並行查詢場景增強、級聯增加排序
    對spring.sqltoy 配置的校驗,避免有開發者寫成sqltoy.xxx遺漏掉spring前綴7、sqltoy中增強sqlResourcesDir 格式的交易,防止開發者寫成文件匹配表達式8、強化未匹配到sql的sqlId執行錯誤提示,避免開發者遇到錯誤時無法定位錯誤9、updateByQuery增加統一欄位處理,針對最後修改時間、最後修改人等公共欄位
  • Feigong:針對各種情況自由變化的MySQL注入腳本
    在使用非攻之前  1、首先你需要找到一個注入點(在考慮寫一個這樣的工具)  2、判斷資料庫為mysql  3、通過巧妙地過濾可以獲取數據  4、開始使用非攻  TODO      完成基本功能          優化log存儲方式          優化build注入、
  • 極致查詢性能 sqltoy-orm-4.12.8 發版增加對國產達夢資料庫支持
    特點說明: 支持mysql、postgresql、db2、oracle、sqlserver、sqlite、clickhouse、elasticsearch、mongodb等 具有JPA模式的CRUD功能(即CRUD無需寫sql),無需寫Dao,sqltoy提供了SqlToyLazyDao,同時提供了
  • 常見的DDOS攻擊及原理-應用層
    二、 DDoS的類型及原理DDOS攻擊主要分為三類:流量型攻擊;連接型攻擊;特殊協議缺陷。1、 Ip lood攻擊原理:此攻擊以多個隨機的源主機地址向目的主機發送超大量的隨機或特定的IP包,造成目標主機不能處理其他正常的IP報文。
  • 第02篇:SQL資料庫的四種基本操作「增刪改查」
    本章主要講解資料庫的常規基本操作,即:增(insert)、刪(delete)、改(update)、查(select)四種操作。其中,查詢的使用頻率最高且語法規則較多,是本章學習的重點和難點。具體操作:先選擇一個「資料庫」,再點擊工具欄的「新建查詢」,右邊會出現空白的代碼編寫區域,這就是書寫SQL腳本的地方,文件保存的後綴名為(*.sql)。以後所有的SQL腳本都可以這樣創建。
  • sql注入入門 之 mssql常規顯錯注入
    1,mssql常規顯錯型,實例注入點,如下:http://vuln.com/Product.aspx?id=8
  • Oracle DBA之常用SQL
    有好多人或事,出現計劃外的狀況,最後那句「但,我依然愛你」 最靚虛擬環境的坑確實很多,tsm相關測試還在繼續,暫且整點sql當夜宵吧。語句select dbms_Lob.substr(a.SQL_FULLTEXT) from v$sql a where sql_id='0x7b21d4ed';select dbms_Lob.substr(s.SQL_FULLTEXT) from v$sql s,v$session se,v$process p where se.paddr=p.addr and s.sql_id
  • 帶你快速了解spark sql
    01spark sql架構spark sql是一種可以通過sql執行spark任務的分布式解析引擎。它能夠將用戶編寫的sql語言解析成RDD對應的分布式任務,由於spark是基於內存去處理、計算數據集,所以其執行速度非常快。spark sql對應的結構可以總結為下圖所示:DataSet,顧名思義,就是數據集的意思,它是 Spark 1.6 新引入的接口。
  • sql替換資料庫欄位中的字符
    下面就用sql批量進行替換。替換shopping_hw表中欄位hw_pic,內容「*common」替換為「+play」.替換sql:UPDATE shopping_hw SET  hw_pic= replace (hw_pic,  '*common', '+play' ) ;運行sql,替換成功,查看結果。
  • JAVA-新手入門:JAVA資料庫基本操作指南
    java 資料庫基本操作  1、java資料庫操作基本流程  2、幾個常用的重要技巧:  ·可滾動、更新的記錄集  ·批量更新  ·事務處理java資料庫操作基本流程:取得資料庫連接 - 執行sql語句 - 處理執行結果 - 釋放資料庫連接基礎視頻有挺多的你是看你的學習欲望!!!!
  • 女朋友都能看懂的,SQL優化乾貨
    >select * from teacher where name like '李%'如果一定要在欄位開頭模糊查詢,那可以使用INSTR(str,substr)意思是:在字符串str裡面,字符串substr出現的第一個位置(index),index是從1開始計算,如果沒有找到就直接返回0 ,所以可以使用如下sql
  • 「原創」試論海賊王980話阿普的攻擊原理
    ,在509話,阿普攻擊黃猿前也演奏了一段「戰鬥音樂」。Bwowww(因為980我看的是英文版,不曉得漢化會翻成什麼)動作:彈撥手臂上弦一般的線效果:目標物像挨了一拳般(當然也可能是被彈了一下)除了「Bwowww」是第一次新出現,980話和509話阿普的攻擊流程、動作基本一樣,因此合理推測那些是發動能力的條件