char buffer[1024]; gets(buffer);Hint: what information or argument is the function gets() missing?
gcc -o program overflow1.cto check whether the result depends on the operating system. (download)
/*****************************************************************************/ /* */ /* File: overflow1.c */ /* */ /*****************************************************************************/ #includeNow answer these questions:main() { char buffer[8]; printf("Please enter your name:"); scanf("%s",buffer); printf("Your name is: [%s]\n",buffer); Function1(); Function2(); } /*****************************************************************************/ Function1() { char buffer[100]; sprintf (buffer,"Mary had a little lamb whose fleece was white as /bin/sh BadScript ..."); printf("%.22s\n",buffer); } /*****************************************************************************/ Function2() { char buffer[50]; printf("Execute command %s\n",buffer); }
Please enter your name:abcdef Your name is: [abcdef] Mary had a little lamb Execute command /bin/sh BadScript ...Can you explain why?
/*****************************************************************************/ /* */ /* File: overflow2.c */ /* */ /*****************************************************************************/ #includemain() { Function1(); Function2(); } /*****************************************************************************/ Function1() { char buffer[100]; scanf("%[^\n]",buffer); } /*****************************************************************************/ Function2() { char buffer[50]; printf("01234567890123456789001234567890012345678901234567890\n"); printf("Executing command %s\n",buffer); system (buffer); }
One of the biggest problems for programmers who write interactive programs (including programs which interact over a network, such as client-server systems) is in handling streams. You have probably heard about streams in connection with the streams library for C++, but you should not think that this is only something to do with that library.
A stream of data is a continuous feed of input/output which contains multiple data items. The length of a data stream is unknown at the start of transmission, it's end is marked by an EOF (end of file) condition. Transfer of data by streams can be contrasted with the transfer of blocks of data, of known size.
The most well-known streams are called standard in/stdin and standard out/stdout . They are usually keyboard input and console output. Each time we ask the user to type in some data, we open a channel to the keyboard stream. Input ends when the user types ENTER.
The purpose of this week's exercise is to highlight the problems involved in stream programming. Why is this difficult? Why is this one of the most common sources of error in interactive programming? We shall be coding both in C and in C++.
C C++
int a; int a;
scanf("%d",&a); cin >> a;
These are amongst the most difficult and dangerous functions in input processing, for
two reasons:
#include <stdio.h> #include <iostream>
main() main()
{ int a = 0; { int a = 0;
static char buffer[20] = "rm *"; static char buffer[20] = "rm *";
printf ("Enter [uid] [command]: "); cout << "Enter [uid] [command]: ";
scanf("%d %s",&a,buffer); cin >> a >> buffer;
printf("Okay, executing %s as user %d\n",buffer,a); cout << "Okay, executing " << buffer << " as user " << a << endl;
} }
Try typing in the following input:
100 ls 100ls ls 100Can you explain the results? Suppose, this has been a server on a Unix host, what would be the result of the last line?
#include <iostream>
main()
{ char command[40]; // Send command to
int time_of_day; // Avoid replay attack?
cin >> time_of_day >> command;
cout << "Command was " << command << " at time " << time_of_day << endl;
}
and try it with the following input:
13 report 13 shoot-to-kill 15 shoot only if they shoot first 12:00 fire
Suppose now, we make this into a loop to receive new commands, like a server:
#include <iostream>
main()
{ char command[40]; // Send command to
int time_of_day; // Avoid replay attack?
const bool ever = 1;
for ( ;ever; )
{
cin >> time_of_day >> command;
cout << "Command was " << command << " at time " << time_of_day << endl;
}
}
Try entering the same input now. Can you see how easy it is to perform
a denial of service attack on this server? This same error was present
in NT4, prior to service pack 2. This problem is difficult to fix
with the C++ stream library, but easy to fix with C's I/O library:
#include <stdio.h>
#define ever 1
main()
{ char command[40]; // Send command to
int time_of_day; // Avoid replay attack?
for ( ;ever; )
{
scanf("%d %[^\n]",&time_of_day,command);
printf("Command %s at time %d\n",command,time_of_day);
}
}
The regular expression matcher %[^\n] means `match any object consisting
of any character up to end of line'.