【新手入门】SQL注入之宽字节注入

一、编码

说到宽字节注入,我们首先要了解一下编码,那么都有哪些编码呢?

url编码、ascii码、gbk和utf8编码

01010101--1byte--1B--8bit

1024B--1KB         1024KB--1MB        1024MB--1GB

1.ascii码

ASCII码使用7位二进制数表示128个字符,包括英文字母、数字、标点符号、控制字符等。

a   英文字母  1B   一个字节    0x61,不支持中文

ascii码表

2.url编码

URL 是一个字符序列,由数字、字母和特殊字符组成。

对 URL 进行编码主要原因有如下几点:

①.保留字符

Ur1可以划分成若干个组件,协议、主机、路径等。有一些字符(: / ? # [] @)是用作分隔不同组件的。

例如:冒号用于分隔协议和主机,/用于分隔主机和路径,?用于分隔路径和査询参数,等等。还有一些字符(!S&'()"+,:=)用于在每个组件中起到分隔作用的,如=用于 表示查询参数中的键值对,&符号用于分隔查询多个键值对。

当组件中的普通数据包含这些特殊字符时,需要对其进行编码。
RFC3986中指定了以下字符为保留字符: ! * ' () ; : @ & = + $ , / ? # []

②.不安全字符

还有一些字符,当他们直接放在URL中的时候,可能会引起解析程序的歧义。这些字符被视为不安全字符.
1.空格:Url在传输的过程,或者用户在排版的过程,或者文本处理程序在处理Ur1的过程,都有可能引入无关紧要的空格,或者将那些有意义的空格给去掉。
2.引号以及<>:引号和尖括号通常用于在普通文本中起到分隔ur1的作用
3.#:通常用于表示书然或者锚点
4.%:百分号本身用作对不安全字符进行编码时使用的特殊字符,因此本身需要编码
5.{}|\^[]`~:某一些网关或者传输代理会篡改这些字符

③.ASCII 无法表示的字符

URL 只使用 ASCII 编码字符集中的可打印字符来编写,因此不可打印字符以及 ASCII 之外的字符如果出现在 URL 中,都需要进行编码;

只有字母和数字[0-9a-zA-Z]、具有特殊含义的保留字符以及非保留字符,才可以不经过编码直接用于 URL。

3.gbk编码

支持中文,一个中文是两个字节    0xdf0x5c

4.utf-8编码

万能码

可变长度的编码方式,一个中文是3个字节 0xdf0x5c0x7b

5.unicode 万国码

Unicode 是国际标准字符集,它将世界各种语言的每个字符定义一个唯一的编码,以满足跨语言、跨平台的文本信息转换。

Unicode 字符集的编码范围是 0x0000 - 0x10FFFF 

Unicode 只是字符集,UTF-8、UTF-16、UTF-32 才是真正的字符编码规则

二、注入防御之引号转义

好多网站,尤其是php的网站,为了防止sql注入,经常会采用一个手段就是引号转义,比如开启全局GPC配置

如在Pikachu靶场中,字符型注入输入xx' or 1=1#,可查询到用户名

而在宽字节注入中输入却查询不到

打开源代码

使用一些转义函数,比如:addslashes和mysql_real_ escape_string,他们转义的字符是单引号(')、双引号(”)、反斜线(/)与NUL(NULL 字符),转义的方式就是在这些符号前面自动加上'\',让这些符号的意义失效,或者可以理解为被注释掉了。

那么我们的sql注入语句就跟着失效了,好多时候,我们写注入语句难免会使用到引号等特殊符号,比如下面这个


http: /192.168.0.14/pikachu/vul/sali/sali_str.php?name=xxx%27+or+1%301+%238submit=%E6%9F%A5%E8%AE%A2?name=xxx%27+or+1%3D1+%23是name=xxx'or 1=1#进行了ur1编码之后的效果。
如果后台执行这样的语句为
$uname =$GET('name')
select *from member where username='$uname':
再注入这样的语句时,由于'被转义了,得到的sq1语句将是如下效果的select * from member where username='xxx\'or1=1#;,后面的引号被转义,导致不能和前面的引号闭合上,那么这个sql语句的语法就是错误的,所有不会达到注入的效果,这就是防御的手段。

如在pikachu文件夹里找到对应php文件。这是原代码:

pikachu靶场  wide byte注入打开如下

在原代码中加入“打印姓名”

刷新pikachu可得到

这种防护手段非常有效地把引号防护掉了。

6.配置文件

但php文件中只有加转义的部分可以拦截引号,其他部分不行,要想全部拦截,需配置文件。

找到PHP扩展及设置——magic_quotes_gpc——php.ini——CTRL+F/CTRL+V搜一下magic_quotes_gpc——将magic_quotes_gpc=off改为magic_quotes_gpc=on即可全局开启

若不支持可换为更低的版本试一下

三、宽字节注入----注入防御之绕过思路

引号被防护掉,这样就没有办法了吗,不是的,还可以尝试宽字节注入.(后台数据库使用gbk编码才可进行宽字节注入)。

7.概念原理

宽字节注入是一种SQL注入攻击方式。在数据库使用GBK等宽字节字符集时,一个汉字占两个字节。

在PHP中,当开启 magic_quotes_gpc (该函数会对特殊字符转义)后,输入的单引号 ' 前自动加上转义符' \' ,从而让单引号‘失效。
攻击者利用宽字节编码特性,通过输入特定字节序列,让转义符号 \ 与后面字节组成一个汉字,从而使单引号 ' 能发挥SQL注入作用,达到恶意攻击目的。

一个登录验证的SQL语句为select  from users where username='$username' and password='$password' 。

正常情况下,若用户的输入包含单引号会被转义。
但攻击者在用户名输入框输入 %df' or 1=1# (这里 %df 在GBK编码下与转义字符 \ 组成一个汉字),SQL语句就会变成 select * from users where username='汉字' or 1=1# and password='$password' ,这样就绕过了原本基于用户名的验证,使攻击者可能成功登录系统。

8.防御

这里我们提一下,上面的语句其实应该是这样的
$uname = $_GET('name')-- $uname,其实等于 xx%27+or+1%3D1+%23,将其进行url16进制解码xx0x27+or+10x3D1+0x23,(%是ur1编码时十六进制数据的前缀0x的简写)。

后台转义单引号的时候,其实在前面加上\的时候,加的是\的十六进制编码0x5C,也就是说xxx0x27这个数据,其实到后台加上转义之后,是xxx0x5C0x27

那么我们可以想到,由于汉字在GBK编码的时候是两个十六进制的字节,UTF8是三个字节,而这个\是一个字节0x5c,如果我们能够再提供一个或者两个十六进制的字节数据和这个0x5c可以合并为一个汉字的编码的话,那么这个\不就被我们吃掉了吗?那么单引号就又可以生效了.

9.实战演练

pikachu靶场,宽字节注入,抓包

url编码:‘→%27→0x27         \→%5c→0x5c 

以上内容均为自己学习理解所得,如有错误,欢迎大家评论指正!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值