1、研究緩衝區溢出的原理,至少針對兩種數據庫進行差別化研究php
1.1 原理mysql
在計算機內部,輸入數據一般被存放在一個臨時空間內,這個臨時存放的空間就被稱爲緩衝區,緩衝區的長度事先已經被程序或者操做系統定義好了。向緩衝區內填充數據,若是數據的長度很長,超過了緩衝區自己的容量,那麼數據就會溢出存儲空間,而這些溢出的數據還會覆蓋在合法的數據上,這就是緩衝區和緩衝區溢出的道理。linux
1.2 對抗緩衝區溢出攻擊程序員
爲了在系統中插入攻擊代碼,攻擊者不但要插入代碼,還要插入指向這段代碼的指針,這個指針也是攻擊字符串的一部分。產生這個指針須要知道這個字符串放置的棧地址。在過去,程序的棧地址很是容易預測,在不一樣的機器之間,棧的位置是至關固定的。
棧隨機化的思想使得棧的位置在程序每次運行時都有變化。所以,即便許多機器都運行相同的代碼。它們的棧地址都是不一樣的。
實現的方式是:程序開始時,在棧上分配一段0--n字節之間的隨機大小空間。程序不使用這段空間,可是它會致使程序每次執行時後續的棧位置發生了變化。web
在Linux系統中,棧隨機化已經變成了標準行爲。(在linux上每次運行相同的程序,其同一局部變量的地址都不相同)sql
在C語言中,沒有可靠的方法來防止對數組的越界寫,可是,咱們可以在發生了越界寫的時候,在沒有形成任何有害結果以前,嘗試檢測到它。
最近的GCC版本在產生的代碼中加入了一種棧保護者機制,用來檢測緩衝區越界,其思想是在棧中任何局部緩衝區與棧狀態之間存儲一個特殊的金絲雀值。這個金絲雀值是在程序每次運行時隨機產生的,所以,攻擊者沒有簡單的辦法知道它是什麼。
在恢復寄存器狀態和從函數返回以前,程序檢查這個金絲雀值是否被該函數的某個操做或者函數調用的某個操做改變了。若是是,那麼程序異常終止。數據庫
限制那些可以存放可執行代碼的存儲器區域。在典型的程序中,只有保存編譯器產生的代碼的那部分存儲器才須要是可執行的,其餘部分能夠被限制爲只容許讀和寫。
如今的64位處理器的內存保護引入了」NX」(不執行)位。有了這個特性,棧能夠被標記爲可讀和可寫,可是不可執行,檢查頁是否可執行由硬件來完成,效率上沒有損失。編程
1.3 數據庫後端
MySQL是一款開放源代碼關係型數據庫系統。數組
MySQL包含的mysql_real_connect()函數不充分檢查用戶提供的參數值,本地或遠程攻擊者能夠利用這個漏洞進行緩衝區溢出攻擊,可能用來破壞數據庫或執行任意指令。
攻擊者能夠利用SQL注入攻擊,或者可上傳惡意腳本到服務器上,經過傳遞超長的字符串做爲mysql_real_connect()函數參數,可觸發溢出,精心構建提交數據可能以數據庫進程權限在系統上執行任意指令。
2、針對不一樣數據類型,研究SQL注入點的發現與注入技術
2.1 sql注入
SQL注入攻擊經過構建特殊的輸入做爲參數傳入Web應用程序,而這些輸入大都是SQL語法裏的一些組合,經過執行SQL語句進而執行攻擊者所要的操做。
SQL注入便是指web應用程序對用戶輸入數據的合法性沒有判斷,攻擊者能夠在web應用程序中事先定義好的查詢語句的結尾上添加額外的SQL語句,以此來實現欺騙數據庫服務器執行非受權的任意查詢,從而進一步獲得相應的數據信息。
● SQL注入威脅表現形式能夠體現爲如下幾點:
繞過認證,得到非法權限 猜解後臺數據庫所有的信息 注入能夠藉助數據庫的存儲過程進行提權等操做
● SQL注入攻擊的典型手段:
判斷應用程序是否存在注入漏洞 收集信息、並判斷數據庫類型 根據注入參數類型,重構SQL語句的原貌 猜解表名、字段名 獲取帳戶信息、攻擊web或爲下一步攻擊作準備
● 注入方法
當輸入的參 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 注入爲數字型注入。
當輸入的參 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 注入爲字符型注入。
這是一種特殊的注入類型。這類注入主要是指在進行數據搜索時沒過濾搜索參數,通常在連接地址中有「keyword=關鍵字」,有的不顯示的連接地址,而是直接經過搜索框表單提交。
此類注入點提交的 SQL 語句,其原形大體爲:
select * from 表名 where 字段 like '%關鍵字%'
當咱們提交注入參數爲「keyword='and[查詢條件] and '%'=',則向數據庫提交的完事SQL語句爲:
select * from 表名 where 字段 like '%' and [查詢條件] and '%'='%'
2.2 經過 LAMP 搭建 Sql 注入環境
2.2.1 Sql 注入示例一.猜解數據庫
(1)以下圖所示,先下載文件並解壓運行:
(2)進入 Firefox 瀏覽器,輸入網址 : localhost/dvwasql , 點擊create/Reset Database建立數據庫:
(3)進入登陸界面,默認用戶名爲:admin 密碼爲:password
(4)將 Security 級別調整爲 low
(5)進入 SQL injection頁面開始注入:
(6)先輸入 1 ,查看回顯 (URL中ID=1,說明php頁面經過get方法傳遞參數):
(7)那實際上後臺執行了什麼樣的Sql語句呢?點擊 view source查看源代碼 :
能夠看到,實際執行的Sql語句是:
SELECT first_name, last_name FROM users WHERE user_id = '1';
咱們是經過控制參數Id的值來返回咱們須要的信息。若是咱們不按常理出牌,好比在輸入框中輸入 1' order by 1#,實際執行的Sql語句就會變成:
SELECT first_name, last_name FROM users WHERE user_id = '1' order by 1#`;(按照Mysql語法,#後面會被註釋掉,使用這種方法屏蔽掉後面的單引號,避免語法錯誤)
這條語句的意思是查詢users表中user_id爲1的數據並按第一字段排行。
(8)輸入 1' order by 1#和 1' order by 2#時都返回正常,當輸入 1' order by 3#時,返回錯誤:
由此可知,users表中只有兩個字段,數據爲兩列。
接下來咱們使用 union select聯合查詢繼續獲取信息。union 運算符能夠將兩個或兩個以上 select 語句的查詢結果集合合併成一個結果集合顯示,即執行聯合查詢。須要注意在使用 union 查詢的時候須要和主查詢的列數相同,而咱們以前已經知道了主查詢列數爲 2,接下來就好辦了。輸入1' union select database(),user()#進行查詢 :
實際執行的Sql語句是 :
SELECT first_name, last_name FROM users WHERE user_id = '1' union select database(),user()#`;
經過上圖返回信息,咱們成功獲取到:
同理咱們再輸入 1' union select version(),@@version_compile_os#進行查詢:
實際執行的Sql語句是:
SELECT first_name, last_name FROM users WHERE user_id = '1' union select version(),@@version_compile_os#`;
(9)接下來咱們嘗試獲取 dvwa 數據庫中的表名。
由經驗咱們能夠大膽猜想users表的字段爲 user 和 password ,因此輸入:1' union select user,password from users#進行查詢:
2.2.2 Sql 注入實例二.驗證繞過
(1)以下圖所示,先下載文件並解壓運行:
(2)進入 Firefox 瀏覽器,輸入網址 : localhost/sql2 , 按照順序,初始化數據:
(3)準備工做完成以後,咱們進入首頁發現這是一個普通的登陸頁面,只要輸入正確的用戶名和密碼就能登陸成功。咱們先嚐試隨意輸入用戶名 123 和密碼 123 登陸,發現提示錯誤。
(4)按照第一個實驗的思路,咱們嘗試在用戶名中輸入 123' or 1=1 #, 密碼一樣輸入 123' or 1=1 # :
爲何可以成功登錄呢?由於實際執行的語句是:
select * from users where username='123' or 1=1 #' and password='123' or 1=1 #'
按照 Mysql 語法,# 後面的內容會被忽略,因此以上語句等同於(實際上密碼框裏不輸入任何東西也同樣):
select * from users where username='123' or 1=1
因爲判斷語句 or 1=1 恆成立,因此結果固然返回真,成功登陸。
(5)再嘗試不使用 # 屏蔽單引號,採用手動閉合的方式:咱們嘗試在用戶名中輸入 123' or '1'='1, 密碼一樣輸入 123' or '1'='1 (不能少了單引號,不然會有語法錯誤):
實際執行的 Sql 語句是:
select * from users where username='123' or '1'='1' and password='123' or '1'='1`
兩個 or 語句使 and 先後兩個判斷永遠恆等於真,因此可以成功登陸。
3、研究緩衝區溢出的防範方法,至少針對兩種編程語言進行差別化研究
根據緩衝區溢出攻擊的步驟,可將經常使用的緩衝區溢出攻擊檢測技術分爲如下3種類型:
3.1 基於輸入字符串的檢測方法
對輸入的字符串進行檢測,肯定其爲溢出攻擊字符串時採起阻攔措施,使攻擊者沒法注入攻擊代碼。通常有如下3 種方法構建溢出攻擊字符串
3.2 基於保護堆棧中返回地址的檢測方法
緩衝區溢出攻擊最關鍵的步驟是要經過修改函數返回地址來改變程序的流程,所以,在函數調用返回前,經過檢查返回地址是否被修改能夠判斷是否有緩衝區溢出攻擊發生。
緩衝區溢出攻擊佔了遠程網絡攻擊的絕大多數,這種攻擊可使得一個匿名的Internet用戶有機會得到一臺主機的部分或所有的控制權。若是能有效地消除緩衝區溢出的漏洞,則很大一部分的安全威脅能夠獲得緩解。 目前有三種基本的方法保護緩衝區免受緩衝區溢出的攻擊和影響:
(1)經過操做系統使得緩衝區不可執行,從而阻止攻擊者植入攻擊代碼
(2)強制寫正確的代碼的方法
(3)利用編譯器的邊界檢查來實現緩衝區的保護,使得緩衝區溢出不可能出現,從而徹底消除了緩衝區溢出的威脅
4、至少使用兩種數據庫注入攻擊工具
4.1 Sqlmap
Sqlmap是一個自動SQL 注入工具。其可勝任執行一個普遍的數據庫管理系統後端指紋,檢索DBMS數據庫、usernames、表格、列、並列舉整個DBMS信息。
Sqlmap提供轉儲數據庫表以及MySQL、PostgreSQL、SQL Server服務器下載或上傳任何文件並執行任意代碼的能力。
4.2 tnscmd10g
容許咱們向Oracle數據庫中注入命令
通常來講,SQL注入通常存在於形如HTTP://xxx.xxx.xxx/abc.asp?id=XX等帶有參數的ASP動態網頁中,有時一個動態網頁中可能只有一個參數,有時可能又N個參數,有時是整型參數,有時是字符串型參數,不能一律而論。總之只要是帶有參數的動態網頁且此網頁訪問了數據庫,那麼就有可能存在SQL注入。若是ASP程序員沒有安全意識,不進行必要的字符過濾,存在SQL注入的可能性就很是大。至於如何防範SQL注入攻擊:請參考
http://blog.csdn.net/testeralai/article/details/26478469