一、编码
说到宽字节注入,我们首先要了解一下编码,那么都有哪些编码呢?
url编码、ascii码、gbk和utf8编码
01010101--1bytes--1B
1024B--1KB 1024KB-1MB 1024M--1GB
1.ascii码
ASCII码使用7位二进制数表示128个字符,包括英文字母、数字、标点符号、控制字符等。
a 英文字母 1B 一个字节 0x61,不支持中文
ascii码表
2.url编码
URL 是一个字符序列,由数字、字母和特殊字符组成。
对 URL 进行编码主要原因有如下几点:
①.保留字符
Ur1可以划分成若干个组件,协议、主机、路径等。有一些字符(: / ? # [] @)是用作分隔不同组件的。
例如:冒号用于分隔协议和主机,/用于分隔主机和路径,?用于分隔路径和査询参数,等等。还有一些字符(!S&'()"+,:=)用于在每个组件中起到分隔作用的,如=用于 表示查询参数中的键值对,&符号用于分隔查询多个键值对。
当组件中的普通数据包含这些特殊字符时,需要对其进行编码。
RFC3986中指定了以下字符为保留字符: ! * ' () ; : @ & = + $ , / ? # []
②.不安全字符
还有一些字符,当他们直接放在Ur1中的时候,可能会引起解析程序的歧义。这些字符被视为不安全字符.
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 才是真正的字符编码规则
二、注入防御之引号转义和绕过思路
1.转义
好多网站,尤其是php的网站,为了防止sql注入,经常会采用一个手段就是引号转义,比如开启全局GPC配置
如在Pikachu靶场中,字符型注入输入xx' or 1=1#,可查询到用户名
而在宽字节注入中输入却查询不到
打开源代码
使用一些转义函数,比如:add$lashes和mysg_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#;,后面的引号被转义,导致不能和前面的引号闭合上,那么这个sq1语句的语法就是错误的,所有不会达到注入的效果,这就是防御的手段。
如在pikachu文件夹里找到对应php文件。这是原代码:
pikachu靶场 wide byte注入打开如下
在原代码中加入“打印姓名”
刷新pikachu可得到
这种防护手段非常有效地把引号防护掉了。
但php文件中只有加转义的部分可以拦截引号,其他部分不行,要想全部拦截,需配置文件。
找到PHP扩展及设置——magic_quotes_gpc——php.ini——CTRL+F/CTRL+V搜一下magic_quotes_gpc——将magic_quotes_gpc=off改为magic_quotes_gpc=on即可全局开启
若不支持可换为更低的版本试一下
2.绕过——宽字节注入
引号被防护掉,这样就没有办法了吗,不是的,还可以尝试宽字节注入.
这里我们提一下,上面的语句其实应该是这样的
$uname = $_GET('name')-- $uname,其实等于 xx%27+or+1%3D1+%23,将其进行url16进制解码xx0x27+or+10x3D1+0x23,(%是ur1编码时十六进制数据的前缀0x的简写)。
后台转义单引号的时候,其实在前面加上\的时候,加的是\的十六进制编码0x5C,也就是说xxx0x27这个数据,其实到后台加上转义之后,是xxx0x5C0x27
那么我们可以想到,由于汉字在GBK编码的时候是两个十六进制的字节,UTF8是三个字节,而这个\是一个字节0x5c,如果我们能够再提供一个或者两个十六进制的字节数据和这个0x5c可以合并为一个汉字的编码的话,那么这个\不就被我们吃掉了吗?那么单引号就又可以生效了.
pikachu靶场,宽字节注入,抓包
url编码:‘→%27→0x27 \→%5c→0x5c
以上内容均为自己学习理解所得,如有错误,欢迎大家评论指正!
标签:编码,字节,字符,引号,转义,新手入门,SQL,注入 From: https://blog.csdn.net/2401_89344791/article/details/144727700