For the first three phases, your exploit strings will attack CTARGET.
This program is set up in a way that the stack positions will be consistent from
one run to the next and so that data on the stack can be treated as executable code.
These features make the program vulnerable to attacks where the exploit strings
contain the byte encodings of executable code.
For Phase 1, you will not inject new code. Instead, your exploit string will redirect the program to execute an existing procedure.
The function getbuf is called within CTARGET
by a function test having the following C code:
void test()
{
int val;
val = getbuf();
printf("No exploit. Getbuf returned 0x%x\n", val);
}
When getbuf executes its return statement (line 5 of
getbuf), the program ordinarily resumes execution within function
test (at line 5 of this function). We want to change this behavior.
Within the file ctarget, there is code for a function touch1
having the following C representation:
void touch1()
{
vlevel = 1; /* Part of validation protocol */
printf("Touch1!: You called touch1()\n");
validate(1);
exit(0);
}
Your task is to get CTARGET to execute the code for
touch1 when getbuf executes its return
statement, rather than returning to test. Note that
your exploit string may also corrupt parts of the stack not directly
related to this stage, but this will not cause a problem, since
touch1 causes the program to exit directly.
Some Advice:
CTARGET. Use objdump -d
to get this dissembled version.touch1 so that the ret instruction at the end
of the code for getbuf will transfer control to touch1.gdb to step the program through
the last few instructions of getbuf to make sure it is
doing the right thing.gdb to step the program through the last
few instructions of getbuf to make sure it is doing the right thing.buf within the stack frame for getbuf
depends on the value of compile-time constant BUFFER_SIZE, as well the
allocation strategy used by GCC. You will need to examine the
disassembled code to determine its position.
Phase 2 involves injecting a small amount of code as part of your exploit string.
Within the file ctarget there is code for a function touch2
having the following C representation:
void touch2(unsigned val)
{
vlevel = 2; /* Part of validation protocol */
if (val == cookie) {
printf("Touch2!: You called touch2(0x%.8x)\n", val);
validate(2);
} else {
printf("Misfire: You called touch2(0x%.8x)\n", val);
fail(2);
}
exit(0);
}
Your task is to get CTARGET to execute the code for touch2 rather
than returning to test. In this case, however, you must make it appear to
touch2 as if you have passed your cookie as its argument.
Some Advice:
ret instruction at the end of the code for
getbuf will transfer control to it.%rdi.ret instruction to transfer control to the first instruction in
touch2.jmp or call instructions in your
exploit code. The encodings of destination addresses for these instructions are
difficult to formulate. Use ret instructions for all transfers of
control, even when you are not returning from a call.Phase 3 also involves a code injection attack, but passing a string as argument.
Within the file ctarget there is code for functions hexmatch
and touch3 having the following C representations:
/* Compare string to hex represention of unsigned value */
int hexmatch(unsigned val, char *sval)
{
char cbuf[110];
/* Make position of check string unpredictable */
char *s = cbuf + random() % 100;
sprintf(s, "%.8x", val);
return strncmp(sval, s, 9) == 0;
}
void touch3(char *sval)
{
vlevel = 3; /* Part of validation protocol */
if (hexmatch(cookie, sval)) {
printf("Touch3!: You called touch3(\"%s\")\n", sval);
validate(3);
} else {
printf("Misfire: You called touch3(\"%s\")\n", sval);
fail(3);
}
exit(0);
}
Your task is to get CTARGET to execute the code for touch3
rather than returning to test. You must make it appear to touch3
as if you have passed a string representation of your cookie as its argument.
Some Advice:
0x”.man ascii” on any Linux machine to see
the byte representations of the characters you need.%rdi to the address of this string.hexmatch and strncmp are called, they push
data onto the stack, overwriting portions of memory that held the buffer used by
getbuf. As a result, you will need to be careful where you place the string
representation of your cookie.