Πέμπτη 27 Φεβρουαρίου 2014

Buffer Overflows

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

  • 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 */

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου