Fuzzing Basics

Prerequisites: 

BASH
Perl
Python
a Brain

Introduction to Fuzzing

What is Fuzzing?

Fuzzing is a method in which seemingly random data is sent to the input of a computer program. While the program is being fuzzed, the process is watched for any unexpected results or output. When the program displays unexpected results, such as an "Illegal Instruction", "Segmentation Fault" or "Memory Corruption Error" to name a few, this may indicate a security vulnerability that should be reviewed further.

Secure operation of a program is much more than just focusing on exploitable programs and remote code execution. Programs succeptable to just crashing can cause denial of service conditions, as well as other issues that may effect the smooth operation of a server, service or network.

Common fuzzing techniques, can help you identify a range of bugs that can make a volitile network environment. These bugs include, but are not limited to, memory leaks, serialization bugs, segmentation faults and memory corruption.

Memory Leaks are where a process is allocated memory, but that memory does not free up after use. This can create a denial of service condition by consuming all the systems available memory resources, leaving no available RAM for SYSTEM tasks and user processes.

Serialization provides persistant objects and Remote Procedure Calls (RPC) among other things.

Segmentation faults can corrupt memory, which will in turn, interrupt the execution flow of what is running.

Although there are a number of applications that automate the fuzzing process, we are only touching on the basics today, and will be learn how to manually fuzz executables for errors. Once these concepts and practices have been understood, we can delve further into more advanced fuzzers, but it's only the first class.

------------------------------------------------

Spotting problem code

While working in the security field, you will need to be able to identify code portions that are vulnerable to specific activities. Sometimes the code we look at is compiled, linked and executed, while other code we might see is scripted and run in-line, such as BASH, Python, Perl, and so on. One of the more basic pieces of problem code that we can come across, are known as a stack-overflow vulnerability.

The idea is this, when a function in a program is executed, the system environment, local variables, etc are assembled in a memory segment called the Stack. This stack is laid out in a universal format, making specific properties of this stack predictable. If certain measures are not taken when writing a program, conditions may be just right for exploitation.

The most basic example of insecure code is the following C function in abo1.c:

int main(int argv,char **argc) {
        char buf[256];

        strcpy(buf,argc[1]);
}

This function defines a character string 256 bytes long, called buf. argc[1] pulls the first argument passed after your binary was executed, and copies that character string into a 256 byte buffer.

What's the problem?
-------------------

When the string gets copied into buf through the strcpy() function, there is nothing to make sure the bounds are checked on the array. If the length of the string is not restricted by exactly how many bytes are being used, the running program will allow you to push more data into the buf variable than 256 bytes. If you have a glass that holds 1 cup of water and fill it with 2 cups, the extra water is going to spill out. When this buffer spills out, that extra data has a chance of overwriting the next CPU instruction, or even the next variable in the stack.

Further information about these effects are going to be explained during a later class, as today, our interest is in the process of fuzzing. As mentioned earlier, fuzzing in the process of sending large chunks of data to the input of a selected program.

First, we are going to have a quick primer into the Hexadecimal ASCII Table and then on to the fun!

Hexadecimal ASCII Characters
----------------------------

As defined by the manual page (man ascii) from the Linux command prompt; ASCII is the American Standard Code for Information Interchange. It is a 7-bit code.

There are 128 ASCII Characters, including control characters that can denote 'new line', 'carriage return' and 'backspace' among others. Hexadecimal is a base 16 positional numeral system, employting 16 distinct symbols. The symbols 0-9 represent the values zero to nine, while A-F (as well as a-f) represent the values 10 to fifteen. Each Hexadecimal number from \x00 to \x7F is a unique ASCII character. The following are a collection of important ASCII characters to remember.

\x41 - A
\x42 - B
...
\x49 - I
\x4A - J
\x4B - K

Notice how instead of 50 being after \x49, it went to \x4A? That is because this numerical system is base 16 as opposed to base 10, which we are used to counting with. After the 16th character (F), does the leading Hex value increase.

Other common ASCII characters would be:

\x0A - New Line (\n)
\x0D - Carriage Return (\r)

Or even the VERY popular \x20 for the space character.

Since our task at hand is fuzzing, we only need to focus on using 1 character, and any character will suffice, as long as we can recognize its pattern at a later time. For our examples we are going to stick with the letter "A", or \x41.

Fuzzing with perl
-----------------

Perl is a very handy scripting/programming language. The power behind this language gives it the ability to handle Regular Expression, also known as RegEx. RegEx provides a fast and flexible way to match and expand strings of text, numbers, etc.

Today we are going to focus on using perl to print characters to the screen, and expand the character count to a specific size that can be easily modified.

The following command will print out the standard letter "A" using perl.
----------------------------

$ perl --help

Usage: perl [switches] [--] [programfile] [arguments]
  -[octal]         specify record separator (\, if no argument)
  -a                autosplit mode with -n or -p (splits $_ into @F)
  -C[number/list]   enables the listed Unicode features
  -c                check syntax only (runs BEGIN and CHECK blocks)
  -d[:debugger]     run program under debugger
  -D[number/list]   set debugging flags (argument is a bit mask or alphabets)
  -e program        one line of program (several -e's allowed, omit programfile)
  -E program        like -e, but enables all optional features
  -f                don'
t do $sitelib/sitecustomize.pl at startup
  -F/pattern/       split() pattern for -a switch (//'s are optional)
  -i[extension]     edit <> files in place (makes backup if extension supplied)
  -Idirectory       specify @INC/#include directory (several -I'
s allowed)
  -l[octal]         enable line ending processing, specifies line terminator
  -[mM][-]module    execute "use/no module..." before executing program
  -n                assume "while (<>) { ... }" loop around program
  -p                assume loop like -n but print line also, like sed
  -P                run program through C preprocessor before compilation
  -s                enable rudimentary parsing for switches after programfile
  -S                look for programfile using PATH environment variable
  -t                enable tainting warnings
  -T                enable tainting checks
  -u                dump core after parsing program
  -U                allow unsafe operations
  -v                print version, subversion (includes VERY IMPORTANT perl info)
  -V[:variable]     print configuration summary (or a single Config.pm variable)
  -w                enable many useful warnings (RECOMMENDED)
  -W                enable all warnings
  -x[directory]     strip off text before #!perl line and perhaps cd to directory
  -X                disable all warnings
$ perl -e 'print "A" . "\n"'
A
$

----------------------------

By executing perl and passing the -e flag, I can have perl run the code that follows after the switch -e. After passing -e, I then define I want to use the 'print' function, to print the letter "A". The following '. "\n"' sends the 'new line' escape sequence to the perl interpreter, bringing my prompt down to the line below the character we just printed.

By experimenting, we can see what happens when we remove the 'new line' from the perl command.
---------------------

$ perl -e 'print "A"'
A$

---------------------

As you can see, our prompt starts directly after the character we printed to the screen.

To expand this out, we can change our perl line to read:
--------------------------------

$ perl -e 'print "A"x100 . "\n"'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

--------------------------------

Which by adding x100 after the "A", perl outputs 100 "A's" to the screen, and brings my cursor down to the new line.

How can this activity assist with the task at hand, fuzzing?

Back to our original example of insecure code, we can compile it, and try to use perl to send a bunch of data to it.

---------------------------

$ gcc -g -o abo1 abo1.c
abo1.c: In function ‘main’:
abo1.c:9: warning: incompatible implicit declaration of built-in function ‘strcpy’
$ ./abo1 blah
$

---------------------------

If you remember looking at the source code example displayed earlier, you will remember this only takes the string passed as the first command line argument while executing the binary, and copies that argument into the variable buf. It does not print anything our, or offer any more interactivity, but it is still a great platform to demonstrate unexpected consequences.

Taking a peek back at the source code, the character array 'buf' is allocated 256 bytes. Each character in a string equals one byte. To see what happens if we put more than 256 bytes into this buffer, we use perl to generate a large string of bytes.

Just as a first stab at this, lets create a 256 byte string using the letter "A". Remember the character doesn't matter, just the size of the string being passed.
--------------------------------

$ perl -e 'print "A"x256 . "\n"'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

--------------------------------

This has created a 256 byte string of the letter "A". What happens when we put this into the 256 byte buffer?
------------------------------------------

$ ./abo1 $(perl -e 'print "A"x256 . "\n"')
$

------------------------------------------
The program exited cleanly, not showing any errors, just as it did earlier with a 4 byte string using "blah"

Now lets try create a 300 byte string. Again, the specifics of what character do not matter, so we will stick with the letter "A".
--------------------------------

$ perl -e 'print "A"x300 . "\n"'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAA

--------------------------------

This has printed 300 "A's" as we had expected. Now we need to put those 300 bytes into the input of abo1.
------------------------------------------

$ ./abo1 $(perl -e 'print "A"x300 . "\n"')
Segmentation fault (core dumped)

------------------------------------------

Something broke! When a segmentation fault takes place, the memory being used by the running binary becomes segmented, and the system becomes "lost", usually from jumping to an invalid or incorrect instruction in memory. The specific events that happen will be demonstrated later, but for now, all we need to concern ourselves with, is breaking the code.

Now what?
---------

So now we know how to break a program expanding a character beyond the size of an allocated buffer using Perl. There are a large variety of ways to accomplish this using different languages and methods. Let us take a look at a few other ways of achieving these same results.

Python
------

Python is another great programming/scripting language similar to Perl. The following example shows you how to print the "A" character the same as earlier with perl.
-----------------------

$ python -c 'print "A"'
A
$

-----------------------

Did you notice that the output dropped us to a new line without having to specify "\n" like in Perl?

Now lets try expanding this character out a few bytes:
--------------------------

$ python -c 'print "A"*20'
AAAAAAAAAAAAAAAAAAAA

--------------------------

Great! Now we have a 20 byte string created by using Python this time. Let's try reproducting our crash from earlier, except using python this time.
-------------------------------------

$ ./abo1 $(python -c 'print "A"*300')
Segmentation fault (core dumped)

-------------------------------------

Yep! We were able to crash abo1 using our fuzzing method in Python as well!

We have one more method to explore using metasploit to wrap up this session. Next week, we will take a closer look at what the reason for the crash was and how to debug it.

Metasploit
----------

Metasploit is an framework designed by HD Moore, that makes up a robust platform for penetration testing. For now, we are only looking at one tool provided with metasploit, designed to assist with the fuzzing and debugging process.

When you install Metasploit, you will be left with a "framework" directory structure in the location you installed it to. For me, it is found in /var/opt/framework-4.0.0/. Inside this folder is the functional framework for using metasploit. This includes your payloads, exploits and auxillary scanners. Also included in this package is ./msf3/tools/ which are a collection of ruby scripts included with the framework.

Here we want to just concern ourselves with the script, pattern_create.rb located in the tools folder.
--------------------------------------------------------

/var/opt/framework-4.0.0/msf3/tools$ ./pattern_create.rb
Usage: pattern_create.rb length [set a] [set b] [set c]
/var/opt/framework-4.0.0/msf3/tools$ ./pattern_create.rb 300
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4
Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9
Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5
Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9

--------------------------------------------------------

This prints out 300 bytes of what appear to be random, but will play an important role in next weeks session. To use this and see if this string will cause the same results seen fuzzing with Perl and Pythin, we can copy the whole string that was output, and run ./abo1 again:
--------------------------------

$ ./abo1 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4
Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4
Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4
Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9
Segmentation fault (core dumped)

--------------------------------

It broke! But lets use the same injection method demonstrated with perl and python earlier as well;
--------------------------------

$ ./abo1 $(/var/opt/framework-4.0.0/msf3/tools/pattern_create.rb 300)
Segmentation fault (core dumped)

--------------------------------

There you have it, a few different ways to try and make a program break. Breaking programs is literally the first step in validating the security of a process. As these sessions continue, you will not only be able to identify a function that can break, but you now know how to break that function, and will soon know how to debug the function, exploit the function and make the program do the bidding of your choosing.

To give you guys a preview of this process, here is a quick demonstration of something cool you can do with this vulnerable function.
--------------------------------

$ ./abo1 $(perl -e 'print "\x41"x268 . "\xf2\xf9\xff\xbf"')
You win!

--------------------------------

Now, if you remember the source code from our example of abo1.c, there is no string printed to standard output (stdout), let alone any string that says "You win!". What differences exist between this example passed to abo1 and the ones passed earlier? And most of all, what is that in the final section of the perl code? We will see you next week to bring you deeper into the rabbit hole! ;o)

Independant Research?
---------------------

Here are a few exercies if you want to know more about some of the items discuss:

Read the ASCII manpage by typing 'man ascii' at a linux prompt.
-- Review these ASCII characters Hex values, and play with the perl -e 'print' command with them and see what they output to your screen.
-- Try doing the same using Python as well and take some notes on how python and perl are different.
-- Finding an environment you are comfortable with is VERY important to building up your tool-set and methods.
-- Google fuzzers, and see if you can find an alternative fuzzing method that makes you feel comfortable.