EC312 Security Exercise 6 Part 1. Initial Setup Today you will use the program sx6.c which has been written for you and placed in the ec310code directory. Copy this file to the work directory by carefully entering the following at the home directory prompt: midshipman@EC310:~ $ cp ec310code/sx6.c Make sure you are at your home directory! work Enter this! Verify that you have sx6.c in your work directory by changing to the work directory: cd work and then listing the files in the work directory: ls If you do not have sx6.c in your work directory or lab tech for help. Otherwise, proceed to Part 2. STOP and ask your instructor Part 2. Our Program for Today Look at the program sx6.c using nano. The program sx6.c is shown below: void test_function( int a, int b, int c, int d) { int flag; char buffer[ 10 ]; flag = 31337; buffer[ 0 ] = ‘A’ ; } int main( ) { test_function( 1, 2, 3, 4 ) ; } Note that to make this first exploration of the stack as simple as possible, we did NOT include the line #include<stdio.h> in our program. 1 This is okay, since we do not use any input (scanf) or output (printf) statements. 1 This program is a very slightly modified version of the program named stack_example.c from page 71 of the Erickson text. We have modified the layout of the braces to the form we are familiar with. 1 Note that this program produces no output. It truly is a useless program… but it’s simple enough to explore the stack for the first time. Question 1: How many functions are in the program? Save your program ( Control-o ) and exit nano ( Control-x) and then compile your program using gcc –g sx6.c and then run your program ./a.out to confirm it executes without errors. (The program does not produce any output—you are just making sure you do not get any error messages.) If your program is not working Otherwise, proceed to Part 3. STOP and ask your instructor for help. Part 3. The Two Functions in Memory Question 2: Note that the function named test_function is passed four arguments: 1, 2, 3 and 4. How much memory (in bytes) does each of these four arguments need? Question 3: How much memory (in bytes) is needed to store test_function ‘s flag variable? Question 4: How much memory (in bytes) is needed to store test_function ‘s array named buffer? Let’s examine how the main function is stored in memory. Enter: gdb –q ./a.out set dis intel disass main You should see this: 2 Recall that the assembly language code above corresponds to the main function, repeated below: int main( ) { test_function( 1, 2, 3, 4 ) ; } Question 5: Where in main memory is the first instruction that starts the main function? Now let’s examine how the function named test_function is stored in memory. Enter: disass test_function You should see this: Question 6: Where in main memory is the first instruction that starts the function named test_function? So… what’s really going on? To answer this, we will look at the stack frame for each of our two functions. Onward to Part 4! Part 4. The Stack Frame for main Let’s set a breakpoint in main right before the call to test_function. Enter the following commands: list main break 11 run This is line 11. So, the command break 11 You should see: will run our program to the point of this line (but not including this line!). That means that our program will pause right before the call to the function named test_function. 3 Question 7: What address is stored in the instruction pointer (i.e., the eip register)? Go back to the assembly code for main (at the bottom of page 2). Question 8. Based on your answer to question 7, what is the assembly language instruction that the instruction pointer is pointing to? Is this still in the main function? So, let's start looking at the stack! Recall that the stack is the area in main memory that the program has available to store any values that it needs for successful execution (such as variables, arguments, important addresses, etc.). The active part of the stack is bounded by the two registers esp and ebp. Question 9: What are the addresses stored in the stack pointer (esp) and the base pointer (ebp) ? Question 10. Considering the values of esp and ebp, how many bytes are in this stack frame? (Hint: you must remember that these values are in hexadecimal! Recall that esp points to the first address in the stack frame and ebp points to the first address after the stack frame. Thus, subtracting the address pointed to by esp from the address pointed to by ebp provides the number of bytes in the stack frame.) Question 11: In the picture of memory shown on your answer sheet, note that the base pointer points to the bottom of the stack. • Fill in the addresses next to each byte (for ease, you may, if you wish, label only the last four hexadecimal digits of each address). • Indicate on the diagram where the stack pointer is pointing to. Now, looking at where the instruction pointer is pointing to, the next four instructions that should be executed are (but don’t actually execute these just yet): mov mov mov mov DWORD DWORD DWORD DWORD PTR PTR PTR PTR [esp+12],0x4 [esp+8],0x3 [esp+4],0x2 [esp],0x1 4 In English, the first of these instructions says: Place the value 4 in the memory location given by esp + 12 (i.e., the stack pointer + 12). Note that the 12 in this case is given in base-10. Similarly, the second of these instructions says: Place the value 3 in the memory location given by esp + 8 (i.e., the stack pointer + 8). Note that the 8 in this case is given in base-10. Question 12: Modify the diagram shown in Question 11 to show what the stack should look like after these four instructions are executed. Remember that an integer (such as 4) takes up four bytes. Enter nexti four times to execute these four assembly language instructions. Now, examine the stack to see if the picture you drew in Question 12 is correct. Examine the stack? How do we do that? Well, to examine the word stored at the address contained in the stack pointer, we can enter: x/xw $esp To examine the word stored at the address four bytes later, we can enter: x/xw $esp + 4 And so forth. As an alternative, you could use x/xw followed by the address you want to examine. For instance, to examine the word that is stored at the address 0xbffff80c I would enter: x/xw 0xbffff80c. Show your instructor your answer to Questions 11-12. If you are on the right track, you will be told to move on to Part 5! Part 5. The Stack Frame for test_function So, we will soon jump to the function named test_function. As we discussed in lecture, this will establish a new stack frame. After the function named test_function is done, we have to be able to return to main's stack frame. To return to the main function, main must save on the stack: • • The proper return address for eip The prior value of the base pointer ebp Let's first establish what these values should be. 5 Question 13: What is the old (prior) value of the base pointer that must be saved on the stack? Look carefully at the assembly language code for main shown on page 4. Question 14: What is the value of the return address that we must save, so that the instruction pointer can be reset back to the correct line of code after the function call to test_function is complete? Let's jump into the function named test_function. Enter: list test_function break 8 continue You should see: Notice that by inserting a breakpoint at line 8, we are within (but at the end of) test_function. Question 15: What address is stored in the instruction pointer (i.e., the eip register)? Question 16. Based on your answer to Question 15, what is the assembly language instruction that the instruction pointer is pointing to (i.e., the next instruction that will execute, but has not yet executed)? Question 17: What are the addresses stored in the stack pointer (esp) and the base pointer (ebp) ? Question 18. Considering the values of esp and ebp, how many bytes are in this stack frame? (Hint: you must remember that these values are in hexadecimal!) Show your instructor your answer to Questions 17-18. If you are on the right track, you will be told to move on to Part 6! 6 Part 6: Do you have the skills of a hacker? Now you will be put to the test! Have you developed hacking skills? Let’s see! Question 19: Using all the skills you have learned so far, attempt to determine the contents of the stack frame for test_function as well as the additional memory locations below the base pointer. Fill in your answers on the picture for Question 19. The arrow on the figure shows where you should place the base pointer (ebp). All other info should be based upon anchoring the base pointer at the location shown. Specifically: • Show the address for each byte (last four hex digits) • where is flag? (Hint: convert the value to hexadecimal) • Where is buffer? (Hint: You should hunt for buffer[0] ) • Where is the return address (see your answer to Question 14)? • Where is the old value of the base pointer (see your answer to Question 13)? 7 8 Security Exercise 6 Name: __________________ Question 1: Question 2: Question 3: Question 4: Question 5: Question 6: Question 7: Question 8: Question 9: Question 10: Question 11 and Question 12: 9 Question 13: Question 14: Question 15: Question 16: Question 17: Question 18: Question 19 is on the next page. 10 11