EC312 Security Exercise 5

advertisement
EC312 Security Exercise 5
Part 1: Initial Setup
Your instructors have prewritten two C programs that you will use for this lab, and have placed them in the
ec310code directory. The two programs you will use today are named sx5a.c and sx5b.c .
Copy these two files from the ec310code directory to the work directory by carefully entering the following
two lines at the home directory prompt:
midshipman@EC310:~ $
cp
ec310code/sx5a.c
work
midshipman@EC310:~ $
cp
ec310code/sx5b.c
work
Make sure you are at your
home directory!
Enter this!
If all went well, you should have copies of sx5a.c and sx5b.c in your
work directory. Verify that you have sx5a.c and sx5b.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 sx5a.c and sx5b.c in in your work directory
tech for help. Otherwise, proceed to Part 2.
STOP and ask your instructor or lab
Part 2: Go Navy
You should now be in the work directory:
Examine the program sx5a.c using nano. The C program is shown below:
#include<stdio.h>
#include<string.h>
int main( )
{
char phrase[ 10 ] = "Go Navy!" ;
printf( "%s\n" , phrase );
}
Save your program ( Control-o ) and exit nano ( Control-x) and then compile your program using
gcc –g sx5a.c
and then run your program: ./a.out . If your program is not working as expected
instructor for help. Otherwise, proceed to Part 3.
1
STOP and ask your
Part 3: Memory
Question 1: The array named phrase is a string, and the contents of this string are stored in main
memory on the program's stack. We would like to determine the starting address of the string.
By using nano, change only a single character in statement
printf( "%s\n" , phrase );
to determine the main memory address of where the string named phrase begins. Compile and
execute your program.
Question 2: How many bytes of memory are required to hold a single character?
Question 3: Looking at your source code, what character should be stored at phrase[ 1 ] ?
Question 4: Looking at your source code, what character should be stored at phrase[ 8 ] ?
Question 5. Complete the printf statement that would allow you to see the address of the character
stored at phrase[1] (don't actually make the change using nano, just state what you would do):
printf(
"The address of phrase[1] is %x " ,
______________ ) ;
Question 6: Sketch how your array should be stored in memory in the picture shown on your answer
sheet. Each box represents a byte in memory. Assume that the array named phrase points to the
location shown, and that memory locations are increasing going down the page. For this question all
you need to do is fill in the ASCII characters that are stored in each memory location.
If, in answering Question 1 above, you made a modification to your program, restore the program to its
original form as shown on page 1.
2
Carefully modify your C program (using nano) so that it contains the three new lines shown in bold italics:
#include<stdio.h>
#include<string.h>
int main( )
{
char phrase[ 10 ] = "Go Navy!" ;
Add these two lines. (You can
also add blank lines around
these two new lines if you wish.)
char *ptr;
ptr = phrase;
printf( "%s\n" , phrase );
Add this line. (Also add blank
lines if you wish.)
printf( "%s\n" , ptr );
}
Compile and execute your program, examining the output. If your program is not compiling
your instructor for help. Otherwise, proceed to Part 4.
STOP and ask
Part 4: Go Navy Navy
Recall that phrase, the name of an array, is really a pointer to an array of characters. In fact, phrase holds
the address of the first element of the array. And the variable ptr is also a pointer.
Question 7: The line of code
ptr = phrase;
is an assignment statement. What is being assigned to what?
Question 8: Explain your program's output.
Carefully modify your C program so that it contains the three new lines shown in bold italics:
#include<stdio.h>
#include<string.h>
int main( )
{
char phrase[ 10 ] = "Go Navy!" ;
char *ptr;
ptr = phrase;
Add this line.
char *another_ptr;
printf( "%s\n" , phrase );
printf( "%s\n" , ptr );
another_ptr = ptr + 3 ;
printf( "%s\n" , another_ptr );
Add these two lines.
}
Compile and execute your program. If your program is not compiling
help. Otherwise, proceed to Part 5.
3
STOP and ask your instructor for
Part 5: Army Strikes Back
Question 9: Explain your program's output.
Question 10: In the same sketch as Question 6, fill in:
•
•
the location where ptr points to.
the location where another_ptr points to.
Carefully modify your C program to add the two new lines shown in bold italics (do not worry about the
presence or absence of blank lines in your code):
#include<stdio.h>
#include<string.h>
int main( )
{
char phrase[ 10 ] = “Go Navy!” ;
char *ptr;
ptr = phrase;
char *another_ptr;
printf( "%s\n" , phrase );
printf( "%s\n" , ptr );
another_ptr = ptr + 3 ;
printf( "%s\n" , another_ptr );
strcpy( another_ptr , "Army!" );
printf( "%s\n" , ptr );
Add these two lines.
}
Recall that the strcpy command provides a means for changing the values of the characters stored in a string.
Ensure that you use strcpy to change another_ptr , not ptr (see the code above).
Note that we then, in the last line of code, use ptr in the printf command.
Compile and execute your program, examining the output.
Question 11: Explain the last line of output produced by the program. Specifically, why did the value
of the string named ptr change (as reflected by the last line of output) when all you did using the
strcpy command was change a different string (the string named another_ptr). Phrasing this
question another way: Your program above never directly changes ptr after the line
ptr = phrase;
but—somehow—the value printed out by the last line reflects a change. What caused this?
If you are baffled,
STOP and ask your instructor for an explanation. Otherwise, proceed to Part 6.
4
Part 6: Autopsy of the Program
Recall that when we execute a program, it is moved from secondary memory (e.g., the hard disk) to main
memory (RAM). The particular program's machine language code is moved into main memory, and the
program is also given additional space in main memory (called the stack) that it can use to store variable values
that it needs to execute.
In the figure shown below, the machine language code has been moved into main memory starting at address
0x08048374 and the program's stack is between memory locations 0xbfffff71 and 0xbfffff73.
Note that our program is not "stored in the CPU." Rather, the program is stored in main memory.
The CPU can interact with the program via the three registers that we have learned about:
•
The eip register holds the address of the next instruction that will be executed (but has not yet been
executed).
•
The esp register points to the "top" of the stack.
•
The ebp register points to the bottom of the stack.
Note in the figure above the values of the eip, esp and ebp registers.
5
Now, the gdb debugger can be thought of as a microscope that allows us to examine in detail the CPU registers
and memory.
We have seen that we can use the info command to examine registers. For example, in the context of the figure
above, if I entered
i r eip
I should obtain the value of 0x08048374.
Similarly, if I entered
x/xb
0x08048374
I should see the value 0x55.
We will examine a program using the debugger, and show in particular how we can use the names of pointer
variables in debugger commands. And at the end of this Security Exercise (no peeking!) we will show you a
useful enhancement to the examine command.
6
Enough of program sx5a.c . I'm sure you are sick of that program! Let's move on to sx5b.c !!! Using
nano examine the program sx5b.c . The C program is shown below:
#include<stdio.h>
#include<string.h>
int main( )
{
char phrase[ 10 ] = "Go Navy!" ;
char *ptr;
ptr = phrase;
char *another_ptr;
printf( "%s\n" , phrase );
printf( "%s\n" , ptr );
another_ptr = ptr + 3 ;
printf( "%s\n" , another_ptr );
strcpy( another_ptr , "Army!" );
printf( "%s\n" , ptr );
}
Note that this is the same program that you left off with, but we have cleaned it up (e.g., to remove unnecessary
blank lines). DO NOT MAKE ANY CHANGES TO THIS PROGRAM!
Let’s use the debugger to examine the program on the top of this page a bit more closely. Type the following at
the prompt. Do not type the comments!
gcc –g sx5b.c
gdb –q
// The –g provides extra functionality for the debugger.
// Recall that gdb is the name of the debugger.
./a.out
set dis intel
// This displays the assembly code in standard Intel lingo
list
// This repeats the source code for convenience
<Enter>
// Just hit the Enter key. This displays the remainder of your source code
break 13
// This sets a “breakpoint” at line 13. This is the next to last line of your
// program – the line that uses strcpy.
run
// This starts executing the program up to the breakpoint.
After entering all of these commands, your program will have executed up to but not including line 13. Line 13
is the next to last line of your program – the line that uses strcpy.
Let's find out the address that phrase holds (remember, the name of an array such as phrase holds the
address of the first element in the array). We would also like to know actual contents of this address.
Let’s do this by typing
x/xb phrase
You should see:
(gdb) x/xb phrase
0xbffff800:
0x47
7
(Note: You may see a number slightly different from 0xbffff800, but you should see the value of 0x47. If
you do not see the value of 0x47 then
STOP and ask your instructor for help.)
Let's explain the command you just entered. Recall that the first x invokes the examine command, the second x
specifies hexadecimal, and the b asks the debugger to display a single-byte quantity. When the examine
command is used with array names or pointer variables (such as phrase, ptr and another_ptr), the first
item returned will be the contents of the pointer and the second item returned will be the value that the pointer is
pointing to.
(gdb) x/xb phrase
0xbffff800:
0x47
The address stored
in phrase.
The memory contents of this
specific address.
Question 12. Fill in the picture shown on the answer sheet, showing the contents of phrase, and the
hexadecimal value stored in the memory location pointed to by phrase. (Note that this figure will be
gradually filled in as we complete this lab; for this question, you are only being asked to show the
contents of phrase, and the value stored in the memory location pointed to by phrase.)
Question 13. What on earth does that 0x47 represent?
Question 14. Determine what is stored at the memory location that phrase contains by examining the
memory directly using the command:
x/xb 0xbffff800
Question 15. On the same figure as Question 12, fill in the contents of ptr and another_ptr.
These are both pointers so your answers should be addresses.
Question 16. On the same figure as Question 12, draw arrows showing where phrase, ptr and
another_ptr all point to; i.e., draw an arrow from the pointer to the memory location with the
corresponding address.
Question 17. On the same figure as Question 12, show the hexadecimal values stored in the memory
locations pointed to by these three pointers phrase, ptr and another_ptr.
Question 18. The pointer named another_ptr seems to be pointing to the value 0x4e. What is that?
Question 19. On the same figure as Question 12, fill in the addresses of each byte of main memory
depicted on the figure, and fill in the contents of each memory location as ASCII characters. You
should do this by using the debugger to examine memory one byte at a time. For example, if I wanted to
examine the memory location 0xbffff801 I would enter
x/xb 0xbffff801
When you have completed your picture,
to Part 7.
STOP and show it to your instructor.
8
If correct, you can proceed
Part 7: Autopsy of the Program
Recall that our program has executed up to but not including line 13. Line 13 is the next to last line of your
program – the line that uses strcpy.
Now, execute the program (using nexti ) until you show line 14 as the next instruction to execute. In other
words, keep entering nexti until you see:
14
printf( "%s\n" , ptr );
It should be the case that you have to enter nexti four times to see the line shown above.
Question 20. Fill in the picture shown on the answer sheet in its entirety, showing the memory address
of all bytes, the contents of all bytes (as ASCII characters) and the contents of the pointers.
Now, the C line of code:
printf( "%s\n" , ptr );
goes to the memory address pointed to by ptr, and starts printing out characters in memory, one after another,
until a NULL is reached.
Question 21. What will be printed out by the next statement (printf( ptr ); )?
Question 22. You friend is confused. He says: “We never made any changes involving ptr – we only
made changes to another_ptr (using the strcpy command).” So, why did we get different results
when we executed the line printf( ptr ); ? How do you reply?
We can type out multiple bytes with a single x/xb command by specifying the number of bytes to display.
For example, we can print out a single byte starting at the address pointed to by phrase by typing
x/xb phrase
But, if we want to see, say, 8 bytes of data starting at the address pointed to by phrase, we can type
x/8xb phrase
Question 23. Explain the meaning of the results that you see when you enter x/8xb phrase.
Question 24. Explain the meaning of the results that you see when you enter x/8c phrase.
9
10
Security Exercise 5
Name: _____________________
Question 1:
Question 2:
Question 3:
Question 4:
Question 5:
Question 6 and Question 10:
Question 7:
Question 8:
Question 9:
Question 11:
11
Question 12, Question 15, Question 16, Question 17, Question 19
Question 13:
Question 14:
Question 18:
Question 20:
Question 21:
Question 22:
Question 23:
Question 24:
12
Download