這是SQL注射原理的講解。
通過暴庫,下載下傳資料庫,阿劍劍對資料庫也有了些感性的認識。可是,并不是所有時候我們都可以得到别人的資料庫并打開來看的。聽說有門技術叫SQL注射,不用下載下傳資料庫,也可以得到資料庫中的資訊。于是阿劍劍嚷嚷着要學它。
欠錢:“SQL注射是一門比較有難度的技術,因為要了解它和熟練它需要有ASP和資料庫的基礎。你認為自己有資格學習它嗎?”
阿劍劍想了一下:“這些基礎我是一點都沒有啊,可是不是聽說市面上有很多SQL注射的傻瓜工具嗎?你教會我使用這些工具不就可以了?”
欠錢:“既然如此,那好吧,我首先把SQL最基本的文法告訴你,這樣你才好了解那些SQL注射工具上的術語和使用步驟。”
阿劍劍:“欠錢你真是太好了,感動ing!不過,不會很難吧?”
“當然不難了!”欠錢拍着胸脯。
一個資料庫一般都包含有若幹張表,如同我們前面暴出的資料庫中admin表包含有管理者資訊,而user表則包含有所有的論壇使用者資訊一樣。以下面這張表為例:
Dv_User
UserID UserName UserPassword UserEmail UserPost
這是DVBBS 7.0的資料庫中所有使用者資料的表,Dv_User 是表名。每一行代表一個使用者,每一列是該使用者的某種屬性。我們最感興趣的自然是使用者名與密碼這樣的屬性了。
SQL是一種用于操作資料庫的規範化語言,不同的資料庫(MSSQL、MYSQL、ORACLE……)大體上都是一樣的。比如我們要查詢資料庫中的資訊:
select UserName,UserPassword from Dv_User where UserID=1;
這就是一個最典型的SQL查詢語句,它的意思是,在Dv_User這張表中,将UserID為1的使用者名與密碼查詢出來。
得到的結果是:admin 469e80d32c0559f8
SELECT語句文法:
SELECT [列名],[列名2]…… FROM [表名] WHERE [限制條件]
例:
SELECT * FROM Dv_User where UserID=1
表示查詢UserID為1的所有資訊。
更新:
UPDATE [表名] SET [列名]=新值 WHERE [限制條件]
UPDATE Dv_User set [UserPassword]=’ 965eb72c92a549dd’ WHERE UserName=’admin’
此語句将把Dv_User表中的UserName為admin的那一行中UserPassword的值改為965eb72c92a549dd。
删除:
DELETE FROM [表名] WHERE [限制條件]
DELETE FROM Dv_User WHERE UserName=’test’
将使用者名為test的那一行從Dv_User表中删除
二、SQL注射漏洞簡述
阿劍劍仔細把上面四個SQL語句讀了幾遍,發現非常的容易,于是虛心請教欠錢:“SQL文法看起來很容易上手嘛,那SQL漏洞是怎麼來的呢?”
欠錢打開一個頁面,指着裡面的代碼:
if id<>"" then
sql="SELECT * FROM [日記] WHERE id="&id
rs.Open sql,Conn,1
阿劍劍看了一眼:“哎呀,頭暈了!”
欠錢敲了他一下:“關于漏洞的成因我隻講這一次,如果怕難就不知道漏洞的由來了,而且實際上一點也不難的,看好了,我們這段代碼是提取自BBSXP論壇的,經過我改動以後,把它做成了一個有漏洞的頁面給你講述SQL漏洞的原理。”
那張日記的表内容如下:
日記
id username title content adddate
1 職業欠錢 今天安裝了BBSXP 這是5.16版,發現BBSXP體積雖小,可是功能一點也不少.完全夠用,不知道安全性怎麼樣 2005-10-25
2 職業欠錢 再寫一個日志吧 多寫幾個日志看看,玩玩,呵呵,反正這個論壇也隻有我一個人在.. 555555555好寂寞 2005-10-25
我們通路
<a href="http://localhost/bbsxp/blog.asp?id=" target="_blank">[url]http://localhost/bbsxp/blog.asp?id=1[/url]</a>
的時候結果
阿劍劍:“我明白了,通路blog.asp的時候,我們送出的參數id為1,那麼放到SQL語句裡就變成了:
SELECT * FROM [日記] WHERE id=1
是以就得到我們看到的那個頁面,對嗎?”
欠錢:“很好!正是如此!SQL漏洞的起源就從這裡開始了!注意到了嗎?id的值是由我們送出的,但是它卻沒有做任何的檢查,也就是我們送出的id可以是任意字元串。假設我們送出一個單引号的話,SQL語句就會因為id=1’ 而出錯”
“等等,為什麼加單引号會出錯呢?”
“因為單引号在SQL語句裡有特殊的含義,它隻能以’abc’這樣的方式出現,表示abc為一個字元串,如果隻出現一個單引号,整個句子肯定會出錯了。”
“哦,那單引号和SQL注射有什麼關系呢?”
“關系很密切,一般來說,常見的SQL語句有這麼幾種:
SELECT * FROM [表] WHERE id=12 這是數字型,12由我們送出
SELECT * FROM [表] WHERE name=’admin’ 這是字元型,admin由我們送出
SELECT * FROM [表] WHERE key like ‘%word%’ 這是搜尋型,word由我們送出
我們以第一種情況為例,假設我們送出 id=12 and 1=1,那麼完整的SQL語句為:
SELECT * FROM [表] WHERE id=12 and 1=1
它并不出錯,但是如果我們送出改為1=2,也就是
SELECT * FROM [表] WHERE id=12 and 1=2
<a></a>
阿劍劍想了一下:“這麼說,為了不讓SQL語句出錯,那麼我們在字元型SQL語句中,要送出的變量就應該是
admin’ and ‘1’=’1
然後補到完整的SQL語句中,就是
SELECT * FROM [表] WHERE name=’admin’ and ‘1’=’1’
而字元型則是
word%’ and ‘%’=’
補充到完整的SQL語句為:
SELECT * FROM [表] WHERE key like ‘%word%’ and ‘%’=’%’
”
欠錢:“完全正确!這正是我們判斷注射類型的方法!”
阿劍劍:“那我們怎麼才能夠得到資料庫中的資訊呢?”
欠錢:“最直接的方法自然是猜了,我們在送出的資料裡加入一些其他的判斷語句來代替and 1=1這樣的條件。以數字型SQL查詢語句為例,我們送出一個id的值如下:
id=1 and exists (select * from admin)
還原到完整的SQL語句中:
SELECT * FROM [表] WHERE id=1 and exists (select * from admin)
如果存在admin這張表的話,那麼這個SQL語句将按原樣傳回,否則将傳回空值。到blog.asp中去實驗一下就知道了。
阿劍劍:“提示不存在這張表,然後我就要再學習很多的SQL語句去猜測接下來的資料嗎?”
欠錢:“呵呵,确實更改這個SQL語句我們就可以慢慢猜出資料庫裡的内容。首先猜一個資料庫裡有哪些表,然後逐個猜解這些表中有哪些列(以後稱為字段),最後猜解個表中的具體内容。記住這個流程後,我們不打算深入下去了,因為我們已經有非常多的注射輔助工具了,這些工具會幫我們完成這些工作。”
“嗯,也好,至少我大緻上知道了SQL注射是怎麼樣一個漏洞,具體的東西要靠我以後自學ASP和資料庫才能提高吧,現在你就教我用那些工具吧,我已經迫不及待了!”
本文轉自loveme2351CTO部落格,原文連結:http://blog.51cto.com/loveme23/8527 ,如需轉載請自行聯系原作者