Ho giocato con alcuni giochi di guerra e ho effettuato il porting di alcuni di questi anche sulla mia macchina Linux. Ho notato che quando non si utilizza -mpreferred-stack-boundary = 2, gcc potrebbe compilare "main" con un prologo / epilogo interessante: efficacemente "basandosi su $ ecx (che si basa su $ ebp-4) per $ esp value before ret". Qualcun altro ha incontrato questa osservazione?
Questo significa che non è possibile sovrascrivere il normale indirizzo di ret in $ ebp + 4, ma invece devi sovrascrivere $ ebp-4 (che è ecx) e riposizionare il puntatore dello stack e il tuo indirizzo di ritorno (efficacemente usando un pivot dello stack) per favorire lo sfruttamento.
Trova gentilmente un codice di esempio e l'assembly correlato di seguito:
$ cat stack4.c
/* stack4-stdin.c *
* specially crafted to feed your brain by gera */
#include <stdio.h>
int main() {
int cookie;
char buf[80];
printf("buf: %08x cookie: %08x\n", &buf, &cookie);
gets(buf);
if (cookie == 0x000d0a00)
printf("you win!\n");
}
$ objdump -D ./stack4_normal | grep -A31 main.:
0804845b <main>:
804845b: 8d 4c 24 04 lea 0x4(%esp),%ecx
804845f: 83 e4 f0 and $0xfffffff0,%esp
8048462: ff 71 fc pushl -0x4(%ecx)
8048465: 55 push %ebp
8048466: 89 e5 mov %esp,%ebp
8048468: 51 push %ecx
8048469: 83 ec 64 sub $0x64,%esp
804846c: 83 ec 04 sub $0x4,%esp
804846f: 8d 45 f4 lea -0xc(%ebp),%eax
8048472: 50 push %eax
8048473: 8d 45 a4 lea -0x5c(%ebp),%eax
8048476: 50 push %eax
8048477: 68 50 85 04 08 push $0x8048550
804847c: e8 8f fe ff ff call 8048310 <printf@plt>
8048481: 83 c4 10 add $0x10,%esp
8048484: 83 ec 0c sub $0xc,%esp
8048487: 8d 45 a4 lea -0x5c(%ebp),%eax
804848a: 50 push %eax
804848b: e8 90 fe ff ff call 8048320 <gets@plt>
8048490: 83 c4 10 add $0x10,%esp
8048493: 8b 45 f4 mov -0xc(%ebp),%eax
8048496: 3d 00 0a 0d 00 cmp $0xd0a00,%eax
804849b: 75 10 jne 80484ad <main+0x52>
804849d: 83 ec 0c sub $0xc,%esp
80484a0: 68 68 85 04 08 push $0x8048568
80484a5: e8 86 fe ff ff call 8048330 <puts@plt>
80484aa: 83 c4 10 add $0x10,%esp
80484ad: 8b 4d fc mov -0x4(%ebp),%ecx
80484b0: c9 leave
80484b1: 8d 61 fc lea -0x4(%ecx),%esp
80484b4: c3 ret
Ho trovato diversi argomenti e spiegazioni su StackExchange sul perché questo accade. Ciononostante, sto cercando una guida / tutorial che tratti specificamente la parte dello sfruttamento. Forse qualcuno più intelligente di me ha standardizzato questo sfruttamento in un modo molto migliore di me.
Sembra che molte persone, nelle esercitazioni, usino semplicemente -mpreferred-stack-boundary = 2 per evitare questo problema e continuare normalmente con il tutorial di exploitation.
Trovo difficile credere che nessuno abbia menzionato questo in un tutorial poiché le nuove versioni di gcc si compilano come di default (almeno sul mio computer).
In ogni caso, la domanda è:
-
È questo il modo ottimale per sfruttarlo (usando un pivot dello stack)?
-
Se no, qualcuno può per favore indicarmi un tutorial o una spiegazione di una migliore modo?