Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
CNIT 127: Exploit Development



Ch 2: Stack Overflows in Linux
Stack-based Buffer Overflows
• Most popular and best understood
exploitation method
• Aleph One's "Smashing the Stack for Fun
and Profit" (1996)
– Link Ch 2a
• Buffer
– A limited, contiguously allocated set of
memory
– In C, usually an array
C and C++ Lack Bounds-Checking
• It is the programmer's responsibility to ensure
that array indices remain in the valid range
#include <stdio.h>
#include <string.h>
int main() {
int array[5] = {1, 2, 3, 4, 5};
printf("%dn", array[5]);
}
Using gdb (GNU Debugger)
• Compile with symbols
– gcc -g -o ch2a ch2a.c
• Run program in debugger
– gdb ch2a
• Show code, place breakpoint, run to it
– list
– break 7
– run
• Examine the memory storing "array"
– x/10x &array
Reading Past End of Array
CNIT 127 Ch 2: Stack overflows on Linux
Reading Past End of Array
• array[5] = 0xb7fb63c4
Writing Past End of Array
Compile and Run, Crash
Debug
• Open in debugger
– gdb ch2b
• Run
– run
• Examine the memory storing "array"
– x/50x &array
CNIT 127 Ch 2: Stack overflows on Linux
Buffer Overflow
• Many RAM locations now contain 0xa
• But why, precisely, did that cause a crash?
Debug
• Examine registers
– info registers
• Examine assembly code near eip
– x/10i $eip-10
10 (0xa) is not in any register
Last Command Writes $0xa to RAM
• Evidently we went so far we exited the
RAM allocated to the program
Intel v. AT&T Format
• gdb uses AT&T format by default, which is
popular with Linux users
– mov source, destination
• Windows users more commonly use Intel
format
– MOV DESTINATION, SOURCE
Jasmin
Assembly Language Simulator
CNIT 127 Ch 2: Stack overflows on Linux
The Stack
LIFO (Last-In, First-Out)
• ESP (Extended Stack Pointer) register
points to the top of the stack
• PUSH puts items on the stack
– push 1
– push addr var
Stack
• POP takes items off the stack
– pop eax
– pop ebx
EBP (Extended Base Pointer)
• EBP is typically used for calculated
addresses on the stack
– mov eax, [ebp+10h]
• Copies the data 16 bytes down the stack
into the EAX register
Functions and the Stack
Purpose
• The stack's primary purpose is to make the
use of functions more efficient
• When a function is called, these things occur:
– Calling routine stops processing its instructions
– Saves its current state
– Transfers control to the function
– Function processes its instructions
– Function exits
– State of the calling function is restored
– Calling routine's execution resumes
Example
Using gdb (GNU Debugger)
• Compile with symbols
– gcc -g -o ch2d ch2d.c
• Run program in debugger
– gdb ch2d
• Show code, place breakpoint, run to it
– list 1,12
– break 9
– break 11
– break 4
CNIT 127 Ch 2: Stack overflows on Linux
Using gdb (GNU Debugger)
• Run to breakpoint after line 9
• run
• Examine registers
– info reg
• Run to breakpoint after line 4
• continue
• Examine registers
– info reg
In main() before calling function()
• esp 0xbffff460
• ebp 0xbffff468 (start of stack frame)
• eip 0x8048414 <main+17>
In function()
• esp 0xbffff430
• ebp 0xbffff450 (start of stack frame)
• eip 0x8048401 <function+6>
Examine the Stack
– x/12x $esp
• Highlight is function()'s stack frame
• Outlined area shows these items
– Return address
– Arguments of function(1,2)
• Next to the left is the original value of $ebp
CNIT 127 Ch 2: Stack overflows on Linux
Using gdb (GNU Debugger)
• Run to breakpoint after line 11
• continue
• Examine registers
– info reg
In main() after calling function()
• esp 0xbffff460
• ebp 0xbffff468
• eip 0x8048420 <main+29>
Functions and the Stack
• Primary purpose of the stack
– To make functions more efficient
• When a function is called
– Push function's arguments onto the stack
– Call function, which pushes the return address
RET onto the stack, which is the EIP at the
time the function is called
Functions and the Stack
– Before function starts, a prolog executes,
pushing EBP onto the stack
– It then copies ESP into EBP
– Calculates size of local variables
– Reserves that space on the stack, by
subtracting the size from ESP
– Pushes local variables onto stack
Functions and the Stack
#include <stdio.h>
void function(int a, int b)
{
int array[5];
}
main()
{
function(1,2);
printf("This is where the

return address pointsn");
}
CNIT 127 Ch 2: Stack overflows on Linux
• <main+3> puts a's value, 1, onto the stack
• <main+5> puts b's value, 2, onto the stack
• <main+7> calls function, which implicitly
pushes RET (EIP) onto the stack
• Prolog
– Push EBP onto stack
– Move ESP into EBP
– Subtract 0x14 from stack to reserve space for array
• leave restores the original stack, same as
– mov esp, ebp
– pop ebp
Stack Buffer Overflow Vulnerability
Compile and Run
Disassemble return_input
Set Breakpoints
• At call to gets
• And at ret
Disassemble main
• Next instruction after the call to
return_input is 0x08048453
Run Till First Breakpoint
• Highlighted values are the saved EBP and
the RET address
Continue and Input 40 Characters
• 30 characters are stored correctly
• Next four overwrite stored EBP with 0x44444444
('DDDD')
• Next four overwrite RET
Examine $eip, Step One Instruction
• x/1i means "Examine one instruction"
• stepi executes one machine language
instruction
Observe Overwritten Registers
• ebp and eip are 0x44444444 = 'DDDD'
Stack Overflow
Controlling eip
• 0x44444444 is invalid and causes the
program to halt
• We can put any valid memory address
there
• However, at the point of the crash we
have returned to main() so we should
choose an instruction in main()
Call to return_input
• 0x0804844e
– stored backwards in a string
– "x4ex84x04x08"
Python Exploit Code
• sys.stdout.write doesn't put a space or
linefeed at end
How to Debug with Arguments

More Related Content

CNIT 127 Ch 2: Stack overflows on Linux

  • 1. CNIT 127: Exploit Development
 
 Ch 2: Stack Overflows in Linux
  • 2. Stack-based Buffer Overflows • Most popular and best understood exploitation method • Aleph One's "Smashing the Stack for Fun and Profit" (1996) – Link Ch 2a • Buffer – A limited, contiguously allocated set of memory – In C, usually an array
  • 3. C and C++ Lack Bounds-Checking • It is the programmer's responsibility to ensure that array indices remain in the valid range #include <stdio.h> #include <string.h> int main() { int array[5] = {1, 2, 3, 4, 5}; printf("%dn", array[5]); }
  • 4. Using gdb (GNU Debugger) • Compile with symbols – gcc -g -o ch2a ch2a.c • Run program in debugger – gdb ch2a • Show code, place breakpoint, run to it – list – break 7 – run • Examine the memory storing "array" – x/10x &array
  • 5. Reading Past End of Array
  • 7. Reading Past End of Array • array[5] = 0xb7fb63c4
  • 8. Writing Past End of Array
  • 10. Debug • Open in debugger – gdb ch2b • Run – run • Examine the memory storing "array" – x/50x &array
  • 12. Buffer Overflow • Many RAM locations now contain 0xa • But why, precisely, did that cause a crash?
  • 13. Debug • Examine registers – info registers • Examine assembly code near eip – x/10i $eip-10
  • 14. 10 (0xa) is not in any register
  • 15. Last Command Writes $0xa to RAM • Evidently we went so far we exited the RAM allocated to the program
  • 16. Intel v. AT&T Format • gdb uses AT&T format by default, which is popular with Linux users – mov source, destination • Windows users more commonly use Intel format – MOV DESTINATION, SOURCE
  • 20. LIFO (Last-In, First-Out) • ESP (Extended Stack Pointer) register points to the top of the stack • PUSH puts items on the stack – push 1 – push addr var
  • 21. Stack • POP takes items off the stack – pop eax – pop ebx
  • 22. EBP (Extended Base Pointer) • EBP is typically used for calculated addresses on the stack – mov eax, [ebp+10h] • Copies the data 16 bytes down the stack into the EAX register
  • 24. Purpose • The stack's primary purpose is to make the use of functions more efficient • When a function is called, these things occur: – Calling routine stops processing its instructions – Saves its current state – Transfers control to the function – Function processes its instructions – Function exits – State of the calling function is restored – Calling routine's execution resumes
  • 26. Using gdb (GNU Debugger) • Compile with symbols – gcc -g -o ch2d ch2d.c • Run program in debugger – gdb ch2d • Show code, place breakpoint, run to it – list 1,12 – break 9 – break 11 – break 4
  • 28. Using gdb (GNU Debugger) • Run to breakpoint after line 9 • run • Examine registers – info reg • Run to breakpoint after line 4 • continue • Examine registers – info reg
  • 29. In main() before calling function() • esp 0xbffff460 • ebp 0xbffff468 (start of stack frame) • eip 0x8048414 <main+17>
  • 30. In function() • esp 0xbffff430 • ebp 0xbffff450 (start of stack frame) • eip 0x8048401 <function+6>
  • 31. Examine the Stack – x/12x $esp • Highlight is function()'s stack frame • Outlined area shows these items – Return address – Arguments of function(1,2) • Next to the left is the original value of $ebp
  • 33. Using gdb (GNU Debugger) • Run to breakpoint after line 11 • continue • Examine registers – info reg
  • 34. In main() after calling function() • esp 0xbffff460 • ebp 0xbffff468 • eip 0x8048420 <main+29>
  • 35. Functions and the Stack • Primary purpose of the stack – To make functions more efficient • When a function is called – Push function's arguments onto the stack – Call function, which pushes the return address RET onto the stack, which is the EIP at the time the function is called
  • 36. Functions and the Stack – Before function starts, a prolog executes, pushing EBP onto the stack – It then copies ESP into EBP – Calculates size of local variables – Reserves that space on the stack, by subtracting the size from ESP – Pushes local variables onto stack
  • 37. Functions and the Stack #include <stdio.h> void function(int a, int b) { int array[5]; } main() { function(1,2); printf("This is where the
 return address pointsn"); }
  • 39. • <main+3> puts a's value, 1, onto the stack • <main+5> puts b's value, 2, onto the stack • <main+7> calls function, which implicitly pushes RET (EIP) onto the stack
  • 40. • Prolog – Push EBP onto stack – Move ESP into EBP – Subtract 0x14 from stack to reserve space for array • leave restores the original stack, same as – mov esp, ebp – pop ebp
  • 41. Stack Buffer Overflow Vulnerability
  • 44. Set Breakpoints • At call to gets • And at ret
  • 45. Disassemble main • Next instruction after the call to return_input is 0x08048453
  • 46. Run Till First Breakpoint • Highlighted values are the saved EBP and the RET address
  • 47. Continue and Input 40 Characters • 30 characters are stored correctly • Next four overwrite stored EBP with 0x44444444 ('DDDD') • Next four overwrite RET
  • 48. Examine $eip, Step One Instruction • x/1i means "Examine one instruction" • stepi executes one machine language instruction
  • 49. Observe Overwritten Registers • ebp and eip are 0x44444444 = 'DDDD'
  • 51. Controlling eip • 0x44444444 is invalid and causes the program to halt • We can put any valid memory address there • However, at the point of the crash we have returned to main() so we should choose an instruction in main()
  • 52. Call to return_input • 0x0804844e – stored backwards in a string – "x4ex84x04x08"
  • 53. Python Exploit Code • sys.stdout.write doesn't put a space or linefeed at end
  • 54. How to Debug with Arguments