CAP 6135 Malware and Software Vulnerability Analysis Fuzzing
CAP 6135: Malware and Software Vulnerability Analysis Fuzzing Test Example Cliff Zou Spring 2016
Objective q Explain basic fuzzing with concrete coding example q q q 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 q $ fuzz. Test-target 200 “what is this? ” 2 q Example code needs three inputs q Int, string, Int input. Integer; /* global variable */ void (*foo)(short); if (argc != 4){ fprintf(stderr, "fuzz. Test needs 3 input parameters: int string int!n"); exit(0); } sscanf(argv[1], "%d", &input. Integer); my_func(input. Integer, argv[2], argv[3]); q Subfun my_func() introduces 3 man-made bugs 3
Bug # 1: Integer Overflow int my_func(short arg. Len, char *str, char *div. Str) { int denominator; float x; char buf[buf. Len]; if (arg. Len != input. Integer) { fprintf(stderr, "Bug #1: integer overflow triggeredn"); foo = (void *)0 xbfffffff; foo(arg. Len); /* trigger illegal instruction fault */ exit(1); q Int variable input. Integer changes to short q q Overflow happens when input. Integer>32767 foo() is a function pointer q q 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=%dn", 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(div. Str, "%d", &denominator); if (denominator == 0){ x = arg. Len / denominator; fprintf(stderr, "Bug #3: division by zero triggeredn"); foo = (void *)0 xbffbffff; foo(arg. Len); /* trigger illegal instruction fault */ }else x = arg. Len / denominator; return 0; q The divide by zero error will usually not cause a program to crash q Thus we use the foo function to make sure the program will crash when this bug is triggered 6
Fuzzer Outline q Generate inputs (random or follow rules) first. Int = rand()%50000; second. Int = rand() % 2; array. Size = rand() % 20; char. Array = (char *) malloc(array. Size); for (j=0; j< array. Size; j++) char. Array[j] = 'A'; char. Array[array. Size-1] = NULL; q Generate execution command line sprintf(buffer, ". /fuzz. Test-target %d "%s" %dn", first. Int, char. Array, second. Int); free(char. Array); /* must free memory for repeat testing! */ 7
Fuzzer Outline q q q Execute target code ret = system(buffer); Obtain target execution exit code wait(&status); ret. Code = WEXITSTATUS(ret); Check abnormal exit code and record inputs that cause the abnormal if ( ret. Code == 128+11 || ret. Code ==128+4) /* segmentation fault (11) or illegal (4) */ { printf("ret. Code=%d ## Input: first. Int = %d, array. Size = %d, second. Int = %dn", ret. Code, first. Int, array. Size, second. Int); fflush(stdout); /*make sure output is print out immediately ! */ } q Repeat from start in generating inputs 8
List of Unix Signal Number q You can find it at: q q http: //man 7. org/linux/man-pages/man 7/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? q q q When abnormal happens, record down inputs that cause the abnormal Record the corresponding abnormal message printout by target code Unix OS I/O definition: q q I/O redirection: q q q 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: q $. /fuzz. Test 100 &> output. txt 10
- Slides: 10