s_group concept

164 views
Skip to first unread message

Bruno Melo

unread,
May 11, 2017, 6:07:56 PM5/11/17
to boofuzz
Hi all,

First of all, nice work on forking Sulley! It was surely needed, and I hope (and look forward) to help and contribute with this project.

I'm new to boofuzz (or Sulley, for that matter), and thus I'm reading the classic Sulley Manual [1] to grasp the basics.
I got really intrigues with some design decisions so far, but one really got me: what is the use of s_group? I'm talking about the "Groups" concept, under "Blocks" on [1].

From [1], the example use is:
# import all of Sulley's functionality.
from sulley import *

# this request is for fuzzing: {GET,HEAD,POST,TRACE} /index.html HTTP/1.1
# define a new block named "HTTP BASIC".
s_initialize("HTTP BASIC")

# define a group primitive listing the various HTTP verbs we wish to fuzz.
s_group("verbs", values=["GET", "HEAD", "POST", "TRACE"])

# define a new block named "body" and associate with the above group.
if s_block_start("body", group="verbs"):
  # break the remainder of the HTTP request into individual primitives.
  s_delim(" ")
  s_delim("/")
  s_string("index.html")
  s_delim(" ")
  s_string("HTTP")
  s_delim("/")
  s_string("1")
  s_delim(".")
  s_string("1")
  # end the request with the mandatory static sequence.
  s_static("\r\n\r\n")
# close the open block, the name argument is optional here.
s_block_end("body")

And we can read:
"(...) When this defined request is loaded into a Sulley session, the fuzzer will generate and transmit all possible values for the block "body", once for each verb defined in the group."

So, basically, what's the advantage (or need) for this concept? Is it any different than:
(...)
for verb in ["GET", "HEAD", "POST", "TRACE"]:
  s_string(verb, fuzzable=False)
  # break the remainder of the HTTP request into individual primitives.
  s_delim(" ")
  s_delim("/")
  s_string("index.html")
  s_delim(" ")
  s_string("HTTP")
  s_delim("/")
  s_string("1")
  s_delim(".")
  s_string("1")
  # end the request with the mandatory static sequence.
  s_static("\r\n\r\n")
# close the open block, the name argument is optional here.
s_block_end("body")

? Maybe I'm missing something, and if so, I'm sorry for that... But I'm just trying to understand the framework.

Best Regards,
Bruno Melo.

Bruno Melo

unread,
May 11, 2017, 6:11:14 PM5/11/17
to boofuzz

Joshua Pereyda

unread,
May 18, 2017, 10:33:00 PM5/18/17
to boofuzz
Bruno,

Sorry for the long delay in my response. I have been on the road most of the last week.

The source code of group.py (permalink) thankfully explains just a little bit more:
        """
        This primitive represents a list of static values, stepping through each one on mutation. You can tie a block
        to a group primitive to specify that the block should cycle through all possible mutations for *each* value
        within the group. The group primitive is useful for example for representing a list of valid opcodes.

        @type  name:   str
        @param name:   Name of group
        @type  values: list or str
        @param values: List of possible raw values this group can take.
        """

So it seems:
  1. If not tied to a block, each element in `values` is treated as a potential mutation.
  2. If tied to a block, it will act like there are n different messages, one for each element in `values`. Each message will be fuzzed separately. This is very much (but not exactly) like your for loop.
The difference with your for loop example is that it will actually create a single "block" (essentially one message in a protocol exchange) containing four full HTTP requests: GET, HEAD, POST, and TRACE.

To get the same effect without `s_group`, you would need to add an `s_initialize` at the beginning of the for loop. Then, when tying them together, you would need to make sure to construct the graph properly so that each of the four messages happens in parallel.

Hope that helps, and happy fuzzing!


Joshua
Reply all
Reply to author
Forward
0 new messages