-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Add Apport Symlink Hijacking: CVE-2020-8831 #20037
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
base: master
Are you sure you want to change the base?
Conversation
|
I've accidentally committed pushes from another module. My apologizes, I am unsure of the proper way to remove these. |
No problem; git is really awesome, but not always super intuitive. It looks like the unwanted commits are all related to your previous game overlay module.
Last, if you want, let me know and I am pretty sure I can fix it for you, but you might lose some commits. The only file you need here is |
822e526 to
68de77e
Compare
|
Yes, I only want the files relevant to this module pushed. I just added the rebase let me know if it is sufficient. |
Looks good! Let us know when you'd like us to review it. |
modules/exploits/linux/local/cve_2020_8831_apport_symlink_privesc.rb
Outdated
Show resolved
Hide resolved
modules/exploits/linux/local/cve_2020_8831_apport_symlink_privesc.rb
Outdated
Show resolved
Hide resolved
modules/exploits/linux/local/cve_2020_8831_apport_symlink_privesc.rb
Outdated
Show resolved
Hide resolved
modules/exploits/linux/local/cve_2020_8831_apport_symlink_privesc.rb
Outdated
Show resolved
Hide resolved
| ) | ||
| ) | ||
| register_options [ | ||
| OptString.new('WRITABLE_DIR', [true, 'A directory we can write to.', '/tmp']), |
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.
For local exploit modules, this is usually registered as an advanced option:
register_advanced_options [
OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp'])
]
modules/exploits/linux/local/cve_2020_8831_apport_symlink_privesc.rb
Outdated
Show resolved
Hide resolved
modules/exploits/linux/local/cve_2020_8831_apport_symlink_privesc.rb
Outdated
Show resolved
Hide resolved
…esc.rb Co-authored-by: bcoles <[email protected]>
…esc.rb Co-authored-by: bcoles <[email protected]>
…esc.rb Co-authored-by: bcoles <[email protected]>
…esc.rb Co-authored-by: bcoles <[email protected]>
…esc.rb Co-authored-by: bcoles <[email protected]>
…esc.rb Co-authored-by: bcoles <[email protected]>
…esc.rb Co-authored-by: bcoles <[email protected]>
|
Hello, I've been working on other things sorry for the delay. I wasn't sure where the symlink hijacking should occur, if you read my first comment I talk about it more there. Can't use |
I'm going to try and finish this next week sorry for the delay just wanted to keep you updated. |
|
I haven't forgotten about this. I'm able to create a root owned file w 777 perms named lock not sure what to do with it. Also I'm creating a container to help with testing. |
|
@gardnerapp, I'm sorry I completely missed the requests. |
Yes sir, I've been working on other modules and have been stumped on this one for quiet some time. I've tried writing a cron but Ubuntu wont execute crons w 777 permissions, and I can't change the permissions because the file is owned by root. I've been thinking about going through the other places to persist but haven't gotten to it. Thanks for getting back to me. |
|
Could we create a |
|
My first thought was cron and something in rc.d, but if you've tried that, we'll need to dig a bit deeper. I've tossed this out to the greater hive mind, and they will likely have some thoughts, too. |
|
#19815 may give you persistence ideas. |
|
The exploit creates a file owned by root:root with the name of lock and 777 permissions. In order to avoid having to re-write the exploit for every single persistence directory I'm going to create this file manually. Every exploit will execute /etc/cron.dcron won't execute because of insecure perms :/ |
/etc/init.dAs ubuntu user I get |
|
Hi there- I got a couple suggestions from the hive-mind here:
|
|
Also, a possible more destructive/persistent suggestion was udev: https://ch4ik0.github.io/en/posts/leveraging-Linux-udev-for-persistence/ |
Sure! Here's that research: https://www.rapid7.com/blog/post/2025/05/07/multiple-vulnerabilities-in-sonicwall-sma-100-series-2025/. Anything like that, writing a malicious binary to a higher directory on the path than the real binary, is a good and generally non-destructive bet. |
|
I've create a udev rule by using the exploit: I've tried rebooting the system after this, no file is created. Additionally I've tried manually triggering the udev rule via As with executing a crontab with 777 permissions I suspect that execution is blocked for files with unsafe permissions. I've tried to validate this hypothesis by debugging udev logs but I can't find anything indicating that the rule is even firing. I've tried using
If you'd like to test this without installing the vulnerable version of Apport you can create a file with 777 permissions in |
|
OK this is all set to go I opted to use apt hooks for the privilege escalation. Thank you to everyone for the contributes and suggestions to this module. Here is a quick run down. Before you test run these on the exploitable system: Now lets configure the exploit. I am using a bind shell because the machine is in the ☁️. Our exploit will now run on the next We'll hop back to msf and you'll find yourself with a root shell. Thank you again ! |
|
@gardnerapp sweet! Is this ready to move out of draft? |
yes |
| OptString.new('HOOKPATH', [false, 'APT configuration directory.', '/etc/apt/apt.conf.d/']) | ||
| ] | ||
| register_advanced_options [ | ||
| OptString.new('WRITABLE_DIR', [true, 'A directory where we can write files', '/tmp']) |
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.
Convention says that Advanced options use Camel case: https://docs.metasploit.com/docs/development/developing-modules/module-metadata/how-to-use-datastore-options.html
That said, I'm not entirely sold on this being an advanced option because we are writing the value, then hoping the user does something. If we write to temp, then the computer reboots before the user performs the action, we loose lose the contents of the temp directory; I'm not sure if the answer is to move the option to a regular option or to change the default location for the write.
| } | ||
| ] | ||
| ], | ||
| 'Privileged' => false, |
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.
Shouldn't this be true since the shell generated is root?
|
|
||
| # sudo rm -rf /var/lock/apport/ /tmp/payload /etc/apt/apt.conf.d/lock && unlink /var/lock/apport | ||
| # The above must be run after each subsequent test! | ||
| return CheckCode::Safe('Platform is not Linux') unless session.platform == 'linux' |
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 this because we destroy the Apport installation, or because Apport is non-permanent?
|
|
||
| print_status("Creating symlink...") | ||
|
|
||
| # Maybe we should just delete /var/lock/apport if it already exists?? |
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.
You could add an advanced option to remove it if it is found. Make the default value of False, then fail if it is found and suggest the user change the datastore option to True and rerun the module if they are OK removing it.
|
Thanks for your pull request! Before this can be merged, we need the following documentation for your module: |
|
Thanks for your pull request! Before this pull request can be merged, it must pass the checks of our automated linting tools. We use Rubocop and msftidy to ensure the quality of our code. This can be ran from the root directory of Metasploit: You can automate most of these changes with the Please update your branch after these have been made, and reach out if you have any problems. |
|
@gardnerapp what version of ubuntu are you using and where are you getting the apport deb package? |
Wooops! You said it in the description- Xenial Xerus 16.04.7 Still curious where you got the deb package, though. |
This pull request is a draft for CVE-2020-8831, I originally came across this vulnerability while reading From Day Zero to Zero Day, which I highly recommend. The long story short is that certain versions of apport will follow symbolic links when writing crash dumps. This file will have a mask of 777 and be owned by root. In this module I used the command
ln -s /cron.d /var/lock/apportso that a/etc/cron.d/lockcrontab file would be created. This crontab should execute a payload every minute which was located in the/tmpdirectory.After scratching my head for several hours and combing through the log files I found that the crontab would not execute because it's file permissions were too excessive. We need to find another place for the symlink hijacking to occur. I have a few places in mind namely
/etc/init.d/or~/.bashrcwhich would trigger the payload upon startup. I am submitting this because I am unsure of which route to go or if there are other places where the symlink hijacking should occur. Thank you !