BBS3000用户注册新漏洞的分析
简介: BBS3000是一套由yuzi等人开发的文本格式类的论坛程序。
由于对用户COOKIE验证方面设计的不完整性,导致非法人员可以通过构造一个特殊的请求,从而可以非法注册任意一个用户名称(当然,已经有人注册过了的,是无法再次注册的)。不管论坛是否禁止新用户注册,或者禁止注册某个用户名,该漏洞依然适用。最大的问题在于论坛管理员无法察觉注册人员数据,直到有新的用户加入论坛。
再者该漏洞导致论坛有可能被远程攻击者利用,进行多次用户注册,从而影响论坛空间大小,最后可以导致空间数据饱和。
有安全问题的程序文件是PHOTO2.CGI,以下为其中那段有问题的代码
-----------代码开始-------------
$username=$Cookies{username};
open(PSD,\"$filepath/yhzl/$username.cgi\");
$line=<PSD>;
chomp($line);
close(PSD);
($rdpassword,$rdname,$rdmail,$rdhome,$rlast,$rdqm,$rd***,$rdwork,$rdcity,$rdlove,$rfy,$rhf,$tu,$jiao,$iewin,$QQ,$photo,$savecookie,$level,$levelstar,$lastlytime,$lastlytopic,$realname,$birthday,$shengxiao,$blood,$constellation,$character,$belief,$marital,$education,$college)=split(/\\t/,$line);
open(PSD,\">$filepath/yhzl/$username.cgi\");
print PSD $rdpassword.\"\\t\".$rdname.\"\\t\".$rdmail.\"\\t\".$rdhome.\"\\t\".$rlast.\"\\t\".$rdqm.\"\\t\".$rd***.\"\\t\".$rdwork.\"\\t\".$rdcity.\"\\t\".$rdlove.\"\\t\".$rfy.\"\\t\".$rhf.\"\\t\".$tu.\"\\t\".$jiao.\"\\t\".$eNV{'HTTP_UseR_AGeNT'}.\"\\t\".$QQ.\"\\t\".$tttname.\"\\t\".$savecookie.\"\\t\".$level.\"\\t\".$levelstar.\"\\t\".$lastlytime.\"\\t\".\"$lastlytopic\\t\".$realname.\"\\t\".$birthday.\"\\t\".$shengxiao.\"\\t\".$blood.\"\\t\".$constellation.\"\\t\".$character.\"\\t\".$belief.\"\\t\".$marital.\"\\t\".$education.\"\\t\".$college;
close(PSD);
-----------代码结束-------------
首先,我们提交Cookie,其内容为username=Torune
open(PSD,\"$filepath/yhzl/$username.cgi\");
#代码转化为open(PSD,\"$filepath/yhzl/Torune.cgi\"); 打开一个名称为Torune.cgi的文件
#如果文件打开成功,则返回非零值,否则返回零。缺省地状态下则意味着打开这个文件并读取其内容
$line=<PSD>;
chomp($line);
close(PSD);
($rdpassword,$rdname,$rdmail,$rdhome,$rlast,$rdqm,$rd***,$rdwork,$rdcity,$rdlove,$rfy,$rhf,$tu,$jiao,$iewin,$QQ,$photo,$savecookie,$level,$levelstar,$lastlytime,$lastlytopic,$realname,$birthday,$shengxiao,$blood,$constellation,$character,$belief,$marital,$education,$college)=split(/\\t/,$line);
#正常情况下,用户登陆论坛后,他的COOKIE中的username的值已经被设置好了
#然而,Torune用户并没有注册过,相对的yhzl目录下的Torune.cgi也不存在
#正由于文件打开失败,返回值为零,则该段程序已经可以算是被略过了
#接下来的一段代码,正是此漏洞的核心所在
open(PSD,\">$filepath/yhzl/$username.cgi\");
#代码转化为open(PSD,\">$filepath/yhzl/Torune.cgi\");
#?*erl中想打开文件以便写入内容,则要在文件名前加个大于号
#例如open(FILE, \">file.txt\");
#向已有的文件末尾添加内容则使用两个大于号
#例如open(FILE, \">>file.txt\");
#在这里,也许yuzi的目的只是想覆盖文件,很奇怪的是这个photo2.cgi完全可以合并到photo.cgi里面去
#并且这些代码可以更加简化,但是不知道,作者的原意是什么。
print PSD
#文件写入字符串,PSD为文件变量
#往Torune.cgi中写入以下的内容
$rdpassword.\"\\t\".$rdname.\"\\t\".$rdmail.\"\\t\".$rdhome.\"\\t\".$rlast.\"\\t\".$rdqm.\"\\t\".$rd***.\"\\t\".$rdwork.\"\\t\".$rdcity.\"\\t\".$rdlove.\"\\t\".$rfy.\"\\t\".$rhf.\"\\t\".$tu.\"\\t\".$jiao.\"\\t\".$eNV{'HTTP_UseR_AGeNT'}.\"\\t\".$QQ.\"\\t\".$tttname.\"\\t\".$savecookie.\"\\t\".$level.\"\\t\".$levelstar.\"\\t\".$lastlytime.\"\\t\".\"$lastlytopic\\t\".$realname.\"\\t\".$birthday.\"\\t\".$shengxiao.\"\\t\".$blood.\"\\t\".$constellation.\"\\t\".$character.\"\\t\".$belief.\"\\t\".$marital.\"\\t\".$education.\"\\t\".$college;
close(PSD);
#由于我们无法对其他函数进行定义,如$rdpassword,$rdname等等。这是十分幸运的。
#如果可以定义,远程攻击者完全可以写入一个WEBSHELL,来控制远端主机
#在者,我们来看看yhzl的权限设置
#在安装过程中install.cgi文件已经把该目录设置为777,也就意味着该目录,可读,可写,可执行
# [ mkdir(\"$filepath/yhzl\",0777); ]
#到这里,我们已经成功地创建一个叫Torune.cgi的文件
#由于没有定义那些函数,但是依然会写入\\t也就是tab
#光是这种符号组成的文件也是会占用一定的空间的
既然已经成功建立了一个文件,接下来分析分析看看,我们新建立的用户是如何登陆论坛的
登陆文件LOGIN.CGI
-----------代码开始-------------
sub login{
if($username eq \"\"){&errorview(\"请输入您的用户名称\");}
#如果输入的用户名为空,则提示请输入您的用户名称
if ( -e \"$filepath/yhzl/$username.cgi\"){
#检查 输入的用户名.cgi 是否存在
open(PSD,\"$filepath/yhzl/$username.cgi\");
#打开 输入的用户名.cgi 文件
$line=<PSD>;
close(PSD);
($rdpassword)=split(/\\t/,$line);
if($userPSD ne \"$rdpassword\"){&errorview(\"您的密码错误!\");}}else{
#如果输入的密码与该用户的密码不一致,则提示您的密码错误!
&errorview(\"此用户名还没有在本社区注册过!\");exit;
}
-----------代码结束-------------
首先先看看那个if ( -e \"$filepath/yhzl/$username.cgi\")
在登陆页面提交username=Torune
而由于利用上面的漏洞,我们成功的建立了Torune.cgi文件,则 -e \"$filepath/yhzl/$username.cgi\" 为true
if($userPSD ne \"$rdpassword\"){&errorview(\"您的密码错误!\");}}else{
#由于我们无法定义函数$rdpassword的值,也就意味着$rdpassword为NULL(空)
#而该程序(LOGIN.CGI)没有if($password eq \"\"){&errorview(\"请输入您的密码\");}
#因此,该用户Torune成功的登陆了论坛
由于远程攻击者不是通过yhreg.cgi注册的
则该用户不会显示在新注册用户上,data/newmember里面也不会有新增加一名用户的记录
漏洞修补方法:
PHOTO2.CGI
在此程序中找到$tttname=$FORM{'tttname'};
?*晃?
-----------代码开始-------------
$username=~s/\\|\\.\\.\\%//g; # 这个可加可不加
$yhzlurl =\"$filepath/yhzl/$username.cgi\";
if (-e \"$yhzlurl\"){
open(PSD,\"$yhzlurl\");
$lines=<PSD>;
close(PSD);
($password)=split(/\\t/,$liness);
if($password ne $Cookies{password}){&errorview(\"对不起,您的密码错误!\");}
}
else {&errorview(\"对不起,此用户名还没有注册!\");}
$tttname=$FORM{'tttname'};
-----------代码结束-------------
LOGIN.CGI
在此程序中找到if($username eq \"\"){&errorview(\"请输入您的用户名称\");}
?*晃?
-----------代码开始-------------
if($username eq \"\"){&errorview(\"请输入您的用户名称\");}
if($userpsd eq \"\"){&errorview(\"请输入您的密码\");}
-----------代码结束-------------