// Titolo: Stack in azione v0.2
// Autore: Saio
// Data: Marzo 2005
////////////
// PAG.03 //
////////////
----------------------------
INDICE
PAG.01
PAG.02
PAG.03
PAG.04
----------------------------
///////COME OTTENERE SEGMENTATION FAULT//////
// Il seguente programma risulta vulnerabile ad errore di segmentazione
// (segmentation fault) in quanto sfrutta la funzione standard
gets(),
// che non fa alcun controllo sulla variabile in ingresso
-------------inizio bof1.c (Fig.01)------------
#include <stdio.h>
int main() {
char buff[15];
gets(buff);
}
-------------fine bof1.c (Fig.01)------------
[root@localhost saio]# gcc -static bof1.c -o bof1
[root@localhost saio]# gdb bof1
(gdb) disassemble main
Dump of assembler code for function main:
0x80481e0 <main>: push %ebp
0x80481e1 <main+1>: mov %esp,%ebp
0x80481e3 <main+3>: sub $0x18,%esp
0x80481e6 <main+6>: sub $0xc,%esp
0x80481e9 <main+9>: lea 0xffffffe8(%ebp),%eax
0x80481ec <main+12>: push %eax
0x80481ed <main+13>: call 0x80486b0 <_IO_gets>
0x80481f2 <main+18>: add $0x10,%esp
0x80481f5 <main+21>: mov %ebp,%esp
0x80481f7 <main+23>: pop %ebp
0x80481f8 <main+24>: ret
0x80481f9 <main+25>: lea 0x0(%esi,1),%esi
End of assembler dump.
(gdb) run
Starting program: /home/saio/Desktop/buffer/bof/bof1
aaaaadddddeeeeegggggtttt
// con 24 caratteri non avviene ancora l’errore Segmentation Fault
(gdb) run
Starting program: /home/saio/Desktop/buffer/bof/bof1
aaaaadddddeeeeegggggttttA
Program received signal SIGSEGV, Segmentation fault.
(gdb) continue
Continuing.
Program terminated with signal SIGSEGV, Segmentation fault.
// con 25 si ottiene Segmentation Fault (Fig.01)
(gdb) q

/////////////////////////////////////////
// Analizziamo meglio come viene ottenuto l’errore di segmentazione
// e verifichiamo come vengono allocate le variabili all’interno dello stack
///////////////
// Esempio 02: Aggiungiamo
num
per chiarire meglio come
// ottenere
S.F.
(Segmentation fault), in questo esempio applichiamo un
buff1[5]
-------------inizio bof2.c (Fig.02)------------
#include <stdio.h>
int main() {
long num=0;
char buff1[5];
gets(buff1);
}
-------------fine bof2.c (Fig.02)------------

[root@localhost saio]# gcc -static bof2.c -o bof2
[root@localhost saio]# ./bof
aaaaadddddeeeeegggggtttttfffffvvvvvrrrrr
[root@localhost saio]# ./bof
aaaaadddddeeeeegggggtttttfffffvvvvvrrrrrA
= 41 caratteri
Segmentation fault (core dumped)
//////////////////
// Esempio 03: Immetto prima
buff1
e poi
num
, vediamo cosa cambia
-------------inizio bof3.c (Fig.03)------------
#include <stdio.h>
int main() {
char buff1[5];
long num=0;
gets(buff1);
}
-------------fine bof3.c (Fig.03)------------

[root@localhost saio]# gcc -static bof3.c -o bof3
[root@localhost saio]# ./bof3
aaaaadddddeeeeegggggtttt
[root@localhost saio]# ./bof3
aaaaadddddeeeeegggggttttD
= 25 caratteri
Segmentation fault (core dumped)
//////////////////
// Esempio 04: Immetto prima
num
, poi
buff1
, poi
buff2
, analizziamo...
-------------inizio bof4.c (Fig.04)------------
#include <stdio.h>
int main() {
long num=0;
char buff1[5];
char buff2[10];
gets(buff1);
}
-------------fine bof4.c (Fig.04)------------

[root@localhost saio]# gcc -static bof4.c -o bof4
[root@localhost saio]# ./bof4
aaaaadddddeeeeegggggtttttyyyyykkkkkddddd
[root@localhost saio]# ./bof4
aaaaadddddeeeeegggggtttttyyyyykkkkkdddddf
= 41 caratteri
Segmentation fault (core dumped)
//////////////////
// Esempio 05: Mantengo l’ordine di immissione
num
, poi
buff1
, poi
buff2
. Ma
// considero il
gets(buff2)
anziche il
gets(buff1)
.
-------------inizio bof5.c (Fig.05)------------
#include <stdio.h>
int main() {
long num=0;
char buff1[5];
char buff2[10];
gets(buff2);
}
-------------fine bof5.c (Fig.05)------------

[root@localhost saio]# gcc -static bof5.c -o bof5
[root@localhost saio]# ./bof5
aaaaadddddeeeeegggggtttttaaaaadddddeeeeegggggtttttsssssd
[root@localhost saio]# ./bof5
aaaaadddddeeeeegggggtttttaaaaadddddeeeeegggggtttttsssssdx
= 57 caratteri
Segmentation fault (core dumped)
/////////////
// Esempio 06: Un’altra funzione che non controlla i dati in ingresso e’
strcpy().
----------- inizio bof6.c --------------
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
char buffer[40];
strcpy(buffer, argv[1]);
return 0;
}
----------- fine bof6.c --------------

[root@localhost saio]# gcc -static bof6.c -o bof6
[root@localhost saio]# ./bof6
[ saio]# ./bof6 rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
[ saio]# ./bof6 rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrre
<--57 car.
Segmentation fault (core dumped)
[root@localhost saio]# gdb bof6 core
Core was generated by `./bof6 rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrraaaa'.
Program terminated with signal 11, Segmentation fault.
#0 0x08048200 in main ()
(gdb)q
// 0x08048200 e’ un indirizzo sporco visto che non ho riempito il buffer oltre il SFP (Fig.06)

// Vediamo invece quando, oltre a riempire SFP, riempiamo il RET.(Fig.06.2)
// Con 56 + 4 + 4
= 64 caratteri riempiamo il RET:
[saio]# ./bof6 rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrraaaawwww
Segmentation fault (core dumped)
[root@localhost saio]# gdb bof6 core
Core was generated by `./bof6 rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrraaaawwww'.
Program terminated with signal 11, Segmentation fault.
#0 0x77777777
in ?? ()
<----------- RET = wwww
(gdb)q
/////////////
// Esempio 07: Chiamata a funzione:
il byte spectre
// Analizziamo il caso di una chiamata a funzione che
// opera con un byte 'spectre' che ci anticipa di 1 byte l’errore di segmentazione,
// senza nulla togliere alla riscrittura del RET che rimane a
// (39+1) + 4 + 4
= 48 byte con cui riempiamo il RET come nel caso precedente
----------- inizio bof7.c --------------
#include <stdio.h>
void lame(void){
char small[30];
gets(small);
}
main(){
lame();
return 0;
}
----------- fine bof7.c --------------

[root@localhost saio]# gcc -static bof7.c -o bof7
[root@localhost saio]# ./bof7
eeeeeeeeeevvvvvvvvvvttttttttttqqqqqxxxx
[root@localhost saio]# ./bof7
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
(S.F. al 40 byte e non al 41)
Segmentation fault (core dumped)
// Verifichiamo pero’ che nulla cambia nella riscrittura del RET:
[root@localhost saio]# ./bof7
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrreeeewwww
Segmentation fault (core dumped)
[root@localhost saio]# gdb bof7 core
Core was generated by `./bof7'.
Program terminated with signal 11, Segmentation fault.
#0 0x77777777
in ?? ()
<----------- RET = wwww
(gdb) q
------------------------------
INDICE
PAG.01
PAG.02
PAG.03
PAG.04
------------------------------