云游屋
扫描关注云游屋

云游屋

Web-SQL注入

云游屋2021-09-07大数据 1042

漏洞介绍:

SQL注入漏洞(SQL injection)是Web层面最高危的漏洞之一。在2008年至2010年期间,SQL注入漏洞连续3年在OWASP年度十大漏洞排行中排名第一

漏洞原理:

SQL注入是因为后台SQL语句拼接了用户的输入,而且Web应用程序对用户输入数据的合法性没有判断和过滤,前端传入后端的参数是攻击者可控的,攻击者可以通过构造不同的SQL语句来实现对数据库的任意操作。比如查询、删除,增加,修改数据等等,如果数据库的用户权限足够大,还可以对操作系统执行操作

漏洞危害:

可以造成信息泄露,上传Webshell、获取或者修改信息

MySQL

MySQL是一种开放源代码的关系型数据库管理系统,使用最常见的数据库管理语言--结构化查询语言(SQL)进行数据库管理

端口号:3306

MySQL支持三种注释风格:

#:注释从 “#” 字符到行尾

--:注释从“--”序列到行尾。需要注意的是,使用此注释时,后面需要跟上一个或者多个空格

/*/:注释从/序列到后面的*/序列中间的字符

MySQL 5.0及其以上版本提供了information_schema,information_schema是信息数据库

information_schema数据库中三个很重要的表:

information_schema.schemata: 该数据表存储了mysql数据库中的所有数据库的库名

information_schema.tables: 该数据表存储了mysql数据库中的所有数据表的表名

information_schema.columns: 该数据表存储了mysql数据库中的所有列的列名

关于这几个表的语法:

通过这条语句可以得到所有的数据库名

select schema_name from information_schema.schemata limit 0,1

通过这条语句可以得到所有的数据表名

select table_name from information_schema.tables limit 0,1

通过这条语句可以得到指定security数据库中的所有表名

select table_name from information_schema.tables where table_schema='security'limit 0,1

通过这条语句可以得到所有的列名

select column_name from information_schema.columns limit 0,1

通过这条语句可以得到指定数据库security中的数据表users的所有列名

select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1

MySQL中比较常用的函数:

version(): 查询数据库的版本

user():查询数据库的使用者

database():数据库

system_user():系统用户名

session_user():连接数据库的用户名

current_user:当前用户名

load_file():读取本地文件

into outfile:写文件操作

@@datadir:读取数据库路径

@@basedir:mysql安装路径

@@version_complie_os:查看操作系统

SQL注入的分类:

数字型和字符型

数字型

数字型注入是最简单的一种,假设URL为http://www.xxxx.com/test.php?id=8

我们可以猜测一下SQL语句为:select * from table where id=8

判断是不是数字型,这时候我们可以在URL后面加一个引号,比如http://www.xxxx.com/test.php?id=8‘

此时的SQL语句为:select * from table where id=8‘

如果我们SQL语句猜测是正确的话,这样会使原来的页面报错。

然后我们在原来的URL后面加and 1=1 、and 1=2测试页面

http://www.xxxx.com/test.php?id=8 and 1=1页面返回正常(SQL语句为:select * from table where id=8 and 1=1 永远为真)

http://www.xxxx.com/test.php?id=8 and 1=2页面返回不正常(SQL语句为:select * from table where id=8 and 1=2 永远为假)

如果满足上述的条件可能就存在SQL注入

字符型

当我们输入的参数是字符串时,我们称为字符型

数字型和字符型存在最大的区别是:数字型不需要单引号来闭合,而字符型一般都是要用单引号来闭合

字符型的SQL语句为:select * from table where username=’admin‘

字符型注入的关键是闭合单引号和注释多于代码

然后我们也要在原来的URL后面加and 1=1 、and 1=2测试页面,但此时要注意单引号和它们的位置关系

正常的SQL语句应该是:

select * from table where username='admin' and 1=1 # (单引号闭合前面的单引号,#注释后面多于的代码 )

select * from table where username='admin' and 1=2 #

如果满足上述的条件可能就存在SQL注入

报错注入

主要利用数据库的报错信息来判断是否存在注入,当我们输入不符合数据库规范的字符时,数据库就会产生报错

常用的字符:’ / ; ) #(

盲注

盲注主要分为:基于时间的注入、布尔类型、无报错信息的注入

基于时间的注入

我们没有办法从其他方面判断我们的SQL语句是否执行,只能通过页面的回显时间来判断

常用的语句是:

if(length(database())>1,sleep(5),1)

如果数据库名称的长度大于1,那么让页面延迟5秒响应,以此来判断我们的语句是否正确

之前遇到过基于时间的注入但是把逗号过滤的情况,这里再给大家介绍一种语句就是:select case when

SQL CASE表达式是一种通用表达式,类似于if/else

select case when username = 'admin' then (sleep(3)) else 'xxxx' end from user;

布尔类型的注入

如果我们成功注入会显示正确信息,如果失败则不会显示正常信息

无报错信息的注入

没有任何报错显示,但是能根据页面是否正确显示来进行判断

常用到的函数:

1.length()函数

判读数据库的长度

lengh(database())=9

2.substr()函数

截取字符串

截取数据库名称的第一个字母是不是p

select substr(database(),1,1)='p'

substr()和substring()功能是一样的,都是截取字符串

3.left()函数

从字符表达式最左边一个字符开始返回指定数目的字符

获取数据库名字最左边的字符是不是p

select left(database(),1)='p'

4.MID()函数

用于从文本字段中提取字符

提取第一个字符判断是不是'p'

select mid(database(),1)='p'

5.ord()函数

把字符转成ASCII

判断第一个字符的ascii是不是97,也就是第一个字符是不是a

select ord(mid(database(),1))=97

很多时候我们需要利用这些函数结合脚本去跑,根据实际情况写脚本

堆叠注入

SQL语句默认是以分号结束,我们可以在参数后面加上分号,然后加上我们的语句

id=1';select mid(database(),1)='p' %23

二次注入

在存入数据库的时候做了过滤检测,但在取出来的时候没有检测,就可能造成二次注入

比如:我们在注册账号时可以注册一个admin -- ‘

然后我们修改这个账号的密码,当这个用户名从数据库里面获取的时候,可能就只获取到了admin,因为我们后面注释了,所以这样就能改admin用户的密码

宽字节注入

宽字节注入是因为客户端的字符集和接收端的字符集设置不一样,造成单引号逃逸,大部分是因为数据库的字符集设置为GBK编码,一般出现在PHP+MySQL中

在单引号前面加%df,GBK编码默认两个字节是一个汉字

Cookie注入

有些时候在Cookie中也会存在注入

XFF注入

在头部信息的X-Forwarded-for字段也可能存在注入

XFF主要作用是伪造客户端IP

注入工具

SQLMap

SQLMap是一个开放源码的渗透测试工具,它可以自动检测和利用SQL注入漏洞,并且它在SecTools.org注入工具分类里位列第一名

SQLMap配置了一个功能强大的检测引擎,如果URL存在注入漏洞,它就可以从数据库中提取数据,如果权限较大,甚至可以在操作系统上执行命令、读写文件

我们实际操作一下,用SQLMap对靶场存在SQL注入的题目进行操作一下

首先判断一下是否存在注入点

-u 参数指定URL

用SQLMap跑一会就提示,id参数是可注入的,问是否还检测其它,我们这里默认否就行

使用--current-db参数列出当前应用程序所使用的数据库,可以看到当前数据库是'maoshe’

再使用--table参数获取数据库表,-D参数指定数据库,可以看到有4个表,我们肯定首先是跑admin表


使用--columns参数列字段名 -T参数指定表明,有三个字段id、username、password

使用--dump参数列数据 -C参数指定字段名称,爆出了用户名和密码

其实这类注入的工具有很多,比如:Pangolin、明小子、Havij、啊D,根据自己的喜好选择

修补建议:

1.严格数据类型

2.特殊字符转义

3.使用预编译语句

4.框架技术

总结

如今SQL注入工具已经比较完善了,如果工具注入无法完成,再进行手工注入,总之,SQL注入时,一般是工具为主,手工为辅,虽然SQL注入危害很大,但是只要程序开发团队的程序员有一定的安全意识的话,完全是可以杜绝的


发表评论