技术笔记

SQL注入详解(宽字符注入) 第二集

字号+ 作者:sqler 来源:转载 2016-11-26 13:40 我要评论( )

前言 建议没看第一集的童鞋可以先看第一集: SQL注入漏洞详解 第一集 0x01 前言 又回来了,今天讲讲宽字节注入。 0x02 简介 宽字节注入源于程序员设置MySQL连接时......

前言
建议没看第一集的童鞋可以先看第一集:SQL注入漏洞详解 第一集


0x01 前言
    又回来了,今天讲讲宽字节注入。

0x02 简介

宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而导致的注入漏洞。具体原理如下:

1.正常情况下当GPC开启或使用addslashes函数过滤GET或POST提交的参数时,黑客使用的单引号 '就会被转义为: \';
 
2.但如果存在宽字节注入,我们输入%df%27时首先经过上面提到的单引号转 义变成了%df%5c%27(%5c是反斜杠\),之后在数据库查询前由于使用了GBK多字节编码,即在汉字编码范围内两个字节会被编码为一个汉字。然后 MySQL服务器会对查询语句进行GBK编码即%df%5c转换成了汉字“運”,而单引号逃逸了出来,从而造成了注入漏洞。
现在基本上都会将mysql的连接配置为“setcharacter_set_client=binary”来解决这个问题,所以这篇文章将介绍出现在php中因为字符编码转换导致的注入问题。

0x03 使用GBK编码
[AppleScript] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
$conn = mysql_connect('localhost', 'root', 'root') or die('bad!');
mysql_query("SET NAMES 'gbk'",$conn);
mysql_select_db('test', $conn) OR emMsg("数据库连接失败");
$id_tmp = isset($_GET['id']) ? urldecode($_GET['id']) : 1;
$id = addslashes($_GET['id']);
$sql = "SELECT * FROM news WHERE id = '{$id}'";
echo $sql;
$result = mysql_query($sql, $conn) or die(mysql_error());
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>gbk</title>
</head>
<body>
<?php
$row = mysql_fetch_array($result, MYSQL_ASSOC);
echo "<h3>{$row['title']}</h3><p>{$row['content']}<p>\n";
mysql_free_result($result);
?>
</body>
</html>
这里纠正一些人的观念,GBK编码是数据库编码,跟前台的编码无关,比如我这代码<meta charset="utf-8" />   就是使用了UTF-8

当我们正常请求这个网站的时候,数据库执行的是   select * from news where id = '1'

我们按照上节课讲的加个单引号,我们看是什么样子

看到,我们输入的变成了   select * from news where id = '1\'' ,在mysql里面,反斜杠\是转义符,相当于,把我们输入的1' 拿到数据库有没有匹配的项。
那这样我们是不是没有办法注入了?
那么本节课的重点就来了。因为数据库使用的是GBK的编码,\的编码是%5c
我们可以使用%df来吃掉它,那什么叫吃掉呢?
%df%5c在GBK编码中是属于一个字符"運",我我们输入id=1%df%27的时候,程序检测到有单引号(%27),就默认在它前面加了一个转义符\(%5c)
数据库查询的就是 select * from news where id = '1%df%5c%27'
之前说过,%df%5c = 運
这样我们的%27也就是单引号就逃出转义了,我们又是可以构造注入语句了

我们来测试一下


现在这种写法已经很少了,有些程序员有这个安全意识,就把代码改成了这样


GBK转UTF-8:

[AppleScript] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
require_once('common.php');
$conn = mysql_connect('localhost', 'root', 'root') or die('bad!');
mysql_query("SET NAMES binary'");
mysql_select_db('test', $conn) OR emMsg("数据库连接失败");
$id_tmp = isset($_GET['id']) ? urldecode($_GET['id']) : 1;
$id = iconv("gbk","utf-8",$id_tmp);
$sql = "SELECT * FROM news WHERE id = '{$id}'";
echo $sql;
$result = mysql_query($sql, $conn) or die(mysql_error());
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>gbk->utf-8</title>
</head>
<body>
<?php
$row = mysql_fetch_array($result, MYSQL_ASSOC);
echo "<h3>{$row['title']}</h3><p>{$row['content']}<p>\n";
mysql_free_result($result);
?>
</body>
</html>


我们来看看,关键的代码
[AppleScript] 纯文本查看 复制代码
?
1
2
mysql_query("SET NAMES binary'");
$id = iconv("gbk","utf-8",$id_tmp);

原理其实跟前言里第2条是一样的,我们输入%df%27时首先经过上面提到的单引号转义变成了%df%5c%27(%5c是反斜杠\),然后%df%5c 正好属于gbk的汉字编码范围,经过iconv转换到utf-8编码转换后变成了汉字“運”,从而吞掉了反斜杠使得单引号逃脱出来。



0x04  utf-8转gbk
测试代码

[AppleScript] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
$conn = mysql_connect('localhost', 'root', 'root') or die('bad!');
mysql_query("SET NAMES binary");
mysql_select_db('test', $conn) OR die("数据库连接失败");
$title_tmp = isset($_GET['id']) ? addslashes($_GET['id']) : 1;
$title = iconv("utf-8","gbk",$title_tmp);
$sql = "SELECT * FROM news WHERE id = '{$title}'";
echo $sql;
echo '<br/>';
$result = mysql_query($sql, $conn) or die(mysql_error());
 
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>gbk->utf-8</title>
</head>
<body>
<?php
$row = mysql_fetch_array($result, MYSQL_ASSOC);
echo "<h3>{$row['title']}</h3><p>{$row['content']}<p>\n";
mysql_free_result($result);
?>
</body>
</html>

这里我们就要用点逆向思维了
这里我们思考下“錦”这个字,它的utf-8编码是e98ca6,它的gbk编码是e55c,而上面提到过反斜杠\正好为5c。
所以如果我们将title设置为:錦’,首先经过addlashes函数或GPC对单引号转义变为:錦\’,然后会经过icnov函数会对”錦”转化为 gbk编码,最后就是:%e5%5c%5c%27。反斜杠被转义了(%5c%5c),从而单引号逃逸出来就会引发注入漏洞。

实验一下,我们看到报错
分析一下报错信息

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''\xE5\\''' at line 1

''\xE5\\'''   \xE是属于一个字符,这就多出了一个\,反斜杠是转义符,\\',这样的话,转义符就转义了第二个\,导致单引号逃出来,我们就可以继续注入了




本文来自: 蜗蜗侠's Blog-关注网络安全 http://blog.icxun.cn/Note/307.html

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 转大表哥安全狗SQL注入语句(176处)

    转大表哥安全狗SQL注入语句(176处)

    2017-12-05 13:47

  • Mysql注入点在limit关键字后面的利用方法

    Mysql注入点在limit关键字后面的利用方法

    2016-12-18 15:06

  • 一个罕见的MSSQL注入漏洞案例

    一个罕见的MSSQL注入漏洞案例

    2016-12-18 15:03

  • postgresql注入之文件读写

    postgresql注入之文件读写

    2016-12-13 15:25

网友点评
暂时未开启评论功能~