Reputation: 271
I'v read that to make a successful return to lib-c attack, the attacker should store the address of the command (for example "bin/sh") on the stack exactly after the return address to 'system' function (for example).
So as the 'system()' function reads that address as its 'parameter' and executes that command. But now after disassembling a program which calls system() I noticed that it doesn't use the stack to get the address of that string ("bin/sh"). Instead the address is stored in EDI or RDI registers. As long as the attacker can't access the registers how is it possible to perform such an attack?
Upvotes: 2
Views: 692
Reputation: 18326
It might actually be easy for an attacker to have the correct value stored in RDI
without having direct access to the registers.
Take a typical vulnerable C function that might lead to a return-to-libc attack:
void f(const char* str)
{
char buf[BUF_LEN];
strcpy(buf, str);
}
On my machine, the following assembly is generated for the call to strcpy
:
movq %rdi, -24(%rbp)
movq -24(%rbp), %rdx
leaq -16(%rbp), %rax
movq %rdx, %rsi
movq %rax, %rdi
call strcpy
As you can see, the destination buffer of strcpy
, which is the vulnerable buffer, is stored in RDI
. This means that if we manage to overwrite the return address with the address of system
, it will be called with a pointer to the vulnerable buffer as its argument.
A small disclaimer: this particular example is just to illustrate that having the correct value in a register can be accomplished by other ways than having direct access to the register. The example itself is actually very difficult to exploit since strcpy
will stop after the first null byte.
Upvotes: 2