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_4034_pwnkit_lpe_pkexec: false positive CheckCode::Vulnerable #19590

Open
bcoles opened this issue Oct 26, 2024 · 0 comments
Open

cve_2021_4034_pwnkit_lpe_pkexec: false positive CheckCode::Vulnerable #19590

bcoles opened this issue Oct 26, 2024 · 0 comments
Labels

Comments

@bcoles
Copy link
Contributor

bcoles commented Oct 26, 2024

CheckCode::Vulnerable is used in instances where a host is proven to be exploitable. However, the current check logic in cve_2021_4034_pwnkit_lpe_pkexec can only verify whether the system appears vulnerable, and should use CheckCode::Appears instead.

The check method logic is extremely aggressive (files and directories are created and deleted, and an executable file is uploaded and executed) as it uses the run_exploit method to determine if the host is vulnerable:

# run the exploit in check mode if everything looks right
if run_exploit(true)
return CheckCode::Vulnerable
end
return CheckCode::Safe('The target does not appear vulnerable')

After setting up the necessary conditions for exploitation, python is invoked and the resulting output is stored in the output variable:

cmd = "#{python_binary} #{exploit_file} #{pkexec_path} #{payload_file} #{random_string_1} #{random_string_2}"
print_warning("Verify cleanup of #{working_dir}")
vprint_status("Running #{cmd}")
output = cmd_exec(cmd)

The check is considered successful (and thus the host is considered vulnerable) if the output does not contain "pkexec --version" (and is not blank):

if check
return false if output.include?('pkexec --version')
return true
end

Although the original PoC apparently works on CentOS and is confirmed to work on Fedora, the module documentation suggests Fedora exhibits the same behaviour as a vulnerable host but is not vulnerable for unknown reasons:

### Fedora:
Fedora should be vulnerable, and the pkexec binary will respond like it is vulnerable, but
the exploit will fail. I don't know why, but it still fails with SELinux disabled or using the
original PoCs that compiled a binary on target. The check method just bails if it sees Fedora.

To work around this, the module bails if the host is Fedora:

if sysinfo[:distro] =~ /[fF]edora/
# Fedora should be supported, and it passes the check otherwise, but it just
# does not seem to work. I am not sure why. I have tried with SeLinux disabled.
return CheckCode::Safe('Fedora is not supported')
end

Additionally, the module documentation says RHEL is not tested but assumed to exhibit the same behaviour as Fedora:

### RedHat:
Untested on Redhat, but I assume similar to Fedora.

The module does not check if the system distro is RHEL. A quick test on RHEL9.0 shows the same behaviour as Fedora (exploitation fails, but check returns CheckCode::Vulnerable).

Thus, if a host is not detected as Fedora, but is not vulnerable due to the same unknown reason that Fedora is not vulnerable, then the host will be reported as CheckCode::Vulnerable. This is a oversight. The check method also does not account for other Linux distros in the Fedora family, including CentOS, Rocky Linux, Alma Linux, and RHEL, which may exhibit the same behaviour.

Without knowing the root cause of failure, the module should return CheckCode::Appears as the host is not proven to be exploitable.


For what it's worth, two different PoCs (https://github.com/PeterGottesman/pwnkit-exploit and https://github.com/arthepsy/CVE-2021-4034) and this exploit module all fail on an aarch64 host (despite check reporting CheckCode::Vulnerable):

$ make
gcc -o exploit exploit.c
make -C ./gconv BADCONV.so
make[1]: Entering directory '/home/user/pwnkit-exploit/gconv'
gcc -fPIC -shared badconv.c -o BADCONV.so
make[1]: Leaving directory '/home/user/pwnkit-exploit/gconv'
./exploit
Running exploit...
GLib: Cannot convert message: Could not open converter from “UTF-8” to “ZT”
The value for the SHELL variable was not found in the /etc/shells file

This incident has been reported.
make: *** [Makefile:12: run-exploit] Error 127
$ ./a.out 
GLib: Cannot convert message: Could not open converter from “UTF-8” to “PWNKIT”
The value for the SHELL variable was not found in the /etc/shells file

This incident has been reported.
msf6 exploit(linux/local/cve_2021_4034_pwnkit_lpe_pkexec) > run

[*] Started reverse TCP handler on 192.168.0.178:4444 
[!] AutoCheck is disabled, proceeding with exploitation
[*] Detected payload arch: aarch64
[*] Detected host architecture: aarch64
[*] Locating pkexec...
[*] Found pkexec here: /usr/bin/pkexec
[*] Creating directory /tmp/.rcuvolvmvb
[*] /tmp/.rcuvolvmvb created
[*] Writing '/tmp/.rcuvolvmvb/klywts/klywts.so' (628 bytes) ...
[!] Verify cleanup of /tmp/.rcuvolvmvb
[*] Running python3 /tmp/.rcuvolvmvb/.hmexrkwss /usr/bin/pkexec /tmp/.rcuvolvmvb/klywts/klywts.so klywts tazzgrryuyon
[*] GLib: Cannot convert message: Could not open converter from “UTF-8” to “tazzgrryuyon”
The value for the SHELL variable was not found in the /etc/shells file

This incident has been reported.
[*] Exploit completed, but no session was created.
@bcoles bcoles added the bug label Oct 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: No status
Development

No branches or pull requests

1 participant