I'm trying to implement simple example of Format String Vulnerability in C on 64-bits Linux. Here is my source code:
void not_called() {
printf("Exploited\n");
}
int main(int argc, char **argv) {
// Buffer overflow vulnerability
char buffer[256];
gets(buffer);
// User may input the format string
printf(buffer);
}
I input the following string to program
AAAABBBB-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x
And the result is
AAAABBBB-8608002c-f458fe00-fbad2288-78252d78-252d7825-5e5c51a8-0-41414141-2d78252d-78252d78-252d7825-2d78252d
I can spot the AAAA as 41414141
but not the BBBB following as I would expect, as it's integral part of the same input string in the buffer.
Is this some sort of protection mechanism or am I misinterpreting something? My goal is to overwrite return address, and I need to read 8 bytes (AAAABBBB) as I'm working on 64-bits machine.
Pseudo-code for exploit string would look something like this
RETRNPTR%[decimal address of not_called - 8]u%[offset of RETRNPTR]$n
RETRNPTR is the address of memory storing the return address in the current stack frame.
So my biggest concern is, 8 bytes of RETRNPTR doesn't seem to be continuously in memory as I would expect. Second concern is, %n is int-pointer, meaning only 4 bytes are written. I'm also confused, where those values preceding the AAAA are coming from.
First of all, you're asking about code that has undefined behaviour; the behaviour of the code indeed should for the most of the part considered undefined by a casual C programmer.
Now, as to why you do not see BBBB
. I presume it is because you're running this program on x86-64 system. There the calling convention is to do 64-bit pushes for the values that go on stack; However %x
prints a 32-bit int
; the 32 least significant bits of 64-bit stack value. To print 64-bit long
values use %lx
.
(Also, on System-V API for x86-64 the 6 first integer/pointer arguments do not go on stack at all; they're in RDI
, RSI
, RDX
, RCX
, R8
, and R9
registers).
For example I entered:
AAAABBBB %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx
and got output
AAAABBBB 7f7c0a88f030 7f7c0a66b980 7f7c0a669980 7f7c0a88f031 786c2520786c2520 7ffc1456b6f8
100000000 4242424241414141 786c2520786c2520 786c2520786c2520