SQL约束攻击
主要知識點
數(shù)據(jù)庫字符串比較:在數(shù)據(jù)庫對字符串進行比較時,如果兩個字符串的長度不一樣,則會將較短的字符串末尾填充空格,令兩個字符串的長度一致,比如,字符串A:[String]和字符串B:[String2]進行比較時,由于String2比String多了一個字符串,這時MySQL會將字符串A填充為[String ],即在原來字符串后面加了一個空格,令兩個字符串長度一致??慈缦聝蓷l查詢語句:
select * from users where username=‘Dumb’
select * from users where username='Dumb ’
它們的查詢結(jié)果是一致的,即第二條查詢語句里Dumb后面的空格并沒有對查詢有任何影響。因為在MySQL把查詢語句里的username和數(shù)據(jù)庫里的username值進行比較時,它們就是一個字符串的比較操作,符合上述特征。
INSERT截斷:這是數(shù)據(jù)庫的另一個特性,當(dāng)設(shè)計一個字段時,我們都需對其設(shè)定一個最大長度,比如CHAR(10),VARCHAR(20)等等。但是當(dāng)實際插入數(shù)據(jù)的長度超過限制時,數(shù)據(jù)庫就會將其進行截斷,只保留限定的長度。
SQL約束攻擊
后臺在接收到用戶名與密碼后使用了php的函數(shù)mysql_real_escape_string()處理,并使用單引號包裹。驗證用戶名與密碼的代碼如下:
按理說上述代碼不會產(chǎn)生SQL注入等漏洞的啊,下面介紹幾類關(guān)鍵知識:
在SQL里執(zhí)行字符串處理時,字符串末尾的空格符將會被刪除。例如如下代碼:
上述代碼和username = 'test’結(jié)果是一樣的。但也存在異常情況,最好的例子就是LIKE子句了。注意,對尾部空白符的這類修剪操作,主要是在“字符串比較”期間進行的。這是因為,SQL會在內(nèi)部使用空格來填充字符串,以便在比較之前令其它們的長度保持一致。
在所有的INSERT查詢里,SQL都會根據(jù)varchar(n)來限制字符串的最大長度。也就是說,如果字符串的長度大于“n”個字符,那么僅插入字符串的前“n”個字符。比如特定列的長度約束為“5”個字符,那么在插入字符串“testName”時,實際上只能插入字符串的前5個字符,即“testN”。
當(dāng)注冊時,后臺一般先select一下用戶名看看是否存在,然后在insert一下。示例代碼如下:
這里注冊時使用用戶名+【大量空格】和隨機密碼注冊即可完成攻擊。
主要原理就是insert時候有varchar(n)的限制,大于n的時候會截取前n個存入。在數(shù)據(jù)庫對字符串進行比較時,即select操作,如果兩個字符串的長度不一樣,則會將較短的字符串末尾填充空格,令兩個字符串的長度一致。注冊時select語句不會將"admin+[大量空格]11"刪減到n位,所以不會被select查出與admin重復(fù),不會返回數(shù)據(jù),接下來就可以插入admin+[空格](截取)11和自定義密碼了。
如果使用用戶名“vampire”和密碼“random_pass”登錄的話,對比時是admin與admin+[大量空格],會將前面的admin添加空格與后面的長度相同在進行對比,那么返回的只能是我們自己注冊的用戶信息,而不會返回目標(biāo)用戶信息。SQL查詢語句是一個and操作,如果密碼不一樣怎么會把目標(biāo)用戶的信息也返回回來?
當(dāng)?shù)顷憰r使用admin與自定義密碼登陸,數(shù)據(jù)庫將返回我們自己注冊的賬戶信息,但是注意此處的return $username,雖然此時查詢出來的是我們自己的用戶信息,但是返回的用戶名則是目標(biāo)的用戶名。如果此后的業(yè)務(wù)邏輯直接以該用戶名為準(zhǔn),則我們就達到了水平越權(quán)的目的。
總結(jié)
- 上一篇: BugkuCTF-Reverse题游戏过
- 下一篇: mysql 流程控制语句,mysql