Lab17 Fuzzing Windows Software
Lab17 Fuzzing Windows Software
Software
LAB 17
You can connect to the lab machine via remote desktop. The target IP is 172.16.172.156
Username: eLS
Password: eLSPwdAdmin1602
In this lab’s context, we chose to run vulnserver on port 9999 (vulnserver.exe 9999)
Note: In case of choppy RDP performance, disconnect from the VPN, edit the latest .ovpn file
and switch the protocol from udp to tcp. Then, re-connect to the lab VPN using the edited
.ovpn file.
GOALS
• Automate payload generation and vulnerability identification
RECOMMENDED TOOLS
• Immunity Debugger
• Mona.py
• Spike
• Wireshark
• Kali linux
Username: eLS
Password: eLSPwdAdmin1602
SPIKE FUNDAMENTALS
According to OWASP, Fuzz testing or Fuzzing is a Black Box software testing technique,
which basically consists in finding implementation bugs using malformed/semi-malformed
data injection in an automated fashion. Fuzzing, when performed by exploit
developers/security researchers etc., focuses on discovering bugs that could lead to code
SPIKE is a protocol fuzzer creation kit. It provides an API that allows a user to create their
own fuzzers for network based protocols using the C++ programming language. The tool
defines a number of primitives that it makes available to C coders, which allows it to
construct fuzzed messages called “SPIKES” that can be sent to a network service …
That being said, you don’t have to be capable at C programming to use SPIKE. SPIKE comes
with a scripting capability and is also accompanied by some useful command line tools
which can act as interpreters to text files containing SPIKE primitives. Find below a quick
overview/description of SPIKE.
http://www.immunitysec.com/downloads/usingspike3.ppt
In the case of TCP based server applications, we can make use of this scripting capability by
writing SPIKE commands into .spk script files, and running them using the TCP SPIKE
script interpreter generic_send_tcp (pre-installed on Kali Linux), which will send the
specified SPIKE at a particular IP address and TCP port. There is also a generic_send_udp,
which will do something similar, however within this interpreter the SPIKES will be sent
over UDP.
The generic_send_tcp interpreter (which we will be using to fuzz our application), if run
without any command line parameters shows the following.
Hopefully the first three required command line options are self-explanatory, with
parameters one and two defining the host and TCP port to connect to for fuzzing, and the
third parameter defining the name of the SPIKE script file. Parameters 4 and 5 may require
some more explanation. These parameters, SKIPVAR and SKIPSTR, essentially allow you to
jump into the middle of the fuzzing session defined by a SPIKE script.
Within a SPIKE script, you may specify “s_string_variables”, which are the commands used
to insert the actual fuzzed strings into each SPIKE that you send. If you use more than one
of these “s_string_variables” in your script, you can skip using the earlier instances of
“s_string_variables” by setting an appropriate value for SKIPVAR. For example, if you
Each of the “s_string_variables” also has an array of different fuzz string values inbuilt into
SPIKE that it will iterate through within a SPIKE fuzzing session. If you want to skip the
first 10 of these strings, and start fuzzing at string 11, you can set SKIPSTR to 10 (again,
counting starts from 0).
When you use generic_send_tcp, it will output information to the command line about
which variable and string it is currently testing, so if a SPIKE session gets interrupted and
you need to continue it later on you can do so with the use of these two command line
parameters.
To start a fuzzing session from the beginning, just use “0 0” for these parameters, so to start
a fuzzing session against host 192.168.1.101 on port 9999 using script file “test.spk” from
the beginning, use the following command line
If you want to hunt through the SPIKE distribution directory, the available primitives that
we can use as commands in our script file can be discovered by examining some of the
example .spk files as well as the SPIKE header file spike.h. The spike.h file will list the
available primitives (commands), and the .spk files will provide examples of how those
commands can be used.
To save you the trouble of hunting through those files, we will list some of the more useful
SPIKE primitives for scripting below. The spike.h file, being written in C, lists each of the
SPIKE commands in C syntax, using C data types, but for the benefit of those unfamiliar
with C syntax I am going to specify the commands using an “example” format that you can
more easily reproduce when writing your scripts. The “//” notation is used in C to
designate line-based comments (everything after that point is ignored by the compiler), so
I have used this syntax below to provide additional explanatory detail for each of the
commands. You can leave these comments in when you create your SPIKE scripts, or add
your own comments, and this text will be ignored by the SPIKE interpreter.
The commands have been broken below into a number of high-level categories relating to
strings, binary data, blocks and other useful functions.
Strings
The string commands provide a way of adding ASCII character data into your SPIKES. Also
included within the string commands is the s_string_variable command, one of the most
important commands within SPIKE as it actually allows you to add fuzz strings to your
SPIKE.
Binary Data
For the binary commands in SPIKE, various other methods for specifying the same data are
also available. To output the same hex character as shown above, we could use “41” or
“0x41” as well, and we can also mix and match these values, (e.g. “410×41\\x42” to output
ASCII “AAB”). Any added white space is also ignored. All of this combines to allows easy
cutting and pasting from a variety of different applications that represent data in Hex
format, such as packet capture tools, debuggers, etc.
Defining Blocks
Block defining commands allow you to specify the start and end points of a named block
within a SPIKE script. This allows you to define the size of those sections of data in your
SPIKES using block size commands.
Block Sizes
Block size commands allow you to insert the size of data inside a named block inside the
SPIKES generated by your script, using a variety of different size formats.
These are just two examples from the many ways of how block size can be added to a
SPIKE. There are other methods too, that can allow you to represent block size in a large
To see some of the other options, simply perform a grep on the spike.h file in the SPIKE src
directory for the strings “block_size” or “blocksize”.
Other useful commands are those that don’t fit into any of the other categories previously
mentioned.
• s_read_packet(); // Reads and prints to screen data received from the server
• s_readline(); // Reads a single line of input from the server
You can also use general C language functions within SPIKE scripts, to give you additional
scripting capabilities. One particularly useful function is printf(), which can be used to
output data to the terminal, which can give our scripts more informative console output.
The following is an example SPIKE script that could be used to fuzz the inputvar variable in
php script testme.php via a POST request to testserver.example.com.
s_string("Host: testserver.example.com\r\n");
s_string("Content-Length: ");
s_blocksize_string("block1", 5);
s_string("\r\nConnection: close\r\n\r\n");
s_block_start("block1");
s_string_variable("inputval");
s_block_end("block1");
This script essentially specifies a message like the below, where [fuzz_string] represents
the location where the SPIKE fuzz strings will be inserted into the message, and
[size_of_data] represents the size of the data section of the POST request, which contains
the fixed string “inputvar=” and the variable data of the fuzz string. This size field will be
automatically updated as the fuzz string changes.
Host: testserver.example.com
Content-Length: [size_of_data]
Connection: close
inputvar=[fuzz_string]
TASKS
TASK 1: INTERACT WITH THE REMOTE VULNSERVER
First, log in to the remote machine (172.16.172.156) and start vulnserver (vulnserver.exe
9999)
Back to your attacking machine, use netcat to interact with the remote vulnserver. Try to
identify its commands and their parameters.
SKIPSTR is used when we want to commence fuzzing from a specific string onwards. If
SKIPSTR is zero, then all available strings will be transmitted and tested.
• If commands that support parameters are invoked without one, we get an UKNOWN
COMMAND response
For example, to fuzz the TRUN command, we can use the below template (let’s name it
trun.spk).
s_readline();
s_string("TRUN ");
s_string_variable("COMMAND");
We notice that packets are successfully transmitted and vulnserver crashes shortly after we
began our fuzzing activities.
Don’t forget to press the start button (or F9) so that vulnserver resumes its operations.
We should follow the TCP conversations to learn more about the crash. We are specifically
looking for conversations that don’t include “TRUN COMPLETE”. If the remote server
crashed, “TRUN COMPLETE” will be missing from the conversation.
Note that the crash took place at item "0:1". If we want to keep searching for other crashes,
we can continue where we left off, as follows.
#!/usr/bin/python
import socket
server = '172.16.172.156'
sport = 9999