Advanced Fuzzing
Advanced Fuzzing
Advanced Fuzzing
click on the new line icon, and click to the "..." icon.
Select the openssl install directory, within that the include directory: "C:\OpenSSL-Win32\include"
At the new windows add the libeay32MD.lib and ssleay32MD.lib files from the openssl install
directory \ lib \ VC \ static, then click to the OK button.
We will get the next:
then right click to the Solution and from the popup menu select the Add \ New Project ... command.
Select the Win32 \ Win32 Console Application. Give it a name, and click to the OK button.
Right click again to the "Source Files" of this project, and select the Add \ New Item ... command
Select the C++ file from the dialog box, and give a name to the file:
Then right click to this project, and select the properties command from the popup menu.
peel the ssl layer
Unfortunately the traffic is ssl encrypted. If we were just try to fuzz it in this way we were fuzz only
the openssl layer, but we want to fuzz the encrypted data within the ssl tunnel. To do it we must peel
the ssl layer.
To do it we need a certificate (we will use now the openssl to generate one, but any other method
can be used). The windows version can be downloaded for example from the next URL:
http://www.openssl.org
And we need the Stunnel application. The Stunnel is able to create an ssl tunnel for us.
Encrypted traffic
chatclient.exe chatclient.exe
Stunnel at 0.0.0.0:1234
Decrypted traffic. We watch it („chatserver“)
with network monitor. We send it
to other machine, because most
network monitor not capable to
listen at 127.0.0.1
Install Openssl on the usual way, then go to the new openssl directory:
cd C:\OpenSSL-Win32\bin
openssl req -config openssl.cfg -new -x509 -days 1001 -key ca.key
-out ca.cer
by default the openssl want to use the demoCA directory so we crate it:
cd \OpenSSL-Win32\bin
md demoCA
cd demoCA
md newcerts
cd ..
from the popup window select certificate then press the add button
in the new window select computer account then click on the next button
Select local computer, then click to the finish button:
now our root certificate is created and accepted by the computer, we has to create the two
certificates for the two stunnel. For this we must create a request, it can be done by openssl as well,
but in that case you should edit the openssl.cnf file, to use the webserver template, so I used the IIS,
to generate a request, and only signed that with the openssl.
To do this start the IIS management console Startmenu \ control panel \ Administrative tools
Open a command prompt, and convert the cer and pfx file to the format required by stunnel:
cd \OpenSSL-Win32\bin
openssl x509 -inform der -in iis1.cer -out iis1.pem
openssl pkcs12 -in iis1.pfx -out iis1.key -nodes -nocerts
Enter Import Password:
Start the Stunnel to listen on port 6789 and forward what it get to 192.168.168.101:1234
After it we should create two config files for the Stunnel, the first on the machine where the chat
server runs save save it to the (c:\Program Files\stunnel).
stunnel.conf:
fips = no
cert = iis1.pem
key = iis1.key
[mylistener]
accept = 6789
connect = 192.168.168.101:1234
stunnel.exe
netstat /na
Also the two Stunnel icon must be seen next to the clock on the notification area.
We should create another conf file for the other machine (because our sample application is quite
simple, we should allow all chiphers, including the anonymous ones):
stunnel.conf:
ciphers = ALL:eNULL
fips = no
[masik]
client = yes
accept = 1234
connect = 127.0.0.1:9999
stunnel.exe
Encrypted traffic
chatclient.exe
Machine 1 Machine 2
now start the wireshark, to captore the traccic toing to or comming from the tcp port 1234:
Start the client application at two machines, and send some text from one to the other.
The stop the capture, and close the chat clints and server. We will capture the uncrypted data.
But as we can see the wireshark does not understand our protocol. In this way it is quite difficult, to
analyze what is going on. So our first task (it is not mandatory, just makes our later job easier). To
use the wireshark we should write a custom dissector. It can be written in C or in LUA languages.
Now we will do it in LUA, because that is a bit easier than the C.
Communication flow between the client and server
Process of connection
Client Server
Client Server
Client Server
Client Server
Message
Protocol creation
To create a dissector first we must register a new protocol to the wireshark. To do it we create a
Protocol object. It requires two input parameters, a protocol name, and a description. Also we can
define the fields of the protocol for filtering an other purposes. I did not need it so I left the field list
empty. It is done by the next two lines, it will be the first two lines of our dissector:
init function
If we create a protocol we must define two functions the init function, and the dissector function.
The init function is called once when the protocol first called, and it has no input parameters. Now I
do not want to do anything at the initialization state so it will be an empty function, and it remains
that:
function p_myproto.init()
end
Dissector Function
The dissector function has three input variables, the packet itself, now I will call it as buf. The
packet metadata now I will call it as pkt. And finally the root shows, where are we in the protocol
tree.
Register Protocol
After created we should register the protocol in wireshark. We will register it to the TCP port 8000
because I started to use that one to see the decrypted traffic. Before we register our protocol to that
port we save the original protocol connected to that TCP port (most probably there is nothing, and
we do not want to use it, but who knows what need later, better to have it). It can be done with the
next code segment:
This script does not do anything yet, so we can start to develop the dissector part.
Set the protocol name to our protocols name in the Protocol column
pkt.cols.protocol = p_myproto.name
actualpos=0
outertree = root:add(p_myproto, buf(0))
now we can start to analyze the packet. The header length is 5 bytes so we start a cycle until there is
more than 5 byte unprocessed data in the packet.
length=0
cmdstr = " = UNKNOWN"
cmd=0
cmd = buf(actualpos+4,1):uint()
length = buf(actualpos+0,4):le_uint()
Now we should check if there is every data in the buffer (the TCP can break the data to more
packets, and it may be only a part of it). If the length in the packet is more than the remaining part
of the packet then we should read the next packet as well. To do it we set the pkt. desegment_offset
to the actual position because we want to continue the dissection process from that position. And we
tell in the pkt.desegment_len variable how many bytes missing. Then we return, and pass back the
pkt structure, to sign to the wireshark we want to read more data.
We create a new branch within our tree to this message. It is done by the outertree:add command,
the outertree variable stores our subtree created not long ago, it will contain our protocol, and it
represents the bytes from actual position till the end of the message we must add 5 because the
message size does not contains the header size what 5 bytes. Then within this branch we create a
leaf by the subtree:add command. The first four bytes represent the length of the message and as
description we give it “Length: “ concatenated with the length we read (the two points are
concatenation)
unfortunately there is no case in LUA so we must examine the value of cmd by lot of ifs to print out
the internal message structure based on the message type.
- We check if the value of cmd is 0x01 what means Client Connect Request.
- We set the cmdstr to “ Client Connect Request”
- add a new leaf 1 bytes from the position 4 represents the command, we highlight it, and type as
description the byte code of the message, and the meaning of it. As we already know this type of
message contains the following fields:
-- Version 4 bytes number,
-- offset of the username 2 bytes little endian data,
-- magic value a string,
-- username string starts from the offset position was given in the offset
Finally we add to the outer subtree the message type to be nicer, and we move the actualpos to the
end of this block.
subtree:append_text(cmdstr)
actualpos=actualpos+5+length
Now save the previous capture, and restart the wireshark. Then evaluate this LUA script as already
described. Then load the previously saved capture.
Now when you check the first packet you can see, instead of the previous TCP data the meaning of
the different bytes are nicely visible.
end
if cmd == 0x20 then
cmdstr = " Client Send Message"
subtree:add(buf(actualpos+4,1)," Command : " .. cmd ..
cmdstr)
messagelength = buf(actualpos+5,4):le_uint()
subtree:add(buf(actualpos+5,4)," message Length : " ..
messagelength)
subtree:add(buf(actualpos+9,messagelength)," Message : " ..
buf(actualpos+9,messagelength):string())
subtree:add(buf(actualpos+9+messagelength,4)," SenderID :
" .. buf(actualpos+9+messagelength,4):le_uint())
subtree:add(buf(actualpos+13+messagelength,4)," TargetID : "
.. buf(actualpos+13+messagelength,4):le_uint())
subtree:add(buf(actualpos+17+messagelength,4)," MetadataSize
: " .. buf(actualpos+17+messagelength,4):le_uint())
subtree:add(buf(actualpos+21+messagelength,4)," Flags : " ..
buf(actualpos+21+messagelength,4):le_uint())
subtree:add(buf(actualpos+25+messagelength,4)," Color : " ..
buf(actualpos+25+messagelength,4):le_uint())
subtree:add(buf(actualpos+29+messagelength,4)," FontSize : "
.. buf(actualpos+29+messagelength,4):le_uint())
subtree:add(buf(actualpos+33+messagelength,8)," Time : " ..
buf(actualpos+33+messagelength,8):le_uint64())
end
To create the whole datamodel from nothing can be a bit time consuming, but fortunately the peach
fuzzer has a small tool at the C:\peach\tools directory called struct2peach.pl, what is able to create
the data models from a C++ header file. Of course this have some limitations:
cd c:\peach\tools
struct2peach.pl little < c:\test\test\mychatsrv.h > out.xml
Another method what is effective, if we want to fuzz data included in one network packet. In this
case we can export the packet from wireshark in xml format, and use the peachshark included in the
peach fuzzer, to generate the data model from it. It requires that, the wireshark should have a
dissector to the protocoll (but we just created one, so it is fine now). See an example to this as well.
We already captured a traffic when the client sent message. It was the 18th packet, and our dissector
compiled shows the details of it.
now select the file \ export \ file command
in the next window select the place where you want to save the packet, the format should be PDML
XML packet detail, and it should contain only ONE packet, because the peachshark is only capable
to decode one packet a time. And select "selected packet" Packet Range.
Open the exported pdml (xml) file, you will see something like this:
from here you can read the name of the protocol we want to create the datamodel from is the
"myproto" (we already knew it, because we created the dissector, but we checked it to be sure).
Now use the following command, to create the datamodel:
We want to simulate us a bad client tries toattack the other clients and server. In drawing it is the
following:
Encrypted traffic
Stunnel at chatclient.exe
0.0.0.0:9999
(„chatserver“) WinDBG
Dencrypted traffic
Peach agent
Peach fuzzer
WinDBG
Because we have a lot of different packets we will use the file generated by the struct2peach. It
looks like as:
<!-- #
#################################################################
-->
</Peach>
So we always see the original line in the header file, and the translated line. Sometimes we can find
something like:
<datamodel name="something">
<!-- original line in the header file -->
<!-- Unknown type: xxx -->
...
</datamodel>
it means, that data type is not a nativ C data type, so it is not included in the struct2peach, so it
could not translate it. We has to do it by hand, and we shouldadd the logical connections between
the elements.
Now open a command line, and enter to the peach directory, then test the chat.xml file:
cd c:\peach
peach -t chat.xml
As we can see we get a nice error message. First we correct the peach file, to be able to test, if we
do any systax error.
<Publisher class="tcp.Tcp">
<Param name="host" value="192.168.168.101"/>
<Param name="port" value="1234"/>
</Publisher>
Then copy the original version inside it after the <datamodel name="thedatamodel">...</datamodel
section>. I recommend it, because now if you have a good xml editor the schema is validated, and
it helps you in the typing. You will get something like:
As we can see the MsgTime, and the Flags has unknown data types, so correct those ones, and
delete the unnecessery comment line. The MsgTime is 8 bytes (64 bit) long. So we can write it as:
The flags are 4 byte (32 bit) long, so it can be written as:
<DataModel name="ChatClientSendMsgFoot">
<Number name="SenderID" size="32" endian="little" signed="true" />
<Number name="TargetID" size="32" endian="little" signed="true" />
<Number name="MetadataSize" size="32" endian="little"
signed="true" />
<Number name="Flags" size="32" endian="little" signed="true" />
<Number name="Color" size="32" endian="little" signed="true" />
<Number name="FontSize" size="32" endian="little" signed="true" />
<Number name="MsgTime" size="64" endian="little" signed="true" />
</DataModel>
We know from the protokoll diagram, the "MetadataSize" is nothing else, but the size of the next
four elements (flags, color, fontsize, and msgtime) together. To be able to add the size reference we
shuold put these four elements into a block, then the model will change to:
<DataModel name="ChatClientSendMsgFoot">
<Number name="SenderID" size="32" endian="little" signed="true" />
<Number name="TargetID" size="32" endian="little" signed="true" />
<Number name="MetadataSize" size="32" endian="little"
signed="true" />
<Number name="Flags" size="32" endian="little" signed="true" />
<Number name="Color" size="32" endian="little" signed="true" />
<Number name="FontSize" size="32" endian="little" signed="true" />
<Number name="MsgTime" size="64" endian="little" signed="true" />
</DataModel>
<DataModel name="ChatClientSendMsgFoot">
<Number name="SenderID" size="32" endian="little" signed="true" />
<Number name="TargetID" size="32" endian="little" signed="true" />
<Number name="MetadataSize" size="32" endian="little"
signed="true">
<Relation type="size" of="Metadata"/>
</Number>
<Block name="Metadata">
<Number name="Flags" size="32" endian="little" signed="true" />
<Number name="Color" size="32" endian="little" signed="true" />
<Number name="FontSize" size="32" endian="little"
signed="true" />
<Number name="MsgTime" size="64" endian="little"
signed="true" />
</Block>
</DataModel>
One might recognized, we just defined the Flags as a simple 4 byte (32 bit) integer value, but in
reality those are flags, so every bit has some meaning. The meaning itself is defined in the header
file (in the MsgFlags type). The question, if we want to define the meaning of every bit, or
enough, to handle the flags as a four byte number. It depends on your decision. I write that version
as well:
<DataModel name="ChatClientSendMsgFoot">
<Number name="SenderID" size="32" endian="little" signed="true" />
<Number name="TargetID" size="32" endian="little" signed="true" />
<Number name="MetadataSize" size="32" endian="little"
signed="true">
<Relation type="size" of="Metadata"/>
</Number>
<Block name="Metadata">
<Flags name="Flags" size="32" endian="little">
<Flag name="colorincluded" size="1" position="0"></Flag>
<Flag name="fontsizeincluded" size="1" position="1"></Flag>
<Flag name="timeincluded" size="1" position="2"></Flag>
</Flags>
<Number name="Color" size="32" endian="little" signed="true" />
<Number name="FontSize" size="32" endian="little"
signed="true" />
<Number name="MsgTime" size="64" endian="little" signed="true" />
</Block>
</DataModel>
If you similarly copy and modify all the datamodels you by in the struct2peach you will get
something like the next chat.xml file:
<DataModel name="ChatHeader">
<Number name="MsgSize" size="32" endian="little"
signed="true" />
<Number name="MsgType" size="8" signed="false"></Number>
</DataModel>
<DataModel name="ChatServerSendAck">
<Flags name="AckFlags" size="32" endian="little">
<Flag name="accept" size="1" position="0"></Flag>
</Flags>
</DataModel>
<DataModel name="ChatServerConnectResponse">
<Flags name="AckFlags" size="32" endian="little">
<Flag name="accept" size="1" position="0"></Flag>
</Flags>
<Number name="PeerID" size="32" endian="little"
signed="true" />
</DataModel>
<DataModel name="ChatClientConnectRequest">
<Number name="ClientVer" size="32" endian="little"
signed="true" />
<Number name="UsernameOffset" size="16" endian="little"
signed="true">
<Relation type="offset" of="UserName"/>
</Number>
<String name="Magic" value="CHAT" nullTerminated="false"
type="char"></String>
<String name="UserName" nullTerminated="false"
type="char"></String>
</DataModel>
<DataModel name="ChatClientSendMsgHead">
<Number name="MsgLength" size="32" endian="little"
signed="true" />
</DataModel>
<DataModel name="ChatClientSendMsgFoot">
<Number name="SenderID" size="32" endian="little"
signed="true" />
<Number name="TargetID" size="32" endian="little"
signed="true" />
<Number name="MetadataSize" size="32" endian="little"
signed="true">
<Relation type="size" of="Metadata"/>
</Number>
<Block name="Metadata">
<Flags name="Flags" size="32" endian="little">
<Flag name="colorincluded" size="1" position="0"></Flag>
<Flag name="fontsizeincluded" size="1"
position="1"></Flag>
<Flag name="timeincluded" size="1" position="2"></Flag>
</Flags>
<Number name="Color" size="32" endian="little" signed="true"
/>
<Number name="FontSize" size="32" endian="little"
signed="true" />
<Number name="MsgTime" size="64" endian="little"
signed="true" />
</Block>
</DataModel>
<DataModel name="ChatServerDeliverMsgHead">
<Number name="MsgLength" size="32" endian="little"
signed="true" />
</DataModel>
<DataModel name="ChatServerDeliverMsgFoot">
<Number name="SenderID" size="32" endian="little"
signed="true" />
<Number name="TargetID" size="32" endian="little"
signed="true" />
<Number name="MetadataSize" size="32" endian="little"
signed="true">
<Relation type="size" of="Metadata"/>
</Number>
<Block name="Metadata">
<Flags name="Flags" size="32" endian="little">
<Flag name="colorincluded" size="1" position="0"></Flag>
<Flag name="fontsizeincluded" size="1"
position="1"></Flag>
<Flag name="timeincluded" size="1" position="2"></Flag>
</Flags>
<Number name="Color" size="32" endian="little" signed="true"
/>
<Number name="FontSize" size="32" endian="little"
signed="true" />
<Number name="MsgTime" size="64" endian="little"
signed="true" />
</Block>
</DataModel>
<DataModel name="ChatClientStatusAck">
<Flags name="AckFlags" size="32" endian="little">
<Flag name="accept" size="1" position="0"></Flag>
</Flags>
</DataModel>
<DataModel name="ChatClientDeliverAck">
<Flags name="AckFlags" size="32" endian="little">
<Flag name="accept" size="1" position="0"></Flag>
</Flags>
</DataModel>
<DataModel name="ChatServerStatusMsg">
<Flags name="ServerStatusFlags" size="32" endian="little">
<Flag name="accept" size="1" position="0"></Flag>
</Flags>
<Number name="TargetID" size="32" endian="little"
signed="true" />
</DataModel>
Now we let us think over what we have done until now. We created all the data models separately,
but in the commonication flow we see that, some of them are connetced. The best example is the
header. It is at the beginning of every sent or received packet. We can copy the ChatHeader
datamodel to the beginning of every other datamodel, but that is obviously a very inefficient
solution, if something chages the modification will be difficult. So we do something else. We can
reference in a datamodel to another one, then the content of the referenced thatamodel will be
included in the new one, and obviously new elements can be added, or existing in the referenced
one could be overdefined. I do again the ChatClientSendMsgFoot as an example.
Copy the ChatHeader datamodel, and let us start to modify (we copy it, because we will need
sometimes the not modified version, as I will show)
<DataModel name="ChatHeader">
<Number name="MsgSize" size="32" endian="little" signed="true" />
<Number name="MsgType" size="8" signed="false"></Number>
</DataModel>
Now modify it. First rename it to ChatHeaderWithBlock. Then add to the end of it a new Block
element, After it we are able to add the logical constraint, the MsgSize should be equal to the size of
the MsgData:
<DataModel name="ChatHeaderWithBlock">
<Number name="MsgSize" size="32" endian="little" signed="true">
<Relation type="size" of="MsgData" />
</Number>
<Number name="MsgType" size="8" signed="false"></Number>
<Block name="MsgData">
</Block>
</DataModel>
As we can see the MsgData block is left empty. Obviously, because it will contain different element
in different cases.
Again I recommend to test it after the modification, it helps to find if one do a syntax or other error.
After the modification of the other datamodels the chat.xml file looks like about this:
<DataModel name="ChatHeader">
<Number name="MsgSize" size="32" endian="little" signed="true"
/>
<Number name="MsgType" size="8" signed="false"></Number>
</DataModel>
<DataModel name="ChatHeaderWithBlock">
<Number name="MsgSize" size="32" endian="little"
signed="true">
<Relation type="size" of="MsgData" />
</Number>
<Number name="MsgType" size="8" signed="false"></Number>
<Block name="MsgData">
</Block>
</DataModel>
<DataModel name="ChatClientSendMsgHead">
<Number name="MsgLength" size="32" endian="little"
signed="true" />
</DataModel>
<DataModel name="ChatClientSendMsgFoot">
<Number name="SenderID" size="32" endian="little"
signed="true" />
<Number name="TargetID" size="32" endian="little"
signed="true" />
<Number name="MetadataSize" size="32" endian="little"
signed="true">
<Relation type="size" of="Metadata"/>
</Number>
<Block name="Metadata">
<Flags name="Flags" size="32" endian="little">
<Flag name="colorincluded" size="1" position="0"></Flag>
<Flag name="fontsizeincluded" size="1"
position="1"></Flag>
<Flag name="timeincluded" size="1" position="2"></Flag>
</Flags>
<Number name="Color" size="32" endian="little" signed="true"
/>
<Number name="FontSize" size="32" endian="little"
signed="true" />
<Number name="MsgTime" size="64" endian="little"
signed="true" />
</Block>
</DataModel>
<DataModel name="ChatClientSendMsg" ref="ChatHeaderWithBlock">
<Block name="MsgData.Head" ref="ChatClientSendMsgHead">
<Number name="MsgLength" size="32" endian="little"
signed="true">
<Relation type="size" of="MsgData.Message"/>
</Number>
</Block>
<String name="MsgData.Message" nullTerminated="false"
type="char"></String>
<Block name="MsgData.Foot" ref="ChatClientSendMsgFoot">
</Block>
</DataModel>
<DataModel name="ChatServerDeliverMsgHead">
<Number name="MsgLength" size="32" endian="little"
signed="true" />
</DataModel>
<DataModel name="ChatServerDeliverMsgFoot">
<Number name="SenderID" size="32" endian="little"
signed="true" />
<Number name="TargetID" size="32" endian="little"
signed="true" />
<Number name="MetadataSize" size="32" endian="little"
signed="true">
<Relation type="size" of="Metadata"/>
</Number>
<Block name="Metadata">
<Flags name="Flags" size="32" endian="little">
<Flag name="colorincluded" size="1" position="0"></Flag>
<Flag name="fontsizeincluded" size="1"
position="1"></Flag>
<Flag name="timeincluded" size="1" position="2"></Flag>
</Flags>
<Number name="Color" size="32" endian="little" signed="true"
/>
<Number name="FontSize" size="32" endian="little"
signed="true" />
<Number name="MsgTime" size="64" endian="little"
signed="true" />
</Block>
</DataModel>
<DataModel name="ChatServerDeliverMsg"
ref="ChatHeaderWithBlock">
<Block name="MsgData.Head" ref="ChatServerDeliverMsgHead">
<Number name="MsgLength" size="32" endian="little"
signed="true">
<Relation type="size" of="MsgData.Message"/>
</Number>
</Block>
<String name="MsgData.Message" nullTerminated="false"
type="char"></String>
<Block name="MsgData.Foot" ref="ChatServerDeliverMsgFoot">
</Block>
</DataModel>
Now we finished the datamodels so we can start to create the state model. It controls the order of
messages we send and receive.
We can create a lot of different state model depending on which part of the communication we want
tot test. First we creaete a simple state model to fuzz only the connection request, and later we
extend it.
The connection is quite easy, we just do the TCP connection, and after that we send a
ChatClientConnectRequest message. And this is all, practically we are even not interested about the
answer of the server. If there is any error it will freeze, what we will detect by the debugger..
The job of the agent is to monitor the server, and the other client, what is a real one. To do a clear
test we want to restart both the server and the real client at every test circle. Because of it we have
to use the process.Process monitor class (the debugger.WindowsDebugEngine monitor is also
capable to start a new process, if you give it the CommandLine parameter, but that is not capable to
restart the process for every test circle).
We should start the server process, then the client process, it means two monitosr, then we should
attach to the started processes by the debugger.WindowsDebugEngine monitor. It can be done on
the following way:
If we want to monitor the Heap in more detail then we can use the process.PageHeap monitor as
well, I added it to this example too.
<Agent name="TheAgent">
<Monitor class="process.Process">
<Param name="Command" value="C:\test\Release\server.exe"/>
<Param name="RestartOnEachTest" value="true"/>
</Monitor>
<Monitor class="debugger.WindowsDebugEngine">
<Param name="ProcessName" value="Server.exe"/>
</Monitor>
<Monitor class="process.PageHeap">
<Param name="Executable" value="Server.exe"/>
</Monitor>
<Monitor class="process.Process">
<Param name="Command" value="C:\test\Release\Client.exe"/>
<Param name="RestartOnEachTest" value="true"/>
</Monitor>
<Monitor class="debugger.WindowsDebugEngine">
<Param name="ProcessName" value="Client.exe"/>
</Monitor>
<Monitor class="process.PageHeap">
<Param name="Executable" value="Client.exe"/>
</Monitor>
</Agent>
The last step is to create the test itself, it does nothing else, but start to call the previously defined
state model, and use the Agent. The default written in the template.xml is almost good, the only
thing we should do is to enable the usage of the agent
<Test name="TheTest">
<!-- TODO: Enable Agent -->
<Agent ref="TheAgent"/>
<StateModel ref="TheState"/>
<!-- TODO: Configure a publisher -->
<Publisher class="tcp.Tcp">
<Param name="host" value="192.168.168.101"/>
<Param name="port" value="1234"/>
</Publisher>
<!-- OPTIONAL: Configure a strategy -->
<!-- <Strategy class=""/> -->
</Test>
This is the last part of the xml file, if one want to modify the logging behaviour, shold modify it, for
me now the default in the template.xml is good, so I do not modify it.
<DataModel name="ChatHeader">
<Number name="MsgSize" size="32" endian="little" signed="true"
/>
<Number name="MsgType" size="8" signed="false"></Number>
</DataModel>
<DataModel name="ChatHeaderWithBlock">
<Number name="MsgSize" size="32" endian="little"
signed="true">
<Relation type="size" of="MsgData" />
</Number>
<Number name="MsgType" size="8" signed="false"></Number>
<Block name="MsgData">
</Block>
</DataModel>
<DataModel name="ChatClientSendMsgHead">
<Number name="MsgLength" size="32" endian="little"
signed="true" />
</DataModel>
<DataModel name="ChatClientSendMsgFoot">
<Number name="SenderID" size="32" endian="little"
signed="true" />
<Number name="TargetID" size="32" endian="little"
signed="true" />
<Number name="MetadataSize" size="32" endian="little"
signed="true">
<Relation type="size" of="Metadata"/>
</Number>
<Block name="Metadata">
<Flags name="Flags" size="32" endian="little">
<Flag name="colorincluded" size="1" position="0"></Flag>
<Flag name="fontsizeincluded" size="1"
position="1"></Flag>
<Flag name="timeincluded" size="1" position="2"></Flag>
</Flags>
<Number name="Color" size="32" endian="little" signed="true"
/>
<Number name="FontSize" size="32" endian="little"
signed="true" />
<Number name="MsgTime" size="64" endian="little"
signed="true" />
</Block>
</DataModel>
<DataModel name="ChatClientSendMsg" ref="ChatHeaderWithBlock">
<Block name="MsgData.Head" ref="ChatClientSendMsgHead">
<Number name="MsgLength" size="32" endian="little"
signed="true">
<Relation type="size" of="MsgData.Message"/>
</Number>
</Block>
<String name="MsgData.Message" nullTerminated="false"
type="char"></String>
<Block name="MsgData.Foot" ref="ChatClientSendMsgFoot">
</Block>
</DataModel>
<DataModel name="ChatServerDeliverMsgHead">
<Number name="MsgLength" size="32" endian="little"
signed="true" />
</DataModel>
<DataModel name="ChatServerDeliverMsgFoot">
<Number name="SenderID" size="32" endian="little"
signed="true" />
<Number name="TargetID" size="32" endian="little"
signed="true" />
<Number name="MetadataSize" size="32" endian="little"
signed="true">
<Relation type="size" of="Metadata"/>
</Number>
<Block name="Metadata">
<Flags name="Flags" size="32" endian="little">
<Flag name="colorincluded" size="1" position="0"></Flag>
<Flag name="fontsizeincluded" size="1"
position="1"></Flag>
<Flag name="timeincluded" size="1" position="2"></Flag>
</Flags>
<Number name="Color" size="32" endian="little" signed="true"
/>
<Number name="FontSize" size="32" endian="little"
signed="true" />
<Number name="MsgTime" size="64" endian="little"
signed="true" />
</Block>
</DataModel>
<DataModel name="ChatServerDeliverMsg"
ref="ChatHeaderWithBlock">
<Block name="MsgData.Head" ref="ChatServerDeliverMsgHead">
<Number name="MsgLength" size="32" endian="little"
signed="true">
<Relation type="size" of="MsgData.Message"/>
</Number>
</Block>
<String name="MsgData.Message" nullTerminated="false"
type="char"></String>
<Block name="MsgData.Foot" ref="ChatServerDeliverMsgFoot">
</Block>
</DataModel>
Then wait.
This state model fuzz only the login process of the chat client, but most probably we want to fuzz as
the client sends the message.
To do it we mnodify the state model. After we sent the ChatClientConnectRequest we should wait
for a ChatServerConnectResponse packet.
When we got the ChatServerConnectResponse packet we should check in it, if the server accepted
the connect request or not. If not we should go to the end, and start a new test cycle. If the server
accepted the connection we should send a message. To do it we should examine the received packet.
It can be done by the changestate action. This action jumps to another state, and it has a when
attribute, where we can write the condition of the jump.
But to jump to another state we should define more states. Now I define the following one:
• Initial: it will do the TCP connection, and immediately after the commection jump to the
next (doconnection) state without any condition:
<State name="Initial">
<Action type="connect"></Action>
<Action name="changetodoconnection" type="changeState"
ref="doconnection"></Action>
</State>
<State name="doconnection">
<Action type="output">
<DataModel ref="ChatClientConnectRequest">
</DataModel>
<Data DataModel="ChatClientConnectRequest">
<Field name="MsgType" value="0x01" valueType="hex"/>
<Field name="MsgData.ClientVer" value="0x00000001"
valueType="hex"/>
<Field name="MsgData.Magic" value="CHAT"/>
<Field name="MsgData.UserName" value="USER00"/>
</Data>
</Action>
<Action name="ReceiveServerConnectResponse" type="input">
<DataModel ref="ChatServerConnectResponse"/>
</Action>
<Action name="CheckIfServerConnectResponse" type="changeState"
ref="End" when="int(StateModel['doconnection']
['ReceiveServerConnectResponse']['ChatServerConnectResponse']
['MsgType'].getInternalValue()) != 2"></Action>
<Action name="CheckIfConnectionRejected" type="changeState"
ref="End" when="int(StateModel['doconnection']
['ReceiveServerConnectResponse']['ChatServerConnectResponse']
['MsgData']['AckFlags']['accept'].getInternalValue()) !=
1"></Action>
<Action name="changetodosendmessage" type="changeState"
ref="dosendmessage"></Action>
</State>
• dosendmessage: we must create the the message, but again we have a probem, the server
just sent us a peerID, and we should set the senderID exactly to this value. To do this we use
another action type, what is called slurp. This element is capable to copy a value from one
element to another element. In case of slurp one must define the source, and the destination
in the format of //State//actionname//valuename. If the valuename contains point ve shoud
separate those.instead of point by a // (practically we should define the path to the element
we want to copy and every level is separated by //).
<State name="dosendmessage">
<Action type="slurp"
valueXpath="//doconnection//ReceiveServerConnectResponse//MsgData/
/PeerID" setXpath="//doChatClientSendMsg//SenderID" />
<Action name="doChatClientSendMsg" type="output">
<DataModel ref="ChatClientSendMsg"></DataModel>
<Data DataModel="ChatClientSendMsg">
<Field name="MsgType" value="0x10" valueType="hex"/>
</Data>
</Action>
<Action name="changetodosendmessage" type="changeState"
ref="End"></Action>
</State>
• End: this is the last state, it close the TCP connection, and we can step to the next iteration
<State name="End">
<Action type="close"></Action>
</State>
All these these modifications together will give the next state model:
<State name="doconnection">
<Action type="output">
<DataModel ref="ChatClientConnectRequest">
</DataModel>
<Data DataModel="ChatClientConnectRequest">
<Field name="MsgType" value="0x01" valueType="hex"/>
<Field name="MsgData.ClientVer" value="0x00000001"
valueType="hex"/>
<Field name="MsgData.Magic" value="CHAT"/>
<Field name="MsgData.UserName" value="USER00"/>
</Data>
</Action>
<Action name="ReceiveServerConnectResponse" type="input">
<DataModel ref="ChatServerConnectResponse"/>
</Action>
<Action name="CheckIfServerConnectResponse" type="changeState"
ref="End" when="int(StateModel['doconnection']
['ReceiveServerConnectResponse']['ChatServerConnectResponse']
['MsgType'].getInternalValue()) != 2"></Action>
<Action name="CheckIfConnectionRejected" type="changeState"
ref="End" when="int(StateModel['doconnection']
['ReceiveServerConnectResponse']['ChatServerConnectResponse']
['MsgData']['AckFlags']['accept'].getInternalValue()) !=
1"></Action>
<Action name="changetodosendmessage" type="changeState"
ref="dosendmessage"></Action>
</State>
<State name="dosendmessage">
<Action type="slurp"
valueXpath="//doconnection//ReceiveServerConnectResponse//MsgData/
/PeerID" setXpath="//doChatClientSendMsg//SenderID" />
<Action name="doChatClientSendMsg" type="output">
<DataModel ref="ChatClientSendMsg"></DataModel>
<Data DataModel="ChatClientSendMsg">
<Field name="MsgType" value="0x10" valueType="hex"/>
</Data>
</Action>
<Action name="changetodosendmessage" type="changeState"
ref="End"></Action>
</State>
<State name="End">
<Action type="close"></Action>
</State>
</StateModel>