web漏洞之SQL注入

目录

一、概述

1.1什么是SQL注入

1.2原理

二、分类

2.1按照数据提交方式分类

2.2按照注入点类型来分类

2.3按照执行效果来分类

三、注入流程

四、验证方法

3.1数字型注入验证

3.2字符型注入验证

五、攻击方法

5.1猜解SQL查询语句中的字段数

5.2找回显点

5.3获取数据库名称

5.4查询表名

5.5查询字段

5.6查信息

六、防御方法

七、绕过姿势(常见)

八、危害


一、概述

1.1什么是SQL注入

web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息

1.2原理

攻击者通过用户可控参数中修改或拼接SQL语句,从而破坏原有SQL结构,让SQL数据库执行恶意的语句

二、分类

2.1按照数据提交方式分类

1.get注入

2.post注入

3.Cookie注入

4.HTTP头部注入

2.2按照注入点类型来分类

1.数字型注入点

2.字符型注入点

3.搜索型注入点

2.3按照执行效果来分类

       1.基于布尔的盲注

       2.基于时间的盲注

       3.基于报错的注入

       4.联合查询注入

       5.堆叠注入

6.宽字节注入

三、注入流程

       1.判断是否存在注入点,注入是字符型还是数字型

       2.猜解SQL查询语句中的字段数(通常使用order by)

       3.确定显示位置

       4.获取当前数据库的名字

       5.获取数据库中的表名

       6.获取表中的字段名

7.获取所需的数据

四、验证方法

这里我们以URL中的注入为例,其他数据交互点相同,添加相同的参数

3.1数字型注入验证

       ①and验证:在URL后加and 1=1 :www.text.com/text.php?id=1 and 1=1,语句执行正常,与原始页面如任何差异

②在URL后面添加and 1=2:www.text.com/text.php?id=1 and 1=2,语句可以正常执行,但是没有查询出结果,返回数据与原始网页存在差异

满足以上两点就可以认为存在数字型SQL注入,如果是登录框或者其他,在输入参数后进行添加如上两个步骤即可。

注:也可以采用别的方法验证比如在原始数据后面加一减一、加零减零,不过如果在url进行,就要对加号(+)进行编码,因为url中默认加号表示空格,方法还有很多,只要能让我们输入的语句能够执行就可以

3.2字符型注入验证

①在URL地址中输入 www.test.com/test.php?id= x' and '1'='1,如果页面运行正常,继续进行下一步

②在URL地址中输入 www.xxx.com/abc.php?id= x' and '1'='2页面运行错误,则说明此 Sql 注入为字符型注入

注:这里补充一点,对于登录框来说,我们可以采用登录名后加sql注释的方式来绕过密码,或者在账号后面添加恒成立的条件来进行登录,这既是万能密码

五、攻击方法

这里攻击我们主要以联合查询注入来举例,对于其他注入后续会有相关文章进行详细讨论。

者进行攻击前我们肯定确定有注入点,接下来我们要想想我们通过注入最后想得到什么?

数据,数据肯定是我们第一目标,但如果可能进行数据库提权,那么提权就更加重要,我们暂且先以获取数据为目标,这里我们以sqlilabs目标

5.1猜解SQL查询语句中的字段数

首先我们猜测为3,因为我们知道这里查询的字段数为2,但是为了演示我们猜测3看会出现什么

当我们输入上面的语句提交后可以看到拔错了,并没有3个字段数

接下来我们输入正确的2,可以看到有返回信息,证明这个地方去数据库查询了两个字段信息

5.2找回显点

通过上面我们知道web程序去查询了两条数据,接下来我们要知道这两条数据显示在哪,为我们后面爆破数据找到一个输出点,我们在注入点输入下面的查询语句(1,2是因为前面我们得出有两个数据),可以看到1,2的位置

5.3获取数据库名称

这一步有些人也可能先去查数据库版本信息,这里我们不啰嗦,直接奔着查信息去,其他信息爆破都同理,我们选择替换之前数字2的位置来爆破信息,可以看到之前显示2的位置变成了我们数据库的名字(sql语句这里不多介绍)

5.4查询表名

我们已经获取到了数据库的名字,接下来就是爆破数据库名,这里我们通过查询information_schema这个里面所有的表名字(Information_schema:包含数据库里所有的其他数据库的信息及其表信息,字段数据信息。注意5.0以上版本存在此数据库,5.0一下没有)

5.5查询字段

到上一步我们已经获得了数据库的表名信息,接下来,我么查询users表中的字段信息

5.6查信息

通过上一步我们已经得到了字段信息,接下来就是针对可能存在账号密码的字段查询相应信息,可以看到下图,我们已经查询出来相应的账号密码,密码是加密的,我们可以通过解密等来进行破解,至此SQL注入获取信息到此为

六、防御方法

6.1在设计应用程序时,完全使用参数化查询(Parameterized Query)来设计数据访问功能,例如PDO预编译

6.2加强对用户输入的检查,过滤特殊字符,比如and、union、select等等

6.3权限做到严格区分,对于每个用户的权限只给到满足需求前提下的最小权限

6.4对用户输入进行长度的校验,SQL注入语句一般较长,条件允许的情况下可以对长度限制

6.5错误消息提示尽量不要暴露服务器一些敏感信息比如数据库、中间件和系统版本等

6.6配置WAF等防御性工具

七、绕过姿势(常见)

7.1.and被过滤,可用替换:+,-,*,%,/,<<,>>,||,|,&,&&

7.2.or被过滤,可使用异或进行判断:^,xor

7.3.如果空格被过滤可以用:

7.3.1/*!50540select user()*/     mysql(独有)内联注释,!后面的数字是版本号,表示当数据库版本>=5.5.40时执行SQL语句

7.3.2用注释代替空格,比如:?id=1 union select /**/schema_name/**/from/**/information_schema.schemata;

7.3.3用一些空白字符代替%09,%0a,%0b,%0c,%0d,%20,%a0

7.3.4用一些特殊字符代替:+、-、!、@、~、{}、"、'、()、``

7.4引号被过滤,一般在where子句后常常用到引号,当引号被过滤,我们可以用十六进制来转换,比如where table_name="users"修改后变成where table_name=0x7573657273

7.5绕过union,select,where等关键字

7.5.1通过注释绕过,常用注释://,-- , /**/, #, --+, -- -, ;,%00,--a,比如:UNI/**/ON /**/ SEL/**/ ECT /**/user,pwd/**/ from user

7.5.2大小写绕过,比如:?id=1 UnioN sEleCT *

7.5.3复写关键字绕过,比如:?id=1'UNIunionONSeLselectECT1,2,3–-

7.6 等号(=)过滤绕过,使用like 、rlike 、regexp 或者 使用< 或者 >

八、危害

8.1数据表中的数据外泄,例如企业及个人机密数据,账户数据,密码等。

8.2数据结构被黑客探知,得以做进一步攻击(例如SELECT * FROM sys.tables)。

8.3数据库服务器被攻击,系统管理员账户被窜改(例如ALTER LOGIN sa WITH PASSWORD='xxxxxx')。

8.4获取系统较高权限后,有可能得以在网页加入恶意链接、恶意代码以及Phishing等。

8.5经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统(例如xp_cmdshell "net stop iisadmin"可停止服务器的IIS服务)。

8.6黑客经由上传php简单的指令至对方之主机内,PHP之强大系统命令,可以让黑客进行全面控制系统(例如:php一句话木马)。

8.7破坏硬盘数据,瘫痪全系统(例如xp_cmdshell "FORMAT C:")。

8.8获取系统最高权限后,可针对企业内部的任一管理系统做大规模破坏,甚至让其企业倒闭。

8.9企业网站主页被窜改