sto sperimentando con i buffer overflow e cercare di sovrascrivere l'indirizzo di ritorno dello stack con un certo ingresso di fgetscausano un buffer overflow con fgets
Questo è il codice:
void foo()
{
fprintf(stderr, "You did it.\n");
}
void bar()
{
char buf[20];
puts("Input:");
fgets(buf, 24, stdin);
printf("Your input:.\n", strlen(buf));
}
int main(int argc, char **argv)
{
bar();
return 0;
}
Su un esecuzione normale il programma restituisce semplicemente il tuo input. Voglio che emetta foo() senza modificare il codice.
La mia idea era di traboccare il buffer di buf
inserendo 20 'A'
s. Funziona e causa un errore di segmentazione. La mia prossima idea era di scoprire l'indirizzo di foo()
che è \x4006cd
e aggiungere questo al 20 'A'
s.
Da quanto ho capito, questo dovrebbe sovrascrivere l'indirizzo di ritorno dello stack e farlo saltare a foo
. Ma provoca solo un segfault.
Cosa sto sbagliando?
Aggiornamento: Assembler discariche principale
Dump of assembler code for function main:
0x000000000040073b <+0>: push %rbp
0x000000000040073c <+1>: mov %rsp,%rbp
0x000000000040073f <+4>: sub $0x10,%rsp
0x0000000000400743 <+8>: mov %edi,-0x4(%rbp)
0x0000000000400746 <+11>: mov %rsi,-0x10(%rbp)
0x000000000040074a <+15>: mov $0x0,%eax
0x000000000040074f <+20>: callq 0x4006f1 <bar>
0x0000000000400754 <+25>: mov $0x0,%eax
0x0000000000400759 <+30>: leaveq
0x000000000040075a <+31>: retq
End of assembler dump.
foo
Dump of assembler code for function foo:
0x00000000004006cd <+0>: push %rbp
0x00000000004006ce <+1>: mov %rsp,%rbp
0x00000000004006d1 <+4>: mov 0x200990(%rip),%rax # 0x601068 <[email protected]@GLIBC_2.2.5>
0x00000000004006d8 <+11>: mov %rax,%rcx
0x00000000004006db <+14>: mov $0x15,%edx
0x00000000004006e0 <+19>: mov $0x1,%esi
0x00000000004006e5 <+24>: mov $0x400804,%edi
0x00000000004006ea <+29>: callq 0x4005d0 <[email protected]>
0x00000000004006ef <+34>: pop %rbp
0x00000000004006f0 <+35>: retq
End of assembler dump.
bar:
Dump of assembler code for function bar:
0x00000000004006f1 <+0>: push %rbp
0x00000000004006f2 <+1>: mov %rsp,%rbp
0x00000000004006f5 <+4>: sub $0x20,%rsp
0x00000000004006f9 <+8>: mov $0x40081a,%edi
0x00000000004006fe <+13>: callq 0x400570 <[email protected]>
0x0000000000400703 <+18>: mov 0x200956(%rip),%rdx # 0x601060 <[email protected]@GLIBC_2.2.5>
0x000000000040070a <+25>: lea -0x20(%rbp),%rax
0x000000000040070e <+29>: mov $0x18,%esi
0x0000000000400713 <+34>: mov %rax,%rdi
0x0000000000400716 <+37>: callq 0x4005b0 <[email protected]>
0x000000000040071b <+42>: lea -0x20(%rbp),%rax
0x000000000040071f <+46>: mov %rax,%rdi
0x0000000000400722 <+49>: callq 0x400580 <[email protected]>
0x0000000000400727 <+54>: mov %rax,%rsi
0x000000000040072a <+57>: mov $0x400821,%edi
0x000000000040072f <+62>: mov $0x0,%eax
0x0000000000400734 <+67>: callq 0x400590 <[email protected]>
0x0000000000400739 <+72>: leaveq
0x000000000040073a <+73>: retq
End of assembler dump.
Hai guardato l'assemblatore corrispondente (e quindi lo stack layout) per questo codice? –
Se solo fosse così facile ... –
Dovresti dare un'occhiata all'assemblaggio corrispondente. A volte il compilatore farà più di 20 byte che hai fatto per l'allineamento. Si dovrebbe anche guardare il layout dello stack e come salvare i registri/salvati addrs e in quale ordine. Vai avanti e pubblica il meglio della funzione e possiamo aiutarti ulteriormente. –