Skip to content

Instantly share code, notes, and snippets.

@Wachiwi
Last active May 11, 2017 09:57
Show Gist options
  • Save Wachiwi/720b76d1235f77f0494461cdf321709f to your computer and use it in GitHub Desktop.
Save Wachiwi/720b76d1235f77f0494461cdf321709f to your computer and use it in GitHub Desktop.
Praktikum 5

Vorbereitung

Keine

Ausgangssituation

Ausgangssituation ist wie in P4 ein simples hackbares Programm via Buffer-Overflow:

#include <stdio.h>

void hack(void);
void read(void);

int main(void){
        read();
        return 0;
}

void hack(void) { printf("Hacked!\n\r"); }

void read(void){
        int test = CAN;
        char hackme[2];
        printf("IN: ");
        gets(hackme);
        printf("%s\n\r", hackme);
}

Das Programm kann nun mit dem üblichen Aktionen disassembled werden und "gehackt" werden.

$ echo -e "123456789012345678901234\xad\x05\x40\x00\x00\x00\x00\x00" | ./a.out
Hacked!

Einfügen des Canary-Schutzes

Als erstes fügen wir im Daten/Text-Segment eine konstante/globale variable hinzu, die unseren Canary-Wert repräsentiert. In unserem Fall haben wir die über ein define die die Variable CAN mit dem Wert 0x41424344 definiert. (0x41424344, da es einfach in gdb zu sehen ist).

#include <stdio.h>

#define CAN 0x41424344 // 1094861636

void hack(void);
void read(void);

int main(void){ read(); return 0; }
void hack(void) { printf("Hacked!\n\r"); }

void read(void){
        int test = CAN;
        char hackme[2];
        printf("test %p hackme %p\n", &test, &hackme);
        printf("IN: ");
        gets(hackme);
        printf("%s\n\r", hackme);
}

Als nächstes wird nun direkt vor einem return der Funktion die Überprüfung des Canaries durchgeführt. Für den Fall das der Canary nicht mehr übereinstimmt wird eine entsprechende Fehlermeldung ausgegeben und das Programm sicherheitshalber beendet.

#include <stdio.h>

#define CAN 0x41424344

void hack(void);
void read(void);

int main(void){ read(); return 0; }
void hack(void) { printf("Hacked!\n\r"); }

void read(void){
        int test = CAN;
        char hackme[2];
        printf("test %p hackme %p\n", &test, &hackme);
        printf("IN: ");
        gets(hackme);
        printf("%s\n\r", hackme);
        if(test != CAN ){
                printf("NO, HACKING PLEASE!\n\r");
                exit(0);
        }
}

Die Besonderheit hierbei ist, dass nun beim Aufruf des Programmes zusätzlich zu dem Overflow noch der Canary mit überschrieben werden muss, daher ist die Anzahl der übergebenen Parameter länger.

# Getestet kann der Canary-Schutz werden mit Hilfe dieses Aufrufes
$ echo -e "12345678901234567890123\x00\x00\xad\x05\x40\x00\x00\x00\x00\x00" | ./a.out
No, HACKING PLEASE!

# Der Canary kann umgangen werden indem im Buffer-Overflow der entsprechende Canary-Wert wieder gesetzt wird (0x41424344 entspricht DCBA)
$ echo -e "123456781234DCBAxxxxxxxx\xfd\x05\x40\x00\x00\x00\x00\x00" | ./a.out

Das Final Programm befindet sich im Anhang

#include <stdio.h>
#define CAN 0x41424344 // 1094861636
void hack(void);
void read(void);
int main(void){
read();
return 0;
}
void hack(void) {
printf("Hacked!\n\r");
}
void read(void){
int test = CAN;
char hackme[2];
printf("test %p hackme %p\n", &test, &hackme);
printf("IN: ");
gets(hackme);
printf("%s\n\r", hackme);
if(test != CAN ){
printf("NO, HACKING PLEASE!\n\r");
printf("%i\n\r", test);
exit(0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment