萬盛學電腦網

 萬盛學電腦網 >> 無線網絡知識 >> SQL在網絡安全中的應用

SQL在網絡安全中的應用

  本文是小編帶來的無線路由器配置錯誤分析,歡迎大家閱讀借鑒,希望能幫到你。

  1.網絡應用和SQL注射

  1.1概述

  有些網絡數據庫沒有過濾客戶提供的數據中可能有害的字符,SQL注射就是利用插入有害字符進行攻擊的技術。盡管非常容易防范,但因特網上仍然有驚人數量的存儲系統容易受到這種攻擊。這篇文章的目的是指導專業安全組織了解這種技術,並告訴他們正確的,用來防范SQL注射的辦法,以及處理各種常見的,由於非法輸入引起的問題.

  1.2背景

  在讀這篇文章之前,你應該對數據庫如何工作,以及SQL如何被用來訪問數據庫有一些基礎的了解。我建議您閱讀eXtropia.com的文章“Introduction to Databases for WebDevelopers”。

  1.3字符編碼

  在大多數的網絡浏覽器中,標點符號和許多其它符號在用於一個網絡請求前需要把URL編碼,以便被適當地編譯(interpret)。在本文中的例子和截圖中我使用了固定的ASCII字符以保證最大的可讀性。然而,在實際應用中,你需要在HTTP請求中用%25來代替百分號(%),用%2B來代替加號(+)等等。

  2.網絡應用和SQL注射

  2.1概述

  有些網絡數據庫沒有過濾客戶提供的數據中可能有害的字符,SQL注射就是利用插入有害字符進行攻擊的技術。盡管非常容易防范,但因特網上仍然有驚人數量的存儲系統容易受到這種攻擊。這篇文章的目的是指導專業安全組織了解這種技術,並告訴他們正確的,用來防范SQL注射的辦法,以及處理各種常見的,由於非法輸入引起的問題.

  2.2背景

  在讀這篇文章之前,你應該對數據庫如何工作,以及SQL如何被用來訪問數據庫有一些基礎的了解。我建議您閱讀eXtropia.com的文章“Introduction to Databases for WebDevelopers”。

  2.3字符編碼

  在大多數的網絡浏覽器中,標點符號和許多其它符號在用於一個網絡請求前需要把URL編碼,以便被適當地編譯(interpret)。在本文中的例子和截圖中我使用了固定的ASCII字符以保證最大的可讀性。然而,在實際應用中,你需要在HTTP請求中用%25來代替百分號(%),用%2B來代替加號(+)等等。。。

  2.4. LIKE語句查詢

  另一個大的災難是陷入一個LIKE子句的陷阱.(Seeing the LIKE keyword or percent signs cited in an error message are indications of this situation.)大多數的web搜索程序使用LIKE子句來查詢數據庫,比如下面這個:

  SQLString = "SELECT FirstName, LastName, Title FROM Employees WHERE LastName LIKE '%" & strLastNameSearch & "%'"

  這裡面的%是通配符,在這個例子裡,WHERE子句會返回TRUE,只要LASTNAME裡有字符串含有strLastNameSearch.為了阻止SQL SERVER返回預計中的記錄,你構造的SQL語句裡必須含有LASTNAME裡沒有的字符串.web搜索程序搜索的字符串來自於用戶的輸入.通常有一個'和一個%在輸入的字符串之前,因此我們構造字符串時,需要在WHERE子句中匹配它們.如果你提交了NULL作為搜索字符串,那麼LIKE的參數會變成"%%",這是一個全匹配,會返回所有的記錄.

  2.5 “死胡同”

  大部分的時候sql injection都要伴隨著大量失敗的實踐,如果你發現你無論如何都不能插入相關的語句,並且無論你怎麼做都不對,這個時候你就要判斷自己是否掉進了一個死胡同,很多時候遇到這種情況你很可能是在一個多重嵌套的WHERE和SELECT子句的語句中,或者一些更加復雜的多重嵌套,連使用“;--”都沒有用,所以自己要小心和避免在這種地方停留。

  2.6列的數目不匹配問題

  如圖所示,我們可以從幾次錯誤中得到很多有用的信息,並且加以調整自己的請求語句,這種信息多了,那就意味著我們離成功不遠了。在猜列名時,如圖所示,我們提交語句後會碰到以下錯誤“在UNION語句中的所有查詢都必須在目標列表中具有相同數目的表達式”,這就是說你需要找出或者說是探測出在合法的請求中有多少個列。

  這裡我解釋一下,UNION 語句是用來將兩個不同的查詢結果集相加得到一個結果集,UNION使用的唯一要求是兩個查詢的信息(你的查詢語句)必須有相同的列數和相同的數據類型

  我舉個例子,web程序中有如下語句:

  SQLstring= "SELECT FirstName,LastName,EmployeeID FROM Employees WHERE City ='"&strCity"'"

  合法的SELECT語句和我們注入的UNION SELECT語句在WHERE子句中都要有相同的列。就上面的語句來說,如果我要加入UNION 語句的話,前後兩者都要有3個列。並且他們列的數據類型也要相互匹配才可以。如果FirstName這個值是字符串類型的,那麼在你注入的語句中所對應的值也應該是字符串類型的。一些數據庫,如ORACLE,是對類型檢查非常嚴格的。其他的數據庫相對要好一些,允許你輸入任何數據類型並且它會自動的把你輸入錯誤的數據類型轉換成正確的。比如SQL數據庫中,你在varchar類型的地方輸入數值類型的數據(如int)是不會報錯的,因為在這裡數值類型會被自動轉為字符串類型。但是如果在smallint列處輸入text類型則被認為是非法的,因為text類型不能被轉換成int類型。把數值類型的數據轉換成字符串型是被允許的,而反之則不行,所以默認都是使用數值類型的數據。

  要想知道我們要注入的目標語句中有多少個列,你就要試探性的往UNION SELECT子句中添加相應的值,直到它不報“在UNION語句中的所有查詢都必須在目標列表中具有相同數目的表達式”這樣的錯為止。如圖所示,如果你遇到的是數據類型不匹配的錯誤,那麼你要去改變列的數據類型。如果返回消息只是一個轉換數據類型失敗的錯誤,那就說明你已經猜對了列的數目,只是其中有個別的列的數據類型不對。那麼接下來要做的就是判斷是哪個列的數據類型的不正確導致的錯誤。然後將他改過來就可以了。

  如果一切順利,那麼祝賀你,你會得到一個和上面格式類似的而且是合法的頁面;)無論動態頁面在哪裡出現,你都可以構造自己的語句應對自如。

  3.WHERE關鍵字

  報錯為“無效的列名'EmployeeID'”,這個問題可能是由我們注入的語句結尾的WHERE關鍵字引起的,舉例說明:

  SQLString="SELECT FirstName,LastName,Title FROM Employees WHERE City='"&strcity&"'AND Country ='USA'"

  如果我們注入的語句是UNION ALL SELECT OtherField FROM OtherTable WHERE 1=1 那麼會得到如下的提交語句:

  SELECT FirstName, LastName, Title FROM Employees WHERE City = 'NoSuchCity' UNION ALL SELECT OtherField FROM OtherTable WHERE 1=1 AND Country = 'USA'

  這樣就會報錯:[Microsoft][ODBC SQL Server Driver][SQL Server]無效的列名 'Country'。

  其實問題就是因為你注入的語句後,系統沒有在從數據庫的表中找到一個叫'Country'的列名。我們這裡可以簡單的用“;--”注釋符號將其注釋掉(如果我們是SQL Server)。或者干脆繼續猜其他的列名,然後構造合法請求就如我們上一節講到的一樣。

  3.1表名的枚舉

  我們已經開始掌握如何來使用注入進行攻擊,但是我們還要確定要從哪個表得到信息,換句話說就是我們要的到關鍵的表名才能獲得我們想要的有用信息。如何獲得表名呢?在SQL Server中,你可以很容易得從數據庫中得到全部的表名和列名。但是在Oracle和Access中,你就不一定能如此輕易的得到了,這要看WEB程序對數據庫的訪問權限了。關鍵在於是否能得到系統建立時自動生成的表中包含的表名和列名。如在SQL Server中,它們分別為'sysobjects'和'syscolumns',(在本文最後我們將給出其他數據庫系統自建表和相應的列名)我們用以下的句子可以在這些表中列出數據庫的所有列名和表名,(根據情況自行修改):

  SELECT name FROM sysobjects WHERE xtype = 'U'

  這句話會返回數據庫中用戶定義的所有表,如果我們看到我們感興趣的或者是想要看的表,那麼我們就把他打開,這裡以Orders為例構造語句:SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = 'Orders')得到結果如圖。

  3.2單一紀錄

  上面我們構造的語句返回了大量的信息,如果你只想顯示一條數據紀錄也是可以的。你完全可以構造你的注入語句來得到你想要的唯一的信息。我們只要在WHERE子句中添加關鍵字來避免某些行的關鍵字被選中就可以了。我來舉個列子:' UNION ALL SELECT name, FieldTwo, FieldThree FROM TableOne WHERE ''='

  我們這樣就可以得到FieldOne,FieldTwo和FieldThree的第一個值,假設我們的到的分別是"Alpha", "Beta"和"Delta"。注意,更有意思的來了,我們要得到第2行的值,怎麼構造下面的語句呢?這樣來:' UNION ALL SELECT FieldOne, FieldTwo, FieldThree FROM TableOne WHERE FieldOne NOT IN ('Alpha') AND FieldTwo NOT IN ('Beta') AND FieldThree NOT IN ('Delta') AND ''='

  這裡有一個子句“NOT IN VALUES”,它的作用是不再返回我們已經得到的信息,即不是alpha,不是beta,不是delta.既然都不是,數據庫就會傻乎乎的告訴我們第二行的值。我們再假設我們得到第二行的值為

copyright © 萬盛學電腦網 all rights reserved