32bits Linux: overflow dello stack semplice: EIP non viene mai sovrascritto

5

Sto cercando di capire come funziona il semplice overflow dello stack (su Linux a 32 bit) ma sono di fronte a uno strano problema.

Sto utilizzando il link per testare il mio codice. Tutto funziona alla grande. Il mio shellcode è perfettamente eseguito, quindi penso di capire (un po ') cosa sto facendo.

MA, quando sto provando la stessa cosa sul mio computer (stesso codice, stesse opzioni GCC, ASLR disattivato), sto affrontando uno strano problema. Semplicemente non riesco a sovrascrivere EIP: /

Prima di tutto, questo è il codice:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char*argv[])
{
char buffer[256];

if(argc < 2) {
perror("Usage: ./pwnme twitt\n");
return 1;
}

strcpy(buffer,argv[1]);
printf("%s", buffer);

return 0;
}

Sul server della sfida, EIP viene sovrascritto (Buone notizie!):

$> lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 8.6 (jessie)
Release:    8.6
Codename:   jessie


$> uname -a
Linux binary-challenges-pwnerrank-com 3.2.0-4-amd64 #1 SMP Debian 3.2.82-1 x86_64 GNU/Linux


$> file ./pwnme
./pwnme: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.26, BuildID[sha1]=b49c31fc047654c28f93910c8e04cecb6a19ac30, not stripped


$> gdb -q ./pwnme

(gdb) r 'python -c 'print "A" * 280''
[SEGFAULT]

(gdb) i r
eax            0x0  0
ecx            0x0  0
edx            0xf7fc9878   -134440840
ebx            0xf7fc8000   -134447104
esp            0xffffd5e0   0xffffd5e0
ebp            0x41414141   0x41414141
esi            0x0  0
edi            0x0  0
eip            0x41414141   0x41414141
eflags         0x10286  [ PF SF IF RF ]
cs             0x23 35
ss             0x2b 43
ds             0x2b 43
es             0x2b 43
fs             0x0  0
gs             0x63 99
(gdb)

=============================================== ======================

Ora proverò sul mio Linux (con lo stesso codice C):

$> lsb_release -a
No LSB modules are available.
Distributor ID: LinuxMint
Description:    Linux Mint 18 Sarah
Release:    18
Codename:   sarah

$> uname -a
Linux 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

Compilazione:

$> gcc bof.c -o pwnme -fno-stack-protector -z execstack -m32

ASLR off:

$> $ sudo cat /proc/sys/kernel/randomize_va_space
0

$> file pwnme 
pwnme: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=bf0e63dc240cb7a8e72fd656677a2d03a93588ed, not stripped


$ gdb -q ./pwnme 
Reading symbols from ./pwnme...(no debugging symbols found)...done.
(gdb) r 'python -c 'print "A" * 280''
Starting program: /home/n3r0x/Documents/BoF/pwnme 'python -c 'print "A" * 280''

Program received signal SIGSEGV, Segmentation fault.
0x080484db in main ()
(gdb) i r
eax            0x0  0
ecx            0x41414141   1094795585
edx            0xf7fac870   -134559632
ebx            0x0  0
esp            0x4141413d   0x4141413d
ebp            0x41414141   0x41414141
esi            0xf7fab000   -134565888
edi            0xf7fab000   -134565888
eip            0x80484db    0x80484db <main+112>
eflags         0x10286  [ PF SF IF RF ]
cs             0x23 35
ss             0x2b 43
ds             0x2b 43
es             0x2b 43
fs             0x0  0
gs             0x63 99
(gdb)

Come puoi vedere, questa volta, solo l'EBP viene sovrascritto. E non capisco perché: / Forse un'altra caratteristica di sicurezza da qualche parte? Hai un'idea ? E ovviamente, se sostituisco 280 "A" di 300 o più "A", è la stessa cosa.

Grazie mille:)

[EDIT] - Scusa, ho trovato la risposta su questo forum. Era solo una questione di allineamento dello stack. Tutto è qui: Compilare un esempio di overflow del buffer nel moderno Linux?

Ho spostato la strcpy su una funzione diversa, funziona benissimo. E l'ultima risposta dà una buona spiegazione.

Grazie per il tuo aiuto!

    
posta n3r0x 03.01.2017 - 16:25
fonte

3 risposte

3

Questa differenza potrebbe esserci a causa del diverso allineamento dello stack utilizzato sul lato server. Per l'impostazione dell'allineamento dello stack, viene utilizzata l'opzione " mpreferred-stack-boundary ". Di Più: link

Spero che questo aiuti!

    
risposta data 04.01.2017 - 07:04
fonte
1

Il comando di hardening-check incluso nel pacchetto include include anche alcune informazioni aggiuntive sulle funzionalità di sicurezza all'interno dell'eseguibile. Penso che il relro sia incluso di default. Questo può essere disabilitato con il seguente flag gcc.

-Wl,-z,norelro
    
risposta data 03.01.2017 - 19:04
fonte
0

C'è un po 'più di protezione per un moderno kernel Linux rispetto alle opzioni ASLR e GCC sui binari compilati.

Sembra che tu stia utilizzando Mint - Non conosco molto bene Mint, ma so che è basato su Ubuntu e Debian e sembra che sia in esecuzione un kernel di Ubuntu.

Il kernel di Ubuntu ha alcune caratteristiche di sicurezza per impostazione predefinita, alcuni probabilmente non possono essere disabilitati.

I responsabili della sicurezza di Ubuntu hanno un script di test di regressione progettato per garantire il funzionamento delle funzionalità di sicurezza. Eseguendo quella localizzazione potrebbe fare luce sul problema o almeno indirizzarti nella giusta direzione.

    
risposta data 03.01.2017 - 18:38
fonte

Leggi altre domande sui tag