10 Stack Hacking - Wellesley College

6 downloads 1166 Views 119KB Size Report
Nov 13, 2012 ... 13, 2012. Wellesley College. Lecture 19: Stack Hacking ... the following steps: lynux@cs342-ubuntu-1:~/stack-hacking$ gcc -c print_stack.c.
CS342 Computer Security Prof. Lyn Turbak Wellesley College

Handout # 20 Mar. 30, 2016

Lab 9: Stack Hacking Today, you will use your low-level knowledge of stack frame conventions to exploit the hackme.c program in Figure 1. Although this program is contrived, it will give you practice parsing the stack and changing values on the stack, including return addresses and base pointers. This is good preparation for our next topic: stack buffer overflows. /* A program that hints at issues involving stack buffer overlow exploits */ /* Compile this as : gcc -o hackme print_stack . o hackme . c */ # include < stdio .h >

// Headers that include types of printf and scanf

int sq ( int x ) { return x * x ; } int getelt ( int * a ) { char c ; // Store character read in read - eval - print loop ( REPL ) int i ; // Stores index read in REPL int prev = 0; // Stores previous value of a [ i ] in REPL // BEGIN REPL printf ( " Enter a character ( ’ r ’ = return ; ’g ’ = get ; ’s ’ = set ; ’p ’ = print stack ) : "); scanf ( " % c " , & c ) ; while ( c != ’r ’) { if ( c == ’p ’) { // print stack print_stack () ; } else if (( c != ’g ’) && ( c != ’s ’) ) { printf ( " unrecognized character ’% c ’\ n " , c ) ; } else { printf ( " Enter an index : " ) ; scanf ( " % i " , & i ) ; if ( c == ’g ’) { // get element at a [ i ] printf ( " getting a [% i ]: % i \ n " , i , a [ i ]) ; } else if ( c == ’s ’) { printf ( " setting a [% i ] to % i \ n " , i , prev ) ; a [ i ] = prev ; // set element at a [ i ] to previous value } prev = a [ i ]; } // Continue REPL printf ( " Enter a character ( ’ r ’ = return ; ’g ’ = get ; ’s ’ = set ; ’p ’ = print stack ) : " ) ; scanf ( " \ n % c " , & c ) ; // \ n consumes newline from index entry } return a [0]; // Always returns a [0] when REPL terminates } int process ( int * a ) { return sq ( getelt ( a ) ) ; // Return the square of the array element returned by getelt . } int main ( int argc , char ** argv ) { int a [3] = {5 ,10 ,15}; // Initialize array a . printf ( " ***** ANS = % i *****\ n " , process ( a ) ) ; // Print result of processing array a }

Figure 1: The contents of hackme.c.

1

Setup The following problems involve playing with the hackme program. Do your work on your CS342 Ubuntu VM. Begin by cding to the ~wendy/cs342 folder and downloading the stack-hacking folder: scp -r gdome@cs . wellesley . edu :/ home / cs342 / download / stack - hacking .

In this directory, perform the following steps to create the hackme executable: wendy@cs342 - ubuntu -1:~/ cs342 / stack - hacking$ gcc -c print_stack . c wendy@cs342 - ubuntu -1:~/ cs342 / stack - hacking$ gcc -o hackme print_stack . o hackme . c

Problems Problem 1 What does the program do when the r option is chosen? Problem 2 What do the g and s options of the program do? How can these be used to square some numbers other than 5? For example, get the program to print 100 and 225. Problem 3 This problem explores the p option. Perform the following steps first: • Invoke the hackme program as follows: hackme a bc def • Use the g option to get array element 2 • Use the s option to set array element 0 • Use the p option to print out the stack. a The print stack utility uses dotted lines to indicate the boundaries of stack frames. (You already know how to find these on your own.) Figure out which function call created each frame. b Where are the variables c, i, and prev stored in the frame for getelt? c What is the memory address of the array a allocated in the main function? d Explain which lines of code in hackme.c the return addresses on the stack correspond to. (You can use gdb to verify your answers.) e Where are argn and argv located on the stack? Where are the characters in the argv strings stored? Where is the pointer to the shell environment? Where are the characters of the shell environment bindings stored? f If you invoke hackme a bc def again, are the stack addresses the same or not? Why? Problem 4 Explain how to use the hackme program to display the square of any positive integer. For example, show how to invoke hackme and its interpreter to display 10002 . Hint: using perl -e and backquotes are helpful here, as explained in the section Perl and Backquote Notes below. For example: hackme ‘ perl -e ’ print " a " x100 ; ’ ‘

invokes hackme with 100 arguments, all of which are the string a. Problem 5 By overwriting return addresses and base pointers, you can get hackme to display any positive integer. Demonstrate this by showing how to invoke hackme and its interpreter to display 1000. Problem 6 You can actually manipulate hackme to display any integer, including negative ones. Demonstrate this by showing how to invoke hackme and its interpreter to display (1) −1 and (2) the integer with hex representation 0xfedcba98. Hint: what is the hex representation of -1? How can we use Perl and backquotes when invoking hackme to inject these hex bytes into a word somewhere on the stack? 2

Perl and Backquote Notes The Perl language interpreter is very useful for hacking, because it provides an easy way in Linux to create replicated strings and strings with characters specified in hex. Here are some examples: wendy@cs342-ubuntu-1:~\$ perl -e ’print "ABC"x10;’ ABCABCABCABCABCABCABCABCABCABCwendy@cs342-ubuntu-1:~\$ wendy@cs342-ubuntu-1:~\$ perl -e ’print "ABC"x10 . "DEF"x2 . "\n";’ ABCABCABCABCABCABCABCABCABCABCDEFDEF wendy@cs342-ubuntu-1:~\$ perl -e ’print "a "x10 . "\n";’ a a a a a a a a a a wendy@cs342-ubuntu-1:~\$ perl -e ’print "\x61\x62\x63\x64"x4 . "\n";’ abcdabcdabcdabcd wendy@cs342-ubuntu-1:~\$ perl -e ’print "\x41\x42\x43\x44"x5 . "\n";’ ABCDABCDABCDABCDABCD

In the Linux shell, text between a pair of backquotes (grave accents) is treated as a command that is executed, and the text it produces is substituted for the backquoted expression. wendy@cs342-ubuntu-1:~\$ echo "wc" > stuff wendy@cs342-ubuntu-1:~\$ echo ‘cat stuff‘ wc wendy@cs342-ubuntu-1:~\$ echo ‘cat stuff‘‘cat stuff‘‘cat stuff‘ wcwcwc wendy@cs342-ubuntu-1:~\$ ‘cat stuff‘ stuff 1 1 3 stuff wendy@cs342-ubuntu-1:~\$ ‘cat stuff‘ ‘cat stuff‘ wc: wc: No such file or directory wendy wendy@cs342-ubuntu-1:~\$ ‘cat stuff‘ shellcode 0 3 49 shellcode

We can combine Perl and backquotes to call command with arguments that would otherwise be difficult to express. For example, to invoke hackme with 1000 arguments, each of which is the string a, we can use: ./hackme ‘perl -e ’print "a "x1000;’‘

Note that this example contains three different kinds of matched quote pairs: backquotes, single quotes, and double quotes. They must be exactly right in order for this to work.

3