Analicé los aspectos básicos de las vulnerabilidades de desbordamiento del búfer e intenté comprender cómo funciona la pila. Para eso quería escribir un programa simple que cambia la dirección de la dirección de retorno a algún valor. ¿Alguien puede ayudarme a calcular el tamaño del puntero base para obtener el desplazamiento del primer argumento?Modificar dirección de devolución en la pila
void foo(void)
{
char ret;
char *ptr;
ptr = &ret; //add some offset value here
*ptr = 0x00;
}
int main(int argc, char **argv)
{
foo();
return 1;
}
El código ensamblador generado se ve de la siguiente manera:
.file "test.c"
.text
.globl foo
.type foo, @function
foo:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
leaq -9(%rbp), %rax
movq %rax, -8(%rbp)
movq -8(%rbp), %rax
movb $0, (%rax)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size foo, .-foo
.globl main
.type main, @function
main:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
call foo
movl $1, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size main, .-main
.ident "GCC: (GNU) 4.7.1 20120721 (prerelease)"
.section .note.GNU-stack,"",@progbits
La parte pertinente del segmento de marco foo debería tener este aspecto:
[Char RET] [puntero de base] [dirección de retorno ]
Tengo la posición de la primera que tiene solo 1 byte de tamaño. ¿Está solo a 1 byte del puntero base o del tamaño de una palabra como se menciona en http://insecure.org/stf/smashstack.html? ¿Y cómo puedo saber el tamaño del puntero base?
+1 Una recompilación siempre podría mover variables. Solo para las pruebas de OP, en este caso particular, la dirección de retorno está en '& ret + 17', que es poco probable que cambie siempre que las variables locales en esa función no cambien. – ughoavgfhw
compensación de 17 obras. ¿Puedes explicar cómo lo determinaste? – fliX
@fliX En el conjunto, la instrucción 'leaq -9 (% rbp),% rax' recibe una dirección en la pila. Como está alineado por bytes, y es el único cálculo de dirección, debe ser donde 'ret' es. Tomando ese 9 y agregando 8 para el puntero base anterior de 64 bits, obtienes 17. – ughoavgfhw