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