Come sfruttare uno stack overflow senza impostare -mpreferred-stack-boundary = 2

3

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?

posta nilminus 09.01.2016 - 21:04
fonte

0 risposte

Leggi altre domande sui tag