Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add exploit for CVE-2019-4716, unauth rce for IBM PA / TM1 #13152

Merged
merged 27 commits into from
Mar 30, 2020

Conversation

pedrib
Copy link
Contributor

@pedrib pedrib commented Mar 27, 2020

This module exploits a vulnerability in IBM TM1 / Planning Analytics that allows an unauthenticated attacker to perform a configuration overwrite.
It starts by quering the Admin server for the available applications, picks one, and then exploits it. You can also provide an application name to bypass this.
The configuration overwrite is used to change an application server authentication method to "CAM", a proprietary IBM auth method, which is simulated by the exploit.
The exploit then performs a fake authentication as admin, and finally abuses TM1 scripting to perform a command injection as root or SYSTEM.

modules/exploits/multi/misc/ibm_tm1_unauth_rce.rb Outdated Show resolved Hide resolved
modules/exploits/multi/misc/ibm_tm1_unauth_rce.rb Outdated Show resolved Hide resolved
modules/exploits/multi/misc/ibm_tm1_unauth_rce.rb Outdated Show resolved Hide resolved
modules/exploits/multi/misc/ibm_tm1_unauth_rce.rb Outdated Show resolved Hide resolved
modules/exploits/multi/misc/ibm_tm1_unauth_rce.rb Outdated Show resolved Hide resolved
@pedrib
Copy link
Contributor Author

pedrib commented Mar 27, 2020

@bcoles all fixed. Do you want pcaps? Unless you have access to a paid copy of the software you won't be able to test.

@bcoles
Copy link
Contributor

bcoles commented Mar 27, 2020

@bcoles all fixed. Do you want pcaps? Unless you have access to a paid copy of the software you won't be able to test.

pcaps will likely be required and can be sent to msfdev@metasploit.com.

I gave the module a quick once over. It is likely that someone else will also wish to give it a once over before landing, especially as the module contains some frowned-upon-but-not-explicitly-forbidden practices like overwriting the datastore options.

Co-Authored-By: bcoles <bcoles@gmail.com>
@pedrib
Copy link
Contributor Author

pedrib commented Mar 27, 2020

@bcoles all fixed. Do you want pcaps? Unless you have access to a paid copy of the software you won't be able to test.

pcaps will likely be required and can be sent to msfdev@metasploit.com.

I gave the module a quick once over. It is likely that someone else will also wish to give it a once over before landing, especially as the module contains some frowned-upon-but-not-explicitly-forbidden practices like overwriting the datastore options.

Yes, this is a common problem for me. It's marked as a TODO in the HttpServer file, mostly because of me:
https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/exploit/http/server.rb#L143

This is the third time I had to use a workaround, here are the other two:
https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/linux/http/dlink_hnap_login_bof.rb#L256
https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/nuuo/nuuo_cms_sqli.rb#L122

@pedrib
Copy link
Contributor Author

pedrib commented Mar 28, 2020

Is there a problem if I put them all on two targets and let the user choose a payload? Would make it less confusing IMO

@pedrib
Copy link
Contributor Author

pedrib commented Mar 28, 2020

      'Arch'           =>
        [
          ARCH_CMD,
          ARCH_X86,
          ARCH_X64
        ],
      'Targets'        =>
        [
          [ '(Windows) IBM TM1 <= 10.2.2 / Planning Analytics <= 2.0.8',
            { 'Platform'  => 'win' }
          ],
          [ '(Linux) IBM TM1 <= 10.2.2 / Planning Analytics <= 2.0.8',
            { 'Platform'  => %w{linux unix} }
          ],
        ],

@pedrib
Copy link
Contributor Author

pedrib commented Mar 28, 2020

Just thought about one thing - it is likely this exploit also works on AIX targets, but I don't have one to test

@bcoles
Copy link
Contributor

bcoles commented Mar 28, 2020

Is there a problem if I put them all on two targets and let the user choose a payload? Would make it less confusing IMO

That's up to whoever reviews this PR.

The module will need to be updated to perform dynamic detection of the user-provided payload type, ie, payload.arch, and control execution flow. A payload with arch cmd will need to execute execute_command whereas a payload with arch X64 will need to execute execute_cmdstager.

Generally it is cleaner and less confusing to have one conditional switch/case for target selection and let the framework take care of verifying whether the supplied payload is compatible with the selected target, rather than trying to use custom code.

@pedrib
Copy link
Contributor Author

pedrib commented Mar 28, 2020

ok understood, I'll make the changes

@bcoles
Copy link
Contributor

bcoles commented Mar 28, 2020

Here's an example for handling the target.

This example is a little more complex than necessary, as it takes advantage of a vulnerability where the response from the command can be viewed, so has custom code to choose whether the payload should be executed in the background or foreground so the operator can see the output.

    case target['Type']
    when :unix_memory
      if datastore['PAYLOAD'] == 'cmd/unix/generic'
        execute_command(payload.encoded, foreground: true)
      else 
        execute_command(payload.encoded)
      end
    when :win_memory
      if datastore['PAYLOAD'] == 'cmd/windows/generic'
        execute_command(payload.encoded, foreground: true)
      else
        execute_command(payload.encoded)
      end
    when :psh_memory
      execute_command(
        cmd_psh_payload(
          payload.encoded,
          payload_instance.arch.first,
          { :remove_comspec => true, :encode_final_payload => true }
        )
      )
    when :linux_dropper
      execute_cmdstager(:linemax => 1_500)
    when :win_dropper
      execute_cmdstager(:linemax => 1_500)
    end     

@pedrib
Copy link
Contributor Author

pedrib commented Mar 28, 2020

@bcoles all done! Let me know your thoughts. BTW I tried sending pcaps to the email address you gave above, but they keep bouncing back. I guess the provider is Gmail, which doesn't like pcaps

@pedrib
Copy link
Contributor Author

pedrib commented Mar 28, 2020

I'm using payload.raw for the ARCH_CMD handling, should I use payload.encoded? This doesn't make sense, since the command is executed directly, so it should be raw?

@bcoles
Copy link
Contributor

bcoles commented Mar 28, 2020

I'm using payload.raw for the ARCH_CMD handling, should I use payload.encoded? This doesn't make sense, since the command is executed directly, so it should be raw?

Payload encoding is best practice and preferred where possible. Only very rarely is payload.raw used (in very restricted circumstances). Using payload.raw will prevent the operator from selecting custom payload encodings.

@bcoles
Copy link
Contributor

bcoles commented Mar 28, 2020

@bcoles all done! Let me know your thoughts. BTW I tried sending pcaps to the email address you gave above, but they keep bouncing back. I guess the provider is Gmail, which doesn't like pcaps

Strange. That's the correct address. I don't have access to the mailbox, but I known PCAP attachments have worked fine in the past. You could try renaming to .txt and/or compressing it.

@pedrib
Copy link
Contributor Author

pedrib commented Mar 28, 2020

I'm using payload.raw for the ARCH_CMD handling, should I use payload.encoded? This doesn't make sense, since the command is executed directly, so it should be raw?

Payload encoding is best practice and preferred where possible. Only very rarely is payload.raw used (in very restricted circumstances). Using payload.raw will prevent the operator from selecting custom payload encodings.

Actually encoding doesn't make any sense here (it's a straight up command injection), but I'll change to it payload.encoded anyway.

@bcoles
Copy link
Contributor

bcoles commented Mar 28, 2020

Just thought about one thing - it is likely this exploit also works on AIX targets, but I don't have one to test

Fortunately, the target for unix ARCH_CMD should also (probably) work on AIX.

You could easily add another target for AIX platform. Usually the fact that it's been untested should be documented somewhere. Either in the target name, ie AIX (Untested), or in a code comment somewhere nearby.

@pedrib
Copy link
Contributor Author

pedrib commented Mar 28, 2020

ok, split the linux and aix command targets.

I have tried sending it encrypted inside a zip, with encrypted file names, and I get this back:
This message was created automatically by mail delivery software.

A message that you sent could not be delivered to one or more of
its recipients. This is a permanent error. The following address(es)
failed:

msfdev@metasploit.com:
SMTP error from remote server for TEXT command, host: aspmx.l.google.com reason: 552-5.7.0 This message was blocked because its content presents a potential
552-5.7.0 security issue. Please visit
552-5.7.0 https://support.google.com/mail/?p=BlockedMessage to review our
552 5.7.0 message content and attachment content guidelines.

  • gsmtp

@bcoles
Copy link
Contributor

bcoles commented Mar 28, 2020

I have tried sending it encrypted inside a zip, with encrypted file names, and I get this back:
This message was created automatically by mail delivery software.

welp. whoever reviews this PR may have a preferred delivery method. Perhaps a private link via slack or dropbox. If the contents of the pcap aren't sensitive, you could drop it here.

I'm using payload.raw for the ARCH_CMD handling, should I use payload.encoded? This doesn't make sense, since the command is executed directly, so it should be raw?

Payload encoding is best practice and preferred where possible. Only very rarely is payload.raw used (in very restricted circumstances). Using payload.raw will prevent the operator from selecting custom payload encodings.

Actually encoding doesn't make any sense here (it's a straight up command injection), but I'll change to it payload.encoded anyway.

The inverse is true. Using payload.encoded is best practice and a point of pride, as this indicates you've effectively enumerated all bad characters and have a stable working exploit, allowing the operator to choose any encoding they wish.

Comparatively, using payload.raw is a warning sign that the code has not been thoroughly written or tested, and may indicate that you were defeated by input filtering or validation (or were too lazy to bypass it).

$ grep -rn payload.raw modules/ | wc -l
53
$ grep -rn payload.encoded modules/ | wc -l
1793

@pedrib
Copy link
Contributor Author

pedrib commented Mar 28, 2020

Most likely a properly configured IPS (with specific rules to catch this) can detect this attack, since there is no way to configure SSL on the authentication (hence why the SSL datastore switch).

I could make it even harder to detect the payload delivery: once the auth is finished (which has to be done over HTTP), starting a second HTTP server that delivers the payload over https, but I have decided against this for two reasons:

  1. this would create additional complexity in an exploit that is already complex, which is far from ideal
  2. I have sunk too much time into this, need to move on to chargeable work!

To counter this a bit I added I added the Command payloads, since they only perform auth over HTTP, and don't download the payload. I believe this will give it a much better chance of sneaking by AV / IPS.

This is just an FYI, I already changed to payload.encoded.

@pedrib
Copy link
Contributor Author

pedrib commented Mar 30, 2020

@bcoles inspired by you I decided to hunt for bad chars, and found one in Linux and several in Windows. I've tested them on my bench against both OS and seems to be working fine now.

Another thing - it seems that now all commands that I send are processed as if they have bad chars, even if they don't. Is there a way to turn that off? I think that might cause problems for long commands.

Also - this product might be installed in very old windows that do not have powershell, so in those cases it would be preferable to use the raw payload, especially if it's not necessary to encode it.

@wvu wvu self-assigned this Mar 30, 2020
@wvu
Copy link
Contributor

wvu commented Mar 30, 2020

@pedrib: Got your pcap and looked through it. Thanks!

wvu added a commit that referenced this pull request Mar 30, 2020
@wvu wvu merged commit d904eed into rapid7:master Mar 30, 2020
@wvu
Copy link
Contributor

wvu commented Mar 30, 2020

Module doc updated as per tools/dev/msftidy_docs.rb in 8209a4e.

@wvu
Copy link
Contributor

wvu commented Mar 30, 2020

Release Notes

This adds an exploit for CVE-2019-4716 against IBM Planning Analytics powered by TM1.

@pedrib
Copy link
Contributor Author

pedrib commented Mar 30, 2020

@wvu-r7 thanks!

What about this?

Another thing - it seems that now all commands that I send are processed as if they have bad chars, even if they don't. Is there a way to turn that off? I think that might cause problems for long commands.

Is there a fix for it?

For example, if I enter calc.exe as the command, it still runs it under powershell...

@wvu
Copy link
Contributor

wvu commented Mar 30, 2020

@pedrib: Show me? Also, are you "careta" on IRC?

@pedrib pedrib deleted the ibm_pa branch March 31, 2020 03:35
@tperry-r7 tperry-r7 added the rn-modules release notes for new or majorly enhanced modules label Apr 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs module rn-modules release notes for new or majorly enhanced modules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants