Saturday, February 16, 2013

Buffer Overflow Exploit

Yesterday I have been told about the buffer overflow exploit. The idea is very simple and an example can be implemented very easily. Nowadays compilers provide protection against Stack Overflows, still it is a good idea to write your programs overflow safe. The example I show here demonstrates an unsafe password authentiaction, given you disable your compiler's stack protection. Basically, you provide char arrays, that hold the user name and password, and an indicator variable for the result of user name and password comparison.
#include <iostream>
#include <cstring>
using namespace std;

int main (int argc, char** argv) {
  if (argc != 3) {
    return 1;
  }
  char user[10];
  char pass[10];
  int granted(0);
  strcpy(user, argv[1]);
  strcpy(pass, argv[2]);
  if (strcmp(user, "admin") == 0 && strcmp(pass, "pw") == 0) {
    granted = 1;
  }
  if (granted) {
    cout << "Access granted\n";
  } else {
    cout << "Access denied\n";
  }

  return 0;
}


If you are using gcc, your need to disable stack protection:

g++ -fno-stack-protector -o overflow main.cxx

If you choose your user name long enough you cause an overflow and change the value of the variable "granted". In my case the user name needs to be at least 13 characters long.

~ » ./overflow abc 123
Access denied
~ » ./overflow admin 123
Access denied
~ » ./overflow admin pw
Access granted
~ » ./overflow AAAAAAAAAAAAA AA
Access granted

If you build your program with debugging symbols, you can print the value of the variables. For the last case, you will have an output like (granted != 0):
(gdb) print user
$5 = "AAAAAAAAAA"
(gdb) print pass
$6 = "AA\000\000\000\000\000\000\220\006"
(gdb) print granted
$7 = 65

This very simple way of exploiting overflows can be avoided very easily, e.g. length checks, and only works if you disable stack protection. However, it shows the very basic idea behind overflow exploitation and should convince you to write code that is overflow safe.

No comments:

Post a Comment