Phase 2: Injecting Some Code
In Phase 1, you forced getbuf to return to the touch1 function
instead of returning to the test function it was called from.
Phase 2 is similar, but this time you'll be injecting a small amount of code as part of your exploit string.
As a reminder, here's the code for getbuf,
1 2 3 4 5 6 | |
and for test:
1 2 3 4 5 6 | |
ctarget includes a function called touch2 with 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
instead of returning to test. To do so, you must make it appear
to touch2 as if you have passed your cookie in as its argument.
Hints
-
You will want to position a byte representation of the address of your injected code in such a way that the
retinstruction at the end of the code forgetbufwill transfer control to it. -
Recall that the first argument to a function is passed in register
rdi. -
Your injected code should set the register to your cookie, and then use a
retinstruction to transfer control to the first instruction intouch2. -
Do not attempt to use
jmporcallinstructions in your exploit code. The encodings of destination addresses for these instructions are difficult to formulate. Useretinstructions for all transfers of control, even when you are not returning from a call. -
See Generating Byte Codes on how to use tools to generate the byte-level representations of instruction sequences.
-
There is a
-qflag toctargetthat stops the program from talking to the grading server. -
There is an
-ioption tofile ctargetthat tells it to read from a file namedinstead of fromfile stdin.
(When logged in, completion status appears here.)