Example of man-made vulnerable code
Download
Report
Transcript Example of man-made vulnerable code
CAP6135: Malware and Software
Vulnerability Analysis
Fuzzing Test Example
Cliff Zou
Spring 2016
Objective
Explain basic fuzzing with concrete coding
example
Fuzzing code that can run under Linux
Explain how the vulnerable code in
programming project 2 is derived
Introduce several useful techniques in
doing the fuzzing test on project 2
2
Example Code
$ fuzzTest-target 200 “what is this?” 2
Example code needs three inputs
Int, string, Int
int inputInteger; /* global variable */
void (*foo)(short);
if (argc != 4){
fprintf(stderr, "fuzzTest needs 3 input parameters: int string int!\n");
exit(0);
}
sscanf(argv[1], "%d", &inputInteger);
my_func(inputInteger, argv[2], argv[3]);
Subfun my_func() introduces 3 man-made bugs
3
Bug # 1: Integer Overflow
int my_func(short argLen, char *str, char *divStr)
{
int denominator;
float x;
char buf[bufLen];
if (argLen != inputInteger) {
fprintf(stderr, "Bug #1: integer overflow triggered\n");
foo = (void *)0xbfffffff;
foo(argLen); /* trigger illegal instruction fault */
exit(1);
Int variable inputInteger changes to short
Overflow happens when inputInteger>32767
foo() is a function pointer
Give it an arbitrary address will cause illegal memory reference
for executing code
A simple way to cause a program to crash
4
Bug # 2: buffer Overflow
char buf[10];
if (strlen(str) > 10){
fprintf(stderr, "Bug #2: buffer overflow triggered. strlen=%d\n", strlen(str));
strcpy(buf, str); /* trigger segmentation fault or stack smashing error */
return 2; /*if overwriting return address, it will cause segmentation fault */
}
5
Bug #3: divide by zero
int denominator; float x;
sscanf(divStr, "%d", &denominator);
if (denominator == 0){
x = argLen / denominator;
fprintf(stderr, "Bug #3: division by zero triggered\n");
foo = (void *)0xbffbffff;
foo(argLen); /* trigger illegal instruction fault */
}else
x = argLen / denominator;
return 0;
The divide by zero error will usually not cause a
program to crash
Thus we use the foo function to make sure the program will
crash when this bug is triggered
6
Fuzzer Outline
Generate inputs (random or follow rules)
firstInt = rand()%50000; secondInt = rand() % 2;
arraySize = rand() % 20;
charArray = (char *) malloc(arraySize);
for (j=0; j< arraySize; j++)
charArray[j] = 'A';
charArray[arraySize-1] = NULL;
Generate execution command line
sprintf(buffer, "./fuzzTest-target %d \"%s\" %d\n", firstInt,
charArray, secondInt);
free(charArray); /* must free memory for repeat testing! */
7
Fuzzer Outline
Execute target code
ret = system(buffer);
Obtain target execution exit code
wait(&status);
retCode = WEXITSTATUS(ret);
Check abnormal exit code and record inputs
that cause the abnormal
if ( retCode == 128+11 || retCode ==128+4) /* segmentation fault (11) or illegal (4) */
{
printf("retCode=%d ## Input: firstInt = %d, arraySize = %d, secondInt = %d\n",
retCode, firstInt, arraySize, secondInt);
fflush(stdout); /*make sure output is print out immediately ! */
}
Repeat from start in generating inputs
8
List of Unix Signal Number
You can find it at:
http://man7.org/linux/man-pages/man7/signal.7.html
The WEXITSTATUS() returns a value that is the signal number
that caused the termination plus 128
9
How to Record Fuzzing Result?
When abnormal happens, record down inputs that cause
the abnormal
Record the corresponding abnormal message printout by
target code
Unix OS I/O definition:
I/O redirection:
stdin (0), stdout (1), stderr (2)
$ Command < data.txt: let stdin get from file (instead of keyboard)
$ Command > output.txt: let stdout redirect to file
$ Command 2> error.txt: let stderr redirect to file
$ Command &> output.txt: let stdout and stderr redirect to file
For our example:
$./fuzzTest100 &> output.txt
10