I. Anatomy of a Buffer Overflow
a. Buffer: μνήμη που χρησιμοποιείται για store user input, με καθορισμένο maximum size
b. Buffer overflow: όταν η user input υπερβαίνει το maximum buffer size. Επιπλέον input οδηγεί σε απροσδόκητη περιοχή μνήμης
void get_input() {
char buf[1024];
gets(buf);
}
void main (int argc, char*argv[]) {
get_input();
}
c. Παράδειγμα Buffer Overflow
int checkPassword() {
char pass[16];
bzero(pass, 16); // Initialize
printf(“Enter password: “);
gets(pass);
if (strcmp(pass, “opensesame”) ==0)
return 1;
else
return 0;
}
void openVault() {
// Opens the vault
}
main() {
if (checkPassword()) {
openVault();
printf(“Vault opened!”);
}
}
d. checkPassword() Bugs
- Execution stacks: maintains την συγκεκριμένη συνάρτησης και κρατάει την διεύθυνση της return function
- Stack frame: κρατά μεταβλητές και δεδομένα της συνάρτησης
- Επιπλέον user input (>16 chars) επικαλύπτει την return address
e. Non-Executable Stacks δεν επιλύουν τα προβλήματα
- Ενδεχόμενη επίθεση μπορεί να κάνει overwrite τη return address και να δώσει νέο point με injected code
- NX stacks μπορούν να το αποτρέψουν αυτό, αλλά όχι στο παρών παράδειγμα (jumping to an existing function)
- Return-into-libc- attack: jump to library functions
f. The safe_gets() Function
#define EOLN ‘\n’
void safe_gets (char *input, int max_chars) {
if ((input == NULL) || (max_chars < 1))) return;
if (max_chars == 1) { input[0] = 0; return;}
int count = 0;
char next_char;
do {
next_char = getchar(); // one character at a time
if (next_char != EOLN)
input[count++] = next_char;
} while ((count < max_chars-1) && // leave space for null
(next_char != EOLN));
Input[count] = 0;
- Σε αντίθεση με τη gets(), λαμβάνει την παράμετρο καθορίζοντας τους max chars που θα εισάγει στον buffer
- Χρησιμοποιεί την checkPassword αντί της gets() για να αποτρέψει κάθε buffer overflow ενδεχόμενο
II. Safe String Libraries
a. C – Avoid (no bounds check) : strcpy(), strcat(), sprint(), scanf()
b. Use safer versions (with bounds check): strncpy(), strncat(), fgets()
c. Null Terminations: StrSafe(), SafeStr()
d. C++: STL string class handles allocation
e. Unlike compiled language (C/C++), interpreted ones (Java/C#) enforce type safety, raise exceptions for buffer overflow
III. Additional Approaches
a. StackGuard/Canaries
- Canary: random value, μη προβλέψιμη από τον hacker
- Compiler technique: ενσωματώνει την Canary τιμή πριν την return address στην stack
- Corrupt Canary: ο κώδικας τερματίζει προκειμένου να αποφύγει ενδεχόμενη επίθεση
b. Static Analysis Tools
- Static Analysis: ανάλυση του προγράμματος χωρίς να τρέχει το πρόγραμμα
- Meta-level compilation
- Coverity
- Fortify
- Ounce Labs
- Klockwork
IV. Heap-Based Overflows
a. H malloc() στην C, δεσμεύει ένα κομμάτι μνήμης στην heap
b. Εώς ότου εκτελεστεί η realloc(), ενδεχόμενη επίθεση μπορεί να προκαλέσει overflow στον heap buffer, να επικαλύψει δεδομεένα και να αλοιώσει το control path του προγράμματος
c. Παρόμοιες μέθοδοι αντιμετώπισης: bounds checking on input
V. Other Memory Corruption Vulnerabilities
a. Format String Vulnerabilities
- Format String στη C δείχνει πως πρέπει να είναι formatted το κείμενο στην έξοδο (π.χ. %d, %s)
- Integer Overflows
- Υπέρβαση των ορίων ενός integer
Signed 4-byte int: (-232) – (232 - 1)
/*Writes str to buffer with offset characters of blank spaces preceding str. */
void formatStr (char *buffer, int buflen, int offset, char *str, int slen) {
char message[slen+offset];
int I;
/* Write blank spaces */
for (i = 0; I < offset; i++)
message[i] = ‘ ‘;
strncpy(message+offset, str, slen);
// offset = 232!?
strncpy(buffer, message, buflen);
message[buflen-1] = 0;
/*Null terminate */
a. Buffer: μνήμη που χρησιμοποιείται για store user input, με καθορισμένο maximum size
b. Buffer overflow: όταν η user input υπερβαίνει το maximum buffer size. Επιπλέον input οδηγεί σε απροσδόκητη περιοχή μνήμης
void get_input() {
char buf[1024];
gets(buf);
}
void main (int argc, char*argv[]) {
get_input();
}
c. Παράδειγμα Buffer Overflow
int checkPassword() {
char pass[16];
bzero(pass, 16); // Initialize
printf(“Enter password: “);
gets(pass);
if (strcmp(pass, “opensesame”) ==0)
return 1;
else
return 0;
}
void openVault() {
// Opens the vault
}
main() {
if (checkPassword()) {
openVault();
printf(“Vault opened!”);
}
}
d. checkPassword() Bugs
- Execution stacks: maintains την συγκεκριμένη συνάρτησης και κρατάει την διεύθυνση της return function
- Stack frame: κρατά μεταβλητές και δεδομένα της συνάρτησης
- Επιπλέον user input (>16 chars) επικαλύπτει την return address
- Attack string 17-20th chars μπορούν να προσδιορίσουν την διεύθυνση της OpenVault() και να κάνουν bypass check
- Η διεύθυνση μπορεί να βρεθεί από τον πηγαίο κώδικα ή το binary αρχείο
e. Non-Executable Stacks δεν επιλύουν τα προβλήματα
- Ενδεχόμενη επίθεση μπορεί να κάνει overwrite τη return address και να δώσει νέο point με injected code
- NX stacks μπορούν να το αποτρέψουν αυτό, αλλά όχι στο παρών παράδειγμα (jumping to an existing function)
- Return-into-libc- attack: jump to library functions
f. The safe_gets() Function
#define EOLN ‘\n’
void safe_gets (char *input, int max_chars) {
if ((input == NULL) || (max_chars < 1))) return;
if (max_chars == 1) { input[0] = 0; return;}
int count = 0;
char next_char;
do {
next_char = getchar(); // one character at a time
if (next_char != EOLN)
input[count++] = next_char;
} while ((count < max_chars-1) && // leave space for null
(next_char != EOLN));
Input[count] = 0;
- Σε αντίθεση με τη gets(), λαμβάνει την παράμετρο καθορίζοντας τους max chars που θα εισάγει στον buffer
- Χρησιμοποιεί την checkPassword αντί της gets() για να αποτρέψει κάθε buffer overflow ενδεχόμενο
II. Safe String Libraries
a. C – Avoid (no bounds check) : strcpy(), strcat(), sprint(), scanf()
b. Use safer versions (with bounds check): strncpy(), strncat(), fgets()
c. Null Terminations: StrSafe(), SafeStr()
d. C++: STL string class handles allocation
e. Unlike compiled language (C/C++), interpreted ones (Java/C#) enforce type safety, raise exceptions for buffer overflow
III. Additional Approaches
a. StackGuard/Canaries
- Canary: random value, μη προβλέψιμη από τον hacker
- Compiler technique: ενσωματώνει την Canary τιμή πριν την return address στην stack
- Corrupt Canary: ο κώδικας τερματίζει προκειμένου να αποφύγει ενδεχόμενη επίθεση
b. Static Analysis Tools
- Static Analysis: ανάλυση του προγράμματος χωρίς να τρέχει το πρόγραμμα
- Meta-level compilation
- Αναζήτηση για security, synchronization και memory bugs
- Εντοπισμός συχνών code patterns/idioms και σηματοδότηση ενδεχόμενων code anomalies
- Coverity
- Fortify
- Ounce Labs
- Klockwork
IV. Heap-Based Overflows
a. H malloc() στην C, δεσμεύει ένα κομμάτι μνήμης στην heap
b. Εώς ότου εκτελεστεί η realloc(), ενδεχόμενη επίθεση μπορεί να προκαλέσει overflow στον heap buffer, να επικαλύψει δεδομεένα και να αλοιώσει το control path του προγράμματος
c. Παρόμοιες μέθοδοι αντιμετώπισης: bounds checking on input
V. Other Memory Corruption Vulnerabilities
a. Format String Vulnerabilities
- Format String στη C δείχνει πως πρέπει να είναι formatted το κείμενο στην έξοδο (π.χ. %d, %s)
- Integer Overflows
- Υπέρβαση των ορίων ενός integer
Signed 4-byte int: (-232) – (232 - 1)
/*Writes str to buffer with offset characters of blank spaces preceding str. */
void formatStr (char *buffer, int buflen, int offset, char *str, int slen) {
char message[slen+offset];
int I;
/* Write blank spaces */
for (i = 0; I < offset; i++)
message[i] = ‘ ‘;
strncpy(message+offset, str, slen);
// offset = 232!?
strncpy(buffer, message, buflen);
message[buflen-1] = 0;
/*Null terminate */
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου