SQL概述及在網路安全中的應用

來源:互聯網
上載者:User
關鍵字 網路安全
1.網路應用和SQL注射 1.1概述 有些網路資料庫沒有過濾客戶提供的資料中可能有害的字元,SQL注射就是利用插入有害字元進行攻擊的技術。 儘管非常容易防範,但網際網路上仍然有驚人數量的存儲系統容易受到這種攻擊。 這篇文章的目的是指導專業安全性群組織瞭解這種技術,並告訴他們正確的,用來防範SQL注射的辦法,以及處理各種常見的,由於非法輸入引起的問題. 1.2背景 在讀這篇文章之前,你應該對資料庫如何工作,以及SQL如何被用來訪問資料庫有一些基礎的瞭解。 我建議您閱讀eXtropia.com的文章「Introduction to Databases for WebDevelopers」。 (網址:HTTP://www.extropia.com/tutorials/sql/toc.html) 1.3字元編碼 在大多數的網路瀏覽器中,標點符號和許多其它符號在用於一個網路請求前需要把URL編碼, 以便被適當地編譯(interpret)。 在本文中的例子和截圖中我使用了固定的ASCII字元以保證最大的可讀性。 然而,在實際應用中,你需要在HTTP請求中用%25來代替百分號(%),用%2B來代替加號(+)等等。 3.2.5 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 '%" &a mp; strLastNameSearch & "%'" 這裡面的%是萬用字元,在這個例子裡,WHERE子句會返回TRUE,只要LASTNAME裡有字串含有strLastNameSearch.為了阻止SQL SERVER返回預計中的記錄,你構造的SQL語句裡必須含有LASTNAME裡沒有的字串.web搜索程式搜索的字串來自于使用者的輸入.通常有一個'和一個%在輸入的字串之前,因此我們構造字串時, 需要在WHERE子句中匹配它們.如果你提交了Null作為搜索字串,那麼LIKE的參數會變成"%%",這是一個全匹配,會返回所有的記錄. 3.2.6 「死胡同」 大部分的時候sql injection都要伴隨著大量失敗的實踐,如果你發現你無論如何都不能插入相關的語句,並且無論你怎麼做都不對,這個時候你就要判斷自己是否掉進了一個死胡同, 很多時候遇到這種情況你很可能是在一個多重嵌套的WHERE和SELECT子句的語句中,或者一些更加複雜的多重嵌套,連使用「;--」都沒有用,所以自己要小心和避免在這種地方停留。 3.2.7 列的數目不匹配問題 我們可以從幾次錯誤中得到很多有用的資訊,並且加以調整自己的請求語句,這種資訊多了,那就意味著我們離成功不遠了。 在猜列名時,如圖所示,我們提交語句後會碰到以下錯誤「在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.2.8.WHERE關鍵字 報錯為「不正確列名'EmployeeID'」,這個問題可能是由我們注入的語句結尾的WHERE關鍵字引起的,舉例說明: SQLString="SELECT FirstName,LastName, Title FROM Employees WHERE City='"&strcity&"'AND Country ='USA'" 如果我們注入的語句是UNION ALL SELECT OtherField FROM OtherT able WHERE 1=1 那麼會得到如下的提交語句: SELECT FirstName, LastName, Title FROM Employees WHERE City = 'NoSuchCity' UNION ALL SELECT O therField FROM OtherTable WHERE 1=1 AND Country = 'USA' 這樣就會報錯:[Microsoft][ODBC SQL Server Driver][SQL Server]不正確列名 'Count ry'。 其實問題就是因為你注入的語句後,系統沒有在從資料庫的表中找到一個叫'Country'的列名。 我們這裡可以簡單的用「;--」注釋符號將其注釋掉(如果我們是SQL Server)。 或者乾脆繼續猜其他的列名,然後構造合法請求就如我們上一節講到的一樣。 表名的枚舉 我們已經開始掌握如何來使用注入進行攻擊,但是我們還要確定要從哪個表得到資訊,換句話說就是我們要的到關鍵的表名才能獲得我們想要的有用資訊。 如何獲得表名呢? 在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.10.單一紀錄 上面我們構造的語句返回了大量的資訊,如果你只想顯示一條資料紀錄也是可以的。 你完全可以構造你的注入語句來得到你想要的唯一的資訊。 我們只要在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.既然都不是,資料庫就會傻乎乎的告訴我們第二行的值。 我們再假設我們得到第二行的值為"AlphaAlpha", "BetaBeta"和"DeltaDelta"。 我們來獲得第三行的值,構造語句如下:' UNION ALL SELECT FieldOne, FieldTwo, FieldThree FROM TableOne WHERE FieldOne NOT IN ('Alpha', 'AlphaAl pha') AND FieldTwo NOT IN ('Beta', 'BetaBeta') AND FieldThree NOT IN ('Delta', 'DeltaDelta') AND ''=' 這樣就避免了得到第一次和第二次我們已經得 到的值,我們就這樣試下去會得到資料庫中所有的值。 這看起來好像確實比較麻煩,但在這裡卻是最有效的,不是麼?   3.3 插入 3.3.1 插入基礎 關鍵字INSERT 被用於向資料庫添加資訊,通常使用INSERT主要在包括使用者註冊,論壇,添加商品到購物車,等等。 檢查INSERT使用的弱點和檢查WHERE一樣。 你可能不想使用INSERT,如何避免被利用弱點是一個重要的考慮問題。 INSERT注入嘗試常常會讓資料庫以行形式返回結果導致氾濫的單獨的引用和SQL關健字的意義可能改變.取決於管理員的注意和資訊對資料庫的操作,這個是要引起注意的,剛剛說過的那些,INSERT注入和SELECT注入的不同。 我們在一個允許使用者進行各種註冊,這就提供了一個你輸入你的名字,位址,電話等等的表單。 在你提交了這個表單之後,為了得到進一步的INSERT的弱點,你必須能夠看到你提交的資訊。 它在那裡不要緊。 可能當你登陸根據在資料庫裡存儲的名字的給予你權利的時候,可能在發送你的spam郵件的。。 ,誰知道,尋找一個途徑至少可以看到你輸入的資訊。 3.3.2 一個插入的請求看起來象這樣:INSERT INTO TableName VALUES ('Vaule One','Value Two','Value Three') 你想可能利用一個在參數VALUES中的子句來看到其他的資料。 我們可以使用這種辦法,sql的代碼象這樣:SQLString ="INSERT INTO TableName VALUES ('" & strValueOne & "', '" & strValueTwo & " ', '" & strValueThree & "')"我們象這樣填寫表單:Name: ' + (SELECT TOP 1 FieldName FROM TableName) + ' Email: blah@blah.com Phone: 333-333-3333 使SQL的聲明象這樣 : INSERT I NTO TableName VALUES ('' + (SELECT TOP 1 FieldName FROM TableName) + '', 'blah@blah.com', '333-333-3333')當你到了個人設定頁面查看你的使用信 息,你將看到的第一個欄位這個通常是使用者名r如果你使不在你的subselect中使用TOP 1,你將得到一個錯誤資訊說你的subselect返回了太多記錄,你能查看表中所有的行,使用NOT IN() 同樣的方法你可以得到單獨的記錄。 3.4. SQL伺服器預存程序利用 3.4.1 預存程序基礎 4. 一個完整安裝的MSSQL伺服器有上千的預存程序。 如果你能在一個後臺使用mssql的網頁應用程式得到SQL注入,你能使用這些預存程序完成一些非凡的成果。 我將討論很少的特殊的過程。 取決於網頁程式使用資料庫的使用者,只有一些可以工作,並不是所有的使用者都可以利用。 第一件事你應該知道預存程序注入不能通過預存程序的傳回值來確定你的注入是否成功.取決於你想完成什麼,你可能不需要得到資料。 你可以找到返回給你的資料的其他意義。 預存程序注入比一般的查詢注入要容易些,預存程序的注入的弱點利用看起來象這樣。 simplequoted.asp?city=seattle'; EXEC master.dbo.xp_cmdshell 'cmd.exe dir c:' 注意, Notice how a valid argument is supplied at the beginning and followed by a quote and the final argument to the stored procedure has no closing quote. This will satisfy the syntax requirements inherent in most quoted vulnerabilities. You may also have to deal with parentheses, additional WHERE statements, etc.但是在這以後將不需要擔心列和資料的類型的匹配。 這個可能弱點的輸出象程式無法返回錯誤資訊一樣。 我最喜歡預存程序。 5. 3.4.2. xp_cmdshell xp_cmdshell {'command_string'} [, no_output] master.dbo.xp_cmdshell是預存程序的聖杯,它帶來了一個問題, 能夠調用命令列的資料庫使用者的和他的運行許可權,這個並不可用除非這個網頁程式使用的資料庫使用者是SA. 執行層級為6 sp_makewebtask [@outputfile =] 'outputfile', [@query =] 'query' 6. 另外一個好的調用物件是master.dbo.sp_makewebtask,象你所看的,它是一個本地的輸出檔案和一個SQL statement。 sp_makewebtask可以查詢並建立一個包含輸出的網頁。 注意你可以象使用一個UNC路徑名一樣使用一個本地輸出。 這個意思就是這個輸出檔案可以放有在任何一台連在Internet並且有個可寫的SMB共用(SMB請求不需要任何的身份驗證)。 如果有一個防火牆限制了伺服器對Internet,試著把輸出檔案放在網頁目錄下(你要知道或者猜測網頁的目錄)。 同樣值得注意的是引用查詢可能是 包括執行其他的預存程序。 Making "EXEC xp_cmdshell 'dir c:'" 這個查詢將在網頁中給出"dir c:"的輸出。 當你進行嵌套引用的時候,記得單獨的引用和雙引號.4.1資料處理 所有的用戶端資料可以被惡意的提交的字元或字串清除。 這些可能在所有的應用程式做到,不僅僅是使用SQL查詢的。 Stripping quotes or putting backslashes in front of them is nowhere near enough.最好的過濾資料的方式是不用規則的表達方式,使它只包括你所想要的字元類型。 舉個例子,下邊的regxp將只能返回字母和數位,盡可能的過濾象s/[^0-9a-zA-Z]//g 這樣的特殊字元。 可能的時候儘量使用數位,在這以後只使用數位和字母。 如果你需要包括各種各樣的標誌或標點。 確信完全的把它們轉換成html標記,像「"e;" or ">」。 例如,一個使用者提交了一個email位址只允許使用數位和字母還有"@", "_", "." 和"-"。 僅僅只有這些字元可以轉換成html標記。 4.2. 編寫安全的web程式 這裡同樣有很少的特殊的sql注入規則。 First, prepend and append a quote to all user input。 儘管資料使數位。 其次,限制網頁應用程式的資料庫使用者在資料庫裡的許可權。 不要給這個使用者訪問所有的預存程序的權利如果這個使用者只需要訪問一些預定義的。 這部分包括了所有在sql注入中有用的系統表,你可以在google上搜索到每一個的表的列的定義 5.1. MS SQL Server Sysobjects syscolumns 5.2. MS Access Server MSysACEs MSysObjects MSysQueries MSysRelationships 5.3. Oracle SYS. USER_OBJECTS SYS. TAB SYS. USER_TABLES SYS. USER_VIEWS SYS. ALL_TABLE S SYS. USER_TAB_COLUMNS SYS. USER_CONSTRAINTS SYS. USER_TRIGGERS SYS. USER_CATALOG 責任編輯 趙毅 zhaoyi#51cto.com TEL:(010)68476636-8001 給力(0票)動心(0票)廢話(0票)專業(0票)標題党(0票)路過(0票) 原文:SQL概述及在網路安全中的應用 返回網路安全首頁
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.