This repo contains my work on clumsily implementing a public 1day exploit for the sudo bug. Wish me luck.
If you would like to help please feel free.
Compile the provided src/sudo
sudoedit
has been modified to use AFL harness to get input from STDIN
AFL Fuzzy loop crash test cases discovered so far, check these out:
-rw------- 1 root root 309 Jan 28 03:31 id:000000,sig:11,src:000024,time:335,op:havoc,rep:2
-rw------- 1 root root 309 Jan 28 03:31 id:000001,sig:06,src:000024,time:1419,op:havoc,rep:4
-rw------- 1 root root 278 Jan 28 03:31 id:000002,sig:06,src:000024,time:2545,op:havoc,rep:8
-rw------- 1 root root 300 Jan 28 03:31 id:000003,sig:11,src:000024,time:5812,op:havoc,rep:4
-rw------- 1 root root 309 Jan 28 03:31 id:000004,sig:11,src:000024,time:7063,op:havoc,rep:8
-rw------- 1 root root 296 Jan 28 03:31 id:000005,sig:11,src:000024,time:8231,op:havoc,rep:8
-rw------- 1 root root 309 Jan 28 03:31 id:000006,sig:11,src:000024,time:8395,op:havoc,rep:2
-rw------- 1 root root 310 Jan 28 03:31 id:000007,sig:11,src:000024,time:9048,op:havoc,rep:8
-rw------- 1 root root 277 Jan 28 03:31 id:000008,sig:11,src:000024,time:9305,op:havoc,rep:16
-rw------- 1 root root 281 Jan 28 03:31 id:000009,sig:06,src:000024,time:11059,op:havoc,rep:2
-rw------- 1 root root 232 Jan 28 03:31 id:000010,sig:11,src:000024,time:13883,op:havoc,rep:4
-rw------- 1 root root 304 Jan 28 03:31 id:000011,sig:11,src:000024,time:17245,op:havoc,rep:8
-rw------- 1 root root 265 Jan 28 03:31 id:000012,sig:06,src:000024,time:18928,op:havoc,rep:8
-rw------- 1 root root 309 Jan 28 03:31 id:000013,sig:11,src:000024,time:21131,op:havoc,rep:8
-rw------- 1 root root 309 Jan 28 03:31 id:000014,sig:09,src:000024,time:29628,op:havoc,rep:4
-rw------- 1 root root 306 Jan 28 03:32 id:000015,sig:11,src:000024,time:60593,op:havoc,rep:8
-rw------- 1 root root 284 Jan 28 03:32 id:000016,sig:06,src:000024,time:65998,op:havoc,rep:16
-rw------- 1 root root 91053 Jan 28 03:39 id:000017,sig:09,src:000026+000018,time:518485,op:splice,rep:8
-rw------- 1 root root 318 Jan 28 03:39 id:000018,sig:11,src:000026+000045,time:520493,op:splice,rep:2
-rw------- 1 root root 65399 Jan 28 03:42 id:000019,sig:06,src:000012,time:678458,op:havoc,rep:16
-rw------- 1 root root 65441 Jan 28 04:33 id:000020,sig:06,src:000009,time:3762442,op:havoc,rep:16
-rw------- 1 root root 303 Jan 28 04:44 id:000021,sig:11,src:000025+000034,time:4377085,op:splice,rep:4
-rw------- 1 root root 91045 Jan 28 04:46 id:000022,sig:06,src:000019+000058,time:4538775,op:splice,rep:16
-rw------- 1 root root 296 Jan 28 05:14 id:000023,sig:06,src:000051,time:6173954,op:havoc,rep:16
-rw------- 1 root root 279 Jan 28 06:10 id:000024,sig:11,src:000023+000037,time:9549571,op:splice,rep:4
sig:11 means Segmentation Fault which is what we want. Signal 06 is SIGABRT which they gave us to start with.
load up the compiled sudoedit (make sure it has effective uid 0, run gdb as root)
# gdb /usr/local/bin/sudoedit
Load crash case from src/afl3/out/default/crashes: (note: this is the first sigsegv i found, its not a very good one, this id:000008 can be found in crashes_old)
gef➤ r < id:000008*
[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax : 0x414196c9adb30e58
$rbx : 0x4141414141414140 ("@AAAAAAA"?)
$rcx : 0x000055886c706010 → 0x0000000000000007
$rdx : 0x4141414141414148 ("HAAAAAAA"?)
$rsp : 0x00007fffdfe911d0 → 0x00007fb17cea12d0 → "<- %s @ %s:%d := %s"
$rbp : 0x00007fb17ccceb80 → 0x0000000000000000
$rsi : 0x000055886c71cca0 → 0x4141414141414180
$rdi : 0x00007fb17ccceb80 → 0x0000000000000000
$rip : 0x00007fb17cb96a79 → <_int_free+409> mov rax, QWORD PTR [r13+0x8]
$r8 : 0x7
$r9 : 0x1
$r10 : 0xfffffffffffff1ed
$r11 : 0x5
$r12 : 0x000055886c71cca0 → 0x4141414141414180
$r13 : 0x414196c9adb30de0
$r14 : 0x00007fb17cccf578 → 0x000055886c71ccb0 → "AAAAAAAAAAAAAAAAAAAAAAAAARAAFAAAAAAAAAAAAAAAAAAAAA[...]"
$r15 : 0x00007fffdfe91290 → 0x00007fb17cc9bb5f → 0x636d656d5f5f0043 ("C"?)
$eflags: [zero CARRY PARITY ADJUST SIGN trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffdfe911d0│+0x0000: 0x00007fb17cea12d0 → "<- %s @ %s:%d := %s" ← $rsp
0x00007fffdfe911d8│+0x0008: 0x000055886c70e880 → 0x0000000000000043 ("C"?)
0x00007fffdfe911e0│+0x0010: 0x0000000000000000
0x00007fffdfe911e8│+0x0018: 0x000000017ce94e8e
0x00007fffdfe911f0│+0x0020: 0x0000000000000000
0x00007fffdfe911f8│+0x0028: 0x00007fb17cb416bb → <new_composite_name+203> test eax, eax
0x00007fffdfe91200│+0x0030: 0x00007fffdfe91290 → 0x00007fb17cc9bb5f → 0x636d656d5f5f0043 ("C"?)
0x00007fffdfe91208│+0x0038: 0xdfb8629d88483900
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
0x7fb17cb96a69 <_int_free+393> je 0x7fb17cb97018 <_int_free+1848>
0x7fb17cb96a6f <_int_free+399> test BYTE PTR [rbp+0x4], 0x2
0x7fb17cb96a73 <_int_free+403> je 0x7fb17cb97028 <_int_free+1864>
→ 0x7fb17cb96a79 <_int_free+409> mov rax, QWORD PTR [r13+0x8]
0x7fb17cb96a7d <_int_free+413> test al, 0x1
0x7fb17cb96a7f <_int_free+415> je 0x7fb17cb97050 <_int_free+1904>
0x7fb17cb96a85 <_int_free+421> mov r14, rax
0x7fb17cb96a88 <_int_free+424> and r14, 0xfffffffffffffff8
0x7fb17cb96a8c <_int_free+428> cmp rax, 0x10
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "sudoedit", stopped 0x7fb17cb96a79 in _int_free (), reason: SIGSEGV
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x7fb17cb96a79 → _int_free(av=0x7fb17ccceb80 <main_arena>, p=0x55886c71cca0, have_lock=<optimized out>)
[#1] 0x7fb17cb41e5c → setname(name=0x7fb17cc9bb5f <_nl_C_name> "C", category=0xb)
[#2] 0x7fb17cb41e5c → __GI_setlocale(category=0xb, locale=<optimized out>)
[#3] 0x7fb17c70cc59 → sudoers_setlocale(locale_type=0x1, prev_locale=<optimized out>)
[#4] 0x7fb17c722336 → sudoers_policy_main(argc=<optimized out>, argv=<optimized out>, pwflag=0x0, env_add=<optimized out>, verbose=0x0, closure=0x7fffdfe93488)
[#5] 0x7fb17c71d65e → sudoers_policy_check(argc=0x7, argv=0x55886c709570, env_add=0x0, command_infop=0x7fffdfe93520, argv_out=0x7fffdfe93558, user_env_out=0x7fffdfe93540, errstr=0x7fffdfe93620)
[#6] 0x55886b1185db → policy_check(argc=0x7, argv=0x55886c709570, env_add=0x0, command_info=0x7fffdfe93520, argv_out=0x7fffdfe93558, user_env_out=0x7fffdfe93540)
[#7] 0x55886b1185db → main(argc=<optimized out>, argv=<optimized out>, envp=0x7fffdfe94758)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤
gef➤ der $sp 50
0x00007ffcc9026680│+0x0000: 0x00007fca4b2b12d0 → "<- %s @ %s:%d := %s" ← $rsp
0x00007ffcc9026688│+0x0008: 0x00005589bfc2e880 → 0x0000000000000043 ("C"?)
0x00007ffcc9026690│+0x0010: 0x0000000000000000
0x00007ffcc9026698│+0x0018: 0x000000014b2a4e8e
0x00007ffcc90266a0│+0x0020: 0x0000000000000000
0x00007ffcc90266a8│+0x0028: 0x00007fca4af516bb → <new_composite_name+203> test eax, eax
0x00007ffcc90266b0│+0x0030: 0x00007ffcc9026740 → 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc90266b8│+0x0038: 0x79e92f350d458c00
0x00007ffcc90266c0│+0x0040: 0x79e92f350d458c00
0x00007ffcc90266c8│+0x0048: 0x00007ffcc90267b0 → 0x00007fca4b0db6a0 → 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc90266d0│+0x0050: 0x000000000000000b
0x00007ffcc90266d8│+0x0058: 0x00007fca4b0dd8e0 → 0x00007fca4af54170 → <_nl_postload_ctype+0> mov rdx, QWORD PTR [rip+0x18b329] # 0x7fca4b0df4a0 <_nl_global_locale>
0x00007ffcc90266e0│+0x0060: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc90266e8│+0x0068: 0x00007fca4b0df578 → 0x00005589bfc3ccb0 → "AAAAAAAAAAAAAAAAAAAAAAAAARAAFAAAAAAAAAAAAAAAAAAAAA[...]"
0x00007ffcc90266f0│+0x0070: 0x00007ffcc9026740 → 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc90266f8│+0x0078: 0x00007fca4af51e5c → <setlocale+1644> mov rdx, QWORD PTR [rsp+0x8]
0x00007ffcc9026700│+0x0080: 0x00007fca4b2b124b → "-> %s @ %s:%d"
0x00007ffcc9026708│+0x0088: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc9026710│+0x0090: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc9026718│+0x0098: 0x00007fca4b2a4e8e → <sudo_debug_printf2_v1+190> mov rax, QWORD PTR fs:0x28
0x00007ffcc9026720│+0x00a0: 0x0000000000000000
0x00007ffcc9026728│+0x00a8: 0x00007fca4ab7b967 → "sudoers_setlocale"
0x00007ffcc9026730│+0x00b0: 0x0000000000000000
0x00007ffcc9026738│+0x00b8: 0x0000000000000000
0x00007ffcc9026740│+0x00c0: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?) ← $r15
0x00007ffcc9026748│+0x00c8: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc9026750│+0x00d0: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc9026758│+0x00d8: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc9026760│+0x00e0: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc9026768│+0x00e8: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc9026770│+0x00f0: 0x00007fca4b2b0830 → 0x6c61660065757274 ("true"?)
0x00007ffcc9026778│+0x00f8: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc9026780│+0x0100: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc9026788│+0x0108: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc9026790│+0x0110: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc9026798│+0x0118: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc90267a0│+0x0120: 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc90267a8│+0x0128: 0x00000000000002fd
0x00007ffcc90267b0│+0x0130: 0x00007fca4b0db6a0 → 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc90267b8│+0x0138: 0x00007fca4b0dbbe0 → 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc90267c0│+0x0140: 0x00007fca4b0dbc60 → 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc90267c8│+0x0148: 0x00007fca4b0dc4e0 → 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc90267d0│+0x0150: 0x00007fca4b0dba20 → 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc90267d8│+0x0158: 0x00007fca4b0db9a0 → 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc90267e0│+0x0160: 0x00007ffcc9026720 → 0x0000000000000000
0x00007ffcc90267e8│+0x0168: 0x00007fca4b0dc1a0 → 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc90267f0│+0x0170: 0x00007fca4b0dc200 → 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc90267f8│+0x0178: 0x00007fca4b0dc280 → 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc9026800│+0x0180: 0x00007fca4b0dc340 → 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
0x00007ffcc9026808│+0x0188: 0x00007fca4b0dc3c0 → 0x00007fca4b0abb5f → 0x636d656d5f5f0043 ("C"?)
gef➤
happy hacking
NEW CRASH UWU CHECK THIS BAD BOY OUT:
gef➤ r < id:000008*
[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax : 0x414141414f414141 ("AAAOAAAA"?)
$rbx : 0x000055e3c33cd080 → 0x000055e3c33cceb0 → "JJJAAAAAAAAOAAAA AAAAAAAAAAAAAAJJJJJJJJJJJJJJJJJJU[...]"
$rcx : 0x49f
$rdx : 0x56
$rsp : 0x00007fffb7527dc0 → 0x000055e3c33c7600 → 0x000055e3c33cd070 → 0x0000000000000000
$rbp : 0x00007ffaa2cf4848 → 0x0000070400000703
$rsi : 0x0
$rdi : 0x00007ffaa34098d8 → 0x000004a00000049f
$rip : 0x00007ffaa2c95fae → 0x3774db8548188b48
$r8 : 0x00007ffaa340124b → "-> %s @ %s:%d"
$r9 : 0x00007fffb7527d30 → 0x0000003000000028 ("("?)
$r10 : 0x00007ffaa31fb45d → "__vdso_time"
$r11 : 0x00007fffb759ca30 → 0x48ffffb649058d48
$r12 : 0x000055e3c33bf938 → 0x000055e3c33c73a0 → 0x000055e3c33c7600 → 0x000055e3c33cd070 → 0x0000000000000000
$r13 : 0x000055e3c33cd070 → 0x0000000000000000
$r14 : 0x0
$r15 : 0x000055e3c33c1dd8 → 0x000055e3c33c1e08 → 0x72007800746f6f72 ("root"?)
$eflags: [zero carry parity adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffb7527dc0│+0x0000: 0x000055e3c33c7600 → 0x000055e3c33cd070 → 0x0000000000000000 ← $rsp
0x00007fffb7527dc8│+0x0008: 0x00007ffaa2cf0970 → 0x0000000000000000
0x00007fffb7527dd0│+0x0010: 0x0000000060137cb7
0x00007fffb7527dd8│+0x0018: 0x000055e3c33cd070 → 0x0000000000000000
0x00007fffb7527de0│+0x0020: 0x00007ffaa2cf482c → 0x000006fd000006fc
0x00007fffb7527de8│+0x0028: 0x000055e3c33c1dd8 → 0x000055e3c33c1e08 → 0x72007800746f6f72 ("root"?)
0x00007fffb7527df0│+0x0030: 0x00007ffaa2cf4848 → 0x0000070400000703
0x00007fffb7527df8│+0x0038: 0x00007ffaa2c754fc → 0x28246c894c01f883
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
0x7ffaa2c95fa1 <userlist_matches+65> call 0x7ffaa2c5a2a0 <sudo_debug_enter_v1@plt>
0x7ffaa2c95fa6 <userlist_matches+70> mov rax, QWORD PTR [rbx+0x8]
0x7ffaa2c95faa <userlist_matches+74> mov rax, QWORD PTR [rax+0x8]
→ 0x7ffaa2c95fae <userlist_matches+78> mov rbx, QWORD PTR [rax]
0x7ffaa2c95fb1 <userlist_matches+81> test rbx, rbx
0x7ffaa2c95fb4 <userlist_matches+84> je 0x7ffaa2c95fed <userlist_matches+141>
0x7ffaa2c95fb6 <userlist_matches+86> lea r13, [rip+0x60bb7] # 0x7ffaa2cf6b74
0x7ffaa2c95fbd <userlist_matches+93> nop DWORD PTR [rax]
0x7ffaa2c95fc0 <userlist_matches+96> mov rdi, r12
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:./match.c+119 ────
114 userlist_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
115 const struct member_list *list)
116 {
117 struct member *m;
118 int matched = UNSPEC;
→ 119 debug_decl(userlist_matches, SUDOERS_DEBUG_MATCH);
120
121 TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
122 if ((matched = user_matches(parse_tree, pw, m)) != UNSPEC)
123 break;
124 }
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "sudoedit", stopped 0x7ffaa2c95fae in userlist_matches (), reason: SIGSEGV
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x7ffaa2c95fae → userlist_matches(parse_tree=0x55e3c33bf938, pw=0x55e3c33c1dd8, list=0x55e3c33cd080)
[#1] 0x7ffaa2c754fc → sudoers_lookup_check(nss=0x7ffaa2cf0970 <sudo_nss_file>, pw=0x55e3c33c1dd8, validated=<optimized out>, info=0x7fffb7527e60, matching_cs=<optimized out>, defs=<optimized out>, now=0x60137cb7)
[#2] 0x7ffaa2c754fc → sudoers_lookup(snl=<optimized out>, pw=<optimized out>, cmnd_status=0x7ffaa2cf0bb8 <cmnd_status>, pwflag=<optimized out>)
[#3] 0x7ffaa2c82354 → sudoers_policy_main(argc=<optimized out>, argv=<optimized out>, pwflag=0x0, env_add=<optimized out>, verbose=0x0, closure=0x7fffb7529fe8)
[#4] 0x7ffaa2c7d65e → sudoers_policy_check(argc=0x7, argv=0x55e3c33bc570, env_add=0x0, command_infop=0x7fffb752a080, argv_out=0x7fffb752a0b8, user_env_out=0x7fffb752a0a0, errstr=0x7fffb752a180)
[#5] 0x55e3c0d245db → policy_check(argc=0x7, argv=0x55e3c33bc570, env_add=0x0, command_info=0x7fffb752a080, argv_out=0x7fffb752a0b8, user_env_out=0x7fffb752a0a0)
[#6] 0x55e3c0d245db → main(argc=<optimized out>, argv=<optimized out>, envp=0x7fffb752b2b8)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────