Monday, September 14, 2009

One-Day Knowledge

In August 2009, ZDI discloses a few details regarding a couple of interesting vulnerabilities (ZDI-09-058, ZDI-09-059) in Oracle Backup Admin server. I’ve seen several installations of this product, mainly used in corporations. Since I was quite interested in such flaws, I did a bit of research and I’ve published an exploit (osb10.3_poc.sh). This PoC exploits two separate vulnerabilities: a smart authentication bypass and a trivial command injection, resulting in arbitrary command execution.

You may find interesting how the bypass works. It is a neat piece of hacking, in my humble opinion.
To have a successful login, both following functions should return "true" (login.php, #75)

if (validate_login($username,$passwd) && authenticate()){
[…]
}
The first one (common.php, #262) verifies username/password size and format.
As you can see, it accepts a username containing a-zA-Z0-9._- chars only.

function validate_login($username, $password)
{
global $status_msg;

if (strlen($username) > 128 || preg_match("/[^a-zA-Z0-9._-]/", trim($username)))
{
$status_msg[] = "Error: login failed";
return false;
}
if (strlen($password) > 16)
{
$status_msg[] = "Error: login failed";
return false;
}
return true;
}
On the other hand, the second function executes a command line tool and checks for error messages. Since Oracle Backup server command line tools require authentication in order to be successfully executed, the developers decided to use this application behavior in order to check whether the user has got a valid session. No comment, please!

// Check for a failed login.
if (strstr($msg[0], " login incorrect") ||
strstr($msg[0], "obtool:") ||
strstr($msg[0], "Obtool:") ||
strstr($msg[0], "Error:") ||
strstr($msg[0], "sh:"))
[…]
And here a question: “Can we tamper a valid username, according to the specified format, in order to properly execute the binary without triggering errors?” Sure, we do. Check the exploit and find the answer!

3 comments:

  1. Great work Luca!!
    Now it makes sense, the '--' in the username field is causing the command line tool to return with no errors right? I think posting the section of the code calling the command-line tool might provide more insight.

    ReplyDelete
  2. Nice to see you here!
    The idea is to inject a fake option (e.g. –-fake) in order to get the usage screen which does not contain strings as “Error”, “login incorrect”, etc. In this case, the username matches the format as well as the “authenticate()” function does not return errors.

    Cheers,
    Luca

    ReplyDelete