Question: Insecure Code /* Simple buffer overflow example Warning this is an example with many pieces of insecure code and information. Inspired by INSIDE THE BUFFER

Insecure Code

/* Simple buffer overflow example Warning this is an example with many pieces of insecure code and information. Inspired by INSIDE THE BUFFER OVERFLOW ATTACK: MECHANISM, METHOD, & PREVENTION Mark E. Donaldson, SANS Corporation. April 3, 2002 GSEC Version 1.3 */ #include #include #include #include #include using namespace std; void get(char* askfor, int numchars, char* input); void get_password(char* name, char* pwd); int main() { // Change these character arrays to strings. char name[8], pwd[8], passwd[8]; cout << "Address of name =" << &name <<" "; cout << "Address of passwd =" << &passwd <<" "; cout << "Address of pwd =" << &pwd <<" "; char Name[5]="Name"; char Password[9]="Password"; bool authenticated=false; while(! authenticated) { // input the name here get(Name, 7, name); // get the password pwd for the name get_password(name, pwd); // input a password passwd get(Password, 7, passwd); // cout <>input; return; } void get_password(char* name, char* pwd) { // Yuch! This returns pwd depending on the variable name // Rewrite so it accepts a string name and returns a string if(!strcmp(name,"botting")) strcpy(pwd, "123456"); else if(!strcmp(name,"ernesto")) strcpy(pwd, "765432"); else if(!strcmp(name,"tong")) strcpy(pwd, "234567"); else strcpy(pwd, "qwert"); return; }

The program is designed as an example of a bad log-in program. It uses char* arrays to hold character strings and the old "str*" library to manipulate them. Each string has an extra '\0' char at the end.

#include // defines the "str*" functions. authenticated= ! strncmp(pwd,passwd,7); // CoMPares upto 7 charcaters of pwd and passwd and sets authenticated to true if they are equal. if(!strcmp(name,"botting")) // compares the characters in name with those in "botting" and does not keep count. It tries pairs of characters until one is different or '\0'. The condition succeeds if the strings are equal. strcpy(pwd, "123456"); // Copies "123456" into pwd -- this copies 6 characters and a null '\0' even if pwd has room for 2 character:-( 

It has many faults and we will remove some of these in our laboratories. This is how it works when compiled and run:

  • First, it outputs the addresses of the three-character arrays used in the program: "name", "pwd", and "passwd".
  • Then it enters a loop until a log-in is authenticated:
  • It asks for a name ("botting" for example) using a function "get".
  • It looks up the password for the name ("botting" has "123456") using function get_password.
  • It asks for a password.
  • It tests to see if the two passwords match.
  • If they don't match it outputs a message and repeats from step 1 above.
  • If the two passwords match it "Welcomes" the user.

Make it compile it into "lab05bad" and test it. It should work as described. Unfortunately, it falls to a simple buffer overrun attack. Run it with name 'botting' and try passwords 'x', 'xx', 'xxxx', 'xxxxxx', and so on.... what happens with each? Any unexpected logins? Explain what is happening. (Hint: examine the memory addresses of the character arrays. Print out pwd before get(Password, 7, passwd); and both pwd and passwd after the get.)

Choose two of the following 3 methods to fix the problem. You gain 5 extra credit points if you implement all 3 methods.

The problem arises from:

 cin>>input; in function void get(char * askfor, int numchars, char * input) 

Here are two ways to attempt to fix the problem that are fairly easy and one that is challenging.

  1. The quick fix: input the user data into a 'string' variable. Then use the 'string' functions to extract a substring that fits in the given 7 character buffer. This relies on the C++ Standard Library not having a buffer overrun in its place.
  2. Use a character by character loop: Have a single
     char c; 
    and put the user data into it one character at a time using
     cin.get(c); 
    until the buffer(input) is full or the user taps enter (' '). Then add the terminating ('\0') and discard the rest of the data by using cin.get(c) and not doing anything with c!
  3. The challenge of getline: Here you use
     cin.getline(input, numchars+1, ' '); 
    to fill the buffer. You then need to use
     cin.fail() 
    to see if there are any characters to discard and
     cin.clear() 
    to clear the fail flag. After clearing the fail flag then you can use cin.get(...) to discard the rest of the line.

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!