PwnKit: Local Privilege Escalation Vulnerability Discovered in polkit’s pkexec [CVE-2021-4034]

We discussed this vulnerability during Episode 116 on 01 February 2022

This was an interesting data based attack all because it was assumed there would be arguments in argv. A for-loop starts with n=1 looping until n < argv. Then after processing the arguments, accessing argv[n] outside of the loop. Normally this would be pointing to the last argument but when argc is zero, and the loop never runs and argv[n] points out of bounds.

This particular issue was actually reported on back in 2013 though it was not exploited at the time. It was noted that they could get as far as having the first environment variable treated as the executable to be started, but without being able to authenticate as root or pass arguments they couldn’t weaponize it.

Which is where PwnKit picks back up, rather than looking at this as just another way of controlling the program that will be executed, they looked at abusing that write-back into argv[n] as a way of introducing environment variables that would have been stripped by ld.so (which removes things like LD_PRELOAD when running setuid binaries so a low-privileged user cannot cause any issues). What Qualys found was that a cleverly named folder and binary name could be used to have it write back a proper environment variable.

Having a folder like name=. in their PATH environment, and inside the name=. folder having a binary named value would result in the g_find_program_in_path call returning the string name=./value which ends up being written into argv[n] aka envp[0].

Using this they could reintroduce sensitive environment values and compromise a privileged setuid binary.