GithubHelp home page GithubHelp logo

jtpereyda / boofuzz Goto Github PK

View Code? Open in Web Editor NEW
2.0K 53.0 334.0 6.23 MB

A fork and successor of the Sulley Fuzzing Framework

License: GNU General Public License v2.0

Python 95.60% HTML 1.39% CSS 0.48% Gherkin 1.21% JavaScript 1.32%
fuzzing python security

boofuzz's Introduction

boofuzz logo

boofuzz: Network Protocol Fuzzing for Humans

image

Documentation Status

image

Join the chat at https://gitter.im/jtpereyda/boofuzz

image

Boofuzz is a fork of and the successor to the venerable Sulley fuzzing framework. Besides numerous bug fixes, boofuzz aims for extensibility. The goal: fuzz everything.

Why?

Sulley has been the preeminent open source fuzzer for some time, but has fallen out of maintenance.

Features

Like Sulley, boofuzz incorporates all the critical elements of a fuzzer:

  • Easy and quick data generation.
  • Instrumentation – AKA failure detection.
  • Target reset after failure.
  • Recording of test data.

Unlike Sulley, boofuzz also features:

  • Online documentation.
  • Support for arbitrary communications mediums.
  • Built-in support for serial fuzzing, ethernet- and IP-layer, UDP broadcast.
  • Better recording of test data -- consistent, thorough, clear.
  • Test result CSV export.
  • Extensible instrumentation/failure detection.
  • Much easier install experience!
  • Far fewer bugs.

Sulley is affectionately named after the giant teal and purple creature from Monsters Inc. due to his fuzziness. Boofuzz is likewise named after the only creature known to have scared Sulley himself: Boo!

Boo from Monsters Inc

Boo from Monsters Inc

Installation

pip install boofuzz

Boofuzz installs as a Python library used to build fuzzer scripts. See INSTALL.rst for advanced and detailed instructions.

Documentation

Documentation is available at https://boofuzz.readthedocs.io/, including nifty quickstart guides.

Contributions

Pull requests are welcome, as boofuzz is actively maintained (at the time of this writing ;)). See CONTRIBUTING.rst.

Community

For questions that take the form of “How do I… with boofuzz?” or “I got this error with boofuzz, why?”, consider posting your question on Stack Overflow. Make sure to use the fuzzing tag.

If you’ve found a bug, or have an idea/suggestion/request, file an issue here on GitHub.

For other questions, check out boofuzz on gitter or Google Groups.

For updates, follow @b00fuzz on Twitter.

boofuzz's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

boofuzz's Issues

SOCK_RAW and SOCK_DGRAM on Windows

If somebody is really in a mood for pain, they could implement SocketConnection's raw-l2 and raw-l3 options on Windows.

One way to do this might be with WinPcap. References:

If I understand correctly, WinPcap would allow behavior similar to SOCK_RAW, in which MACs must be supplied by the user (but not CRCs). To emulate SOCK_DGRAM may require custom code to figure out the right MAC addresses based on the included IP packet information.

Binary Install for Windows Not Applicable

The latest wheel doesn't have Windows binaries.

This might not be worth maintaining, in which case the quick fix is to remove the binary subsection from INSTALL.rst.

Rename IFuzzable.fuzzable

It seems like IFuzzable.fuzzable would always be true, but the property "fuzzable" means something different than the interface "fuzzable."

Rename.

Perhaps a name like "should_fuzz" or "skip" would be more helpful.

Add make test

pytest-bdd has a Makefile on which you can run make and make test to run all the tests. This is very nice. It would be nice to have something similar for boofuzz.

  1. Makes it easier for developers to "run all the tests."
  2. As the tox documentation describes, it would act "as a frontend to Continuous Integration servers, greatly reducing boilerplate and merging CI and shell-based testing."

Continue fuzzing even if the target is not responding

I was having some problems, but after some testing I figured out that boofuzz performs only three fuzzing iterations of a primitive, when it is not receiving data from the target.

However, I want to fuzz each and every field of my protocol, even if the request doesn't generate response, or at least to revert the last fuzzed primitive to its default and to continue with the next one.

Currently Boofuzz jumps over to the next request (or finishes the fuzzing of the request), when no response is received in three fuzz attempts of a primitive and because of this it never reaches the fields (primitives) that are further down the protocol.

I can manually disable fuzzing of primitives, thus forcing it to fuzz the fields I want, but it would have been much easier to just let it fuzz all fields overnight.

Also now it never reaches past the first three attempts and thus the primitive is not extensively fuzzed. For example some value which is past the first three attempts may generate response or even trigger crash, however currently it never reaches for it as Boofuzz quits after three attempts.

Is this expected behaviour and how do I make it fuzz through all values of the primitives, when the target doesn't responds to the requests?

I am fuzzing a binary protocol and my sample request looks like this:

s_initialize("request")
s_byte(0x03, name="version", fuzzable=True)
s_byte(0x00, name="reserved", fuzzable=True)
s_binary("0x0016", name="length")
s_word(0x1111, name="pdu_type",  endian=">", fuzzable=True)
s_dword(0x00000000, name="data",  endian=">", fuzzable=True)

Fuzz a bitfield of various fixed bit sizes

A requirement for protocol fuzzing is to have protocol header(s) split into various fixed size fields (e.g. 4b, 20b, 8b etc.) for protocol options. These fields require to be defined separately, specified as fuzzable or non-fuzzable and afterwards assembled together to be sent to the target socket.
Currently Boofuzz pads the bitfield to the next byte boundary, therefore introducing unneeded bytes into the protocol header.

Consider an IPv6 header test case:

s_bit_field(0b0110, 4, fuzzable = False, name = "Version")
s_bit_field(0b00000000, 8, name = "Traffic_Class")
s_bit_field(0b00000000000000000000, 20, name = "Flow_Label")
s_bit_field(0b0000000000100000, 16, name = "Payload_Length")
s_bit_field(0x06, 8, name = "Next_Header")
s_bit_field(0xff, 8, name = "Hop_Limit")
s_binary("0x2a071180000200000000000000bb0001", name = "Source_Address")
s_binary("0x2a071180000200000000000000bb0002", name = "Destination_Address")

A Bofuzz feature supporting this would be highly required in order to ensure raw binary (e.g. L2,L3) protocol fuzzing.

More information on feature discussion is here: https://groups.google.com/forum/#!topic/boofuzz/7rZeBYnEyV0

Support no receive step

Issue reported by @Ramzeth, see Gitter chats here.

@Ramzeth You bring up a good point... Boofuzz doesn't currently support a scenario where the receive step should be skipped

In order to avoid changing the default behavior for other scenarios, I think another setting would be warranted... We could add a self._receive_after_send variable. The code would look like:

if self._receive_after_send:
    self.last_recv = self.targets[0].recv(10000)
    if self._check_data_received_each_request:
        self._fuzz_data_logger.log_check("Verify some data was received from the target.")

Then Session would get a new keyword parameter receive_after_send=True

Request Mutations: Empty Message

Make Request objects have at least one special mutation: an empty message.
Do the same for Block.

Also, there is lots of duplicate code between Request and Block which would be nice to clean out.

Easier post_send API

The post_send API is defined by a function, and it's not exceedingly intuitive. Consider using an interface instead.

Inspired by this talk: The End Of Object Inheritance & The Beginning Of A New Modularity

Essentially, Python is not defined to handle functions this way. It can, but the language lends itself to using objects rather than just functions. One of the speakers argues that objects/interfaces are better than functions for this case.

The current way of registering post_send is also pretty clunky. We could take a more event handler style approach and allow multiple functions.

I'm not sure what the best approach is. This should be settled after we see more use cases.

Test Case Variant Identifier

It's nice to have a way to quickly identify the nature of a test case variant. Should describe the variant in an abbreviated way, perhaps with a link to the full data if it's long.

Elements of unique identification:

  1. Instance/scenario: Which path is being taken through the protocol.
  2. Message: Which message.
  3. Element: Which part of message.
  4. Mutation: Which mutation.

Ideas for representation:

  1. Scenario: Number.
  2. Message: Name.
  3. Element: Name.
  4. Mutation: Number with preview?

Write Code of Conduct

Provide a foundation for behavior, as well as details in how it applies.

Detail ideas:

  1. Bear with newcomers; if you close something, provide a helpful answer or pointer as well.
  2. Expect criticism.

Add Feature To Evaluate For Reproducibility

Add a feature to retry failures and determine whether boofuzz can reproduce them.

A binary search approach that moves backwards starting with just the failing case, then it and one before, then 4 cases, then 8... may be a good start (I thought Sulley already did this but I can't find any such script).

View detailed logs from web interface

It would be handy to navigate through test cases and view detailed logs from the web GUI.

Also slick: If the logs could be dynamically fed to the web page, with logs wizzing by in a nifty little text window, while finished cases are added to a tree view on the left.

Use iter to simplify mutatable interface

A lot of fluff in BasePrimitive could be removed if we just made mutatable things iterable.

The interface is functionally the same: You get only one mutation at a time.

The interface would now be:

  • __iter__ to yield mutations
  • Default value: Probably a separate property. Yielding it as the first iterator value would result in duplicate test cases, or the fuzzing code would need to skip every first mutation.
  • num_mutations: As is.

While we're modifying things, make all member variables private if possible.

Add crash_threshold for individual primitives instead of whole message

As I understand, the crash_threshold is used to limit the number of mutations of a single primitive if the target continues to crash. E.g. if mutations in the primitive "test" already caused 3 crashes skip the rest of the mutations and continue with the next primitive.

In my case after this happens the fuzzing session is aborted entirely. Specifically in sessions.py:595
self._skip_after_cur_test_case = True
a flag is set that causes the loop in sessions.py:818 to break:
if self._skip_after_cur_test_case:
self._skip_after_cur_test_case = False
break

Therefore, the iterator no longer yields anything. I guess this behaviour is not intended?

Custom Test Cases Insertion

For every kind of block/primitive/etc: Add a parameter that allows the user to inject a few custom cases. Parameter should probably be an iterable.

No session filename causes crash

Problem

If you don't give Session the session_filename attribute, it will crash.

$ python ftp.py
Traceback (most recent call last):
  File "ftp.py", line 58, in <module>
    main()
  File "ftp.py", line 11, in main
    session = sessions.Session(sleep_time=0.0, fuzz_data_logger=logger)
  File "/home/joshpere/code/fuzz/boofuzz/boofuzz/sessions.py", line 241, in __init__
    self.import_file()
  File "/home/joshpere/code/fuzz/boofuzz/boofuzz/sessions.py", line 442, in import_file
    with open(self.session_filename, "rb") as f:
TypeError: coercing to Unicode: need string or buffer, NoneType found

Solution

Add a simple check at the beginning of import_file(). This is what export_file() already does:

        if self.session_filename is None:
            return

Use tox

Tox seems like an excellent tool for simplifying testing. It will build virtual environments for us, which also means we don't have to put it all in .travis.yml. And tests run on user machines will be closer to what Travis does without having to make your own virtualenv.

Make Process Monitor Start Process Itself

Process monitor is able to re-start a process, but it will not work unless the process is already running when the test starts. The current workflow is:

  1. Start the process under test.
  2. Start the process monitor.
  3. Start test.

Make the process monitor start the process if it does not already exist. This would give a new, shorter workflow:

  1. Start the process monitor.
  2. Start test.

This begs the question: Can we start the process monitor automatically if the targert is localhost? I don't see why not. Or we could even run it as a local library instead of a separate service (I don't know if it'd be worth the effort or not).

Test Run Header

Idea: Add a log_test or log_test_run method to IFuzzLogger. This will provide a header describing a test run. Advantages:

  1. Fully encapsulates test data, rather than leaving it in stray files.
  2. Allows us to add some kind of unique identifier to the test run.
  3. Allows us to add test run metadata as needed.
  4. Takes care of append problem, where multiple test runs with a single log file result in confusing data.

Also record the boofuzz version number, and the test suite version number if possible.

Error during Installation

Hi, when I try to install boofuzz on ubuntu 14.04, I get this error:-

Cleaning up...
  Removing temporary dir /tmp/pip_build_root...
Exception:
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/pip/basecommand.py", line 122, in main
    status = self.run(options, args)
  File "/usr/lib/python2.7/dist-packages/pip/commands/install.py", line 278, in run
    requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
  File "/usr/lib/python2.7/dist-packages/pip/req.py", line 1198, in prepare_files
    do_download,
  File "/usr/lib/python2.7/dist-packages/pip/req.py", line 1376, in unpack_url
    self.session,
  File "/usr/lib/python2.7/dist-packages/pip/download.py", line 572, in unpack_http_url
    download_hash = _download_url(resp, link, temp_location)
  File "/usr/lib/python2.7/dist-packages/pip/download.py", line 433, in _download_url
    for chunk in resp_read(4096):
  File "/usr/lib/python2.7/dist-packages/pip/download.py", line 421, in resp_read
    chunk_size, decode_content=False):
  File "/usr/share/python-wheels/urllib3-1.7.1-py2.py3-none-any.whl/urllib3/response.py", line 225, in stream
    data = self.read(amt=amt, decode_content=decode_content)
  File "/usr/share/python-wheels/urllib3-1.7.1-py2.py3-none-any.whl/urllib3/response.py", line 174, in read
    data = self._fp.read(amt)
  File "/usr/lib/python2.7/httplib.py", line 573, in read
    s = self.fp.read(amt)
  File "/usr/lib/python2.7/socket.py", line 380, in read
    data = self._sock.recv(left)
  File "/usr/lib/python2.7/ssl.py", line 341, in recv
    return self.read(buflen)
  File "/usr/lib/python2.7/ssl.py", line 260, in read
    return self._sslobj.read(len)
SSLError: The read operation timed out

What could be the problem??

Windows CI build

PR #96 fixed a Windows build issue. Investigate and deploy a Windows automated build. Looks like AppVeyor and Buildkite are options.

Production wheels missing files

The wheels being built and deployed appear to be outdated. After cleaning and rebuilding, they are still missing all sub-folders of boofuzz. Not good!

Fix and redeploy.

Safer Restarting

PR #45 revealed some deficiencies in the procmon restart process. Right now, the user of a procmon must decide whether to stop a process before starting it.

But probably, if you called Session.restart_target, you just want it to actually restart. So to decide whether to stop it, you need to know if it's still running, which is information that lives in the procmon, not Session.

Proposed solution: Give the procmon a restart() method that decides whether to stop first. Call restart from Session, and remove the stop_first parameter from Session.restart_target.

Too much boilerlate!

The first five lines of this example are all boilerplate: https://github.com/jtpereyda/boofuzz-ftp/blob/master/ftp.py (permalink)

This is way more boilerplate than necessary. We can add a default logger to FuzzLogger, or even to Session. And the Target class is pretty meaningless in this example. If we make Session the direct manager for connections (and process monitors, etc.), we can nix this Target middle man altogether.

And if we go really stir crazy, we can even make sleep_time default to zero!

The brave new boilerplate may look like:

session = sessions.Session(
        connection=SocketConnection("127.0.0.1", 8021, proto='tcp'))

Add CONTRIBUTING.txt

Consider basing it off of this one: https://github.com/jtpereyda/ezoutlet/blob/master/CONTRIBUTING.rst

Edit: Make sure to include a note about the expectation of professional code reviews on all pull requests. Not all users may be familiar with this. Find an article or something that briefly and effectively introduces the process.

See Bob Martin's "Clean Code", introduction to Chapter 16:

No, this is not an activity of nastiness or arrogance. What I am about to do is nothing more and nothing less than a professional review. It is something that we should all be comfortable doing. And it is something we should welcome when it is done for us. It is only through critiques like these that we will learn. Doctors do it. Pilots do it. Lawyers do it. And we programmers need to learn how to do it too.

Finish automating build

Travis currently deploys to PyPI when it gets a tag from Github. However, the release checklist (see CONTRIBUTING.rst) still requires manual interaction:

  • bump version number
  • commit and push version number
  • add tag to Github

Ideally, whenever we merge a PR to master, Travis would do these steps for us and push out a new dev release.

Sulley: Optimize Session.fuzz_single_case()

If you use fuzz_single_case() to fuzz all of the test cases, it will take longer and longer as you get into higher numbers. Each time the method is called, it iterates up to the desired point in the list. This can add non-trivial delay with a big enough test.

Options:

  • Cache cases within fuzz_case_iterator. This would be snazzy.
  • Cache the iterator within fuzz_single_case(), and don't reset unless needed. Less flexible.

Failed to import sulley on windows xp

Boofuzz, pydbg, and pydasm seemd to install fine but process monitor errors with no CancelIoEx

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\marcus\Desktop\boofuzz-master\boofuzz-master>python pr
ocess_monitor.py
Traceback (most recent call last):
File "process_monitor.py", line 11, in
from boofuzz import utils
File "C:\Documents and Settings\marcus\Desktop\boofuzz-master\boofuzz-master\b
oofuzz_init_.py", line 27, in
from .serial_connection import SerialConnection
File "C:\Documents and Settings\marcus\Desktop\boofuzz-master\boofuzz-master\b
oofuzz\serial_connection.py", line 4, in
from . import serial_connection_low_level
File "C:\Documents and Settings\marcus\Desktop\boofuzz-master\boofuzz-master\b
oofuzz\serial_connection_low_level.py", line 2, in
import serial
File "C:\Python27\lib\site-packages\serial_init_.py", line 27, in
from serial.serialwin32 import Serial
File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 15, in
from serial import win32
File "C:\Python27\lib\site-packages\serial\win32.py", line 182, in
CancelIoEx = stdcall_libraries['kernel32'].CancelIoEx
File "C:\Python27\lib\ctypes_init
.py", line 375, in getattr
func = self.getitem(name)
File "C:\Python27\lib\ctypes_init_.py", line 380, in getitem
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'CancelIoEx' not found

Update: I downloaded a Vista VM and it installed perfectly on that.

is_valid_msg Method

Feature

Add a .is_valid_msg() method to the IFuzzable interface.

The method should return True if the data given to it can be parsed as a valid message; false otherwise.

Motivation

A simple way to improve the thoroughness of a fuzzer is to parse the reply messages received to ensure they meet expected values.

Design

I can think of three steps to implementation:

  1. The easiest step would be to use the original_value property. The data to be checked could be compared with the Request object's `original_value.
  2. For further customization, we could add a valid_values parameter to fuzz primitives. This parameter would be a list of valid values that the primitive could take. If the values could be variable-length, things could get complicated.
  3. A list of values may be too much for certain data types, so a custom function could be given to customize behavior. This is not too far from creating a new fuzz primitive type. The easiest place to hook in this function might be in the Request object.

Fuzzing activities would also be helped by a deserialize() method, providing an object representation of the message. This object could be used to check various properties of the reply. That might be more than is needed typically, and comes close to allowing for a full protocol functional test, perhaps beyond the needs of a fuzzer.

For now, a procedure that parses a message for validity might be enough. A typical post_send method could parse against the expected message and a range of known error messages. Any message following outside this domain could be considered erroneous.

s_checksum issues

Hello everyone,I find if i pass a my own defined algorithm function to s_checksum,it may cause a error. so i check the code,and do some changes as blow:
in checksum.py:
add algorithm argument's type judgement
if type(self._algorithm) is not str:
self.checksum_lengths[self._algorithm.name] = self._length
and in _get_dummy_value function :
def _get_dummy_value(self):
if type(self._algorithm) is str:
return self.checksum_lengths[self._algorithm] * '\x00'
else:
return self.checksum_lengths[self._algorithm.name] * '\x00'
hope it would be helpful or anyone have good idea?

socket.error: [Errno 10054] An existing connection was forcibly closed by the remote host

One user has reported and I've personally seen errors like this before:

Traceback (most recent call last):
  File "Z:\ftp\ftp.py", line 119, in <module>
    sess.fuzz()
  File "C:\Python27\lib\site-packages\boofuzz\sessions.py", line 414, in fuzz
    self._fuzz_current_case(*fuzz_args)
  File "C:\Python27\lib\site-packages\boofuzz\sessions.py", line 868, in _fuzz_current_case
    self.transmit(target, self.fuzz_node, edge)
  File "C:\Python27\lib\site-packages\boofuzz\sessions.py", line 739, in transmit
    self.last_recv = self.targets[0].recv(10000)
  File "C:\Python27\lib\site-packages\boofuzz\sessions.py", line 110, in recv
    data = self._target_connection.recv(max_bytes=max_bytes)
  File "C:\Python27\lib\site-packages\boofuzz\socket_connection.py", line 143, in recv
    data = self._sock.recv(max_bytes)
socket.error: [Errno 10054] An existing connection was forcibly closed by the remote host

This seems to indicate a crash of the unit under test, which boofuzz should report as an error instead of crashing itself.

I don't know if there are times when this is valid behavior; perhaps in some protocols.

If anyone has any further details or ideas, please post.

Remove ITargetConnection.recv max_bytes parameter

ITargetConnection.recv has a max_bytes parameter that is mostly an annoyance. In existing code, it has been set to some arbitrarily high number. We should eliminate the parameter, give it a helpful default, or something.

Provide Repeatable Random Seeds

grep -rni --exclude-dir .git --exclude-dir .idea "random"

Randomness in tests reduces repeatability. Remove randomness, or else provide a means to record and repeat seed values.

Update 2021-02-24: Using a repeatable seed is probably easier and better.

Add smart support for size limits

There are many cases where fuzzing a single field will exceed a size limit.

For example, if a field in an IP or UDP packet gets super oversized, the UDP checksum becomes undefined. Now we have to make the checksum function fudge in an undefined checksum.

Another exmaple is when the sockets layer has a datagram limit, and a UDP packet gets fuzzed to be too big. We then truncate it at the sockets layer, but now it doesn't even have a checksum!

This is good because it stretches size limits, but it's problematic because the packet will break in other ways. We'd probably rather make our test cases meet the maximum size of any given field. But then we'd want separate test cases to exceed the size limit.

Intermittent test failure

Investigate. Occurred at least twice, intermittently, on Windows 10 machine. boofuzz v0.0.3.dev13

C:\Users\josh\code\boofuzz>python -m tox
GLOB sdist-make: C:\Users\josh\code\boofuzz\setup.py
py27 inst-nodeps: C:\Users\josh\code\boofuzz\.tox\dist\boofuzz-0.0.3.dev13.zip
py27 installed: backports.ssl-match-hostname==3.5.0.1,boofuzz==0.0.3.dev13,certifi==2016.2.28,check-manifest==0.31,colorama==0.3.7,enum34==1.1.2,Flask==0.10.1,funcsigs==1.0.0,future==0.15.2,glob2==0.4.1,impacket==0.9.14,itsdangerous==0.24,Jinja2==2.8,Mako==1.0.4,MarkupSafe==0.23,mock==2.0.0,ordereddict==1.1,parse==1.6.6,parse-type==0.3.4,pbr==1.9.0,py==1.4.31,pydot2==1.0.33,pyparsing==2.1.1,pyserial==3.0.1,pytest==2.9.1,pytest-bdd==2.16.1,six==1.10.0,tornado==4.0.2,Werkzeug==0.11.5
py27 runtests: PYTHONHASHSEED='449'
py27 runtests: commands[0] | python -m pytest
============================= test session starts =============================
platform win32 -- Python 2.7.11, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: C:\Users\josh\code\boofuzz, inifile:
plugins: bdd-2.16.1
collected 106 items

unit_tests\test_ez_outlet_reset.py ................
unit_tests\test_fuzz_logger.py .............
unit_tests\test_fuzz_logger_text.py .......................
unit_tests\test_helpers_ip_str_to_bytes.py ...................
unit_tests\test_helpers_udp_checksum.py ........
unit_tests\test_serial_connection_generic.py ...............
unit_tests\test_socket_connection.py .ssssss..F..

================================== FAILURES ===================================
____________________ TestSocketConnection.test_tcp_client _____________________

self = <unit_tests.test_socket_connection.TestSocketConnection testMethod=test_tcp_client>

    def test_tcp_client(self):
        """
            Given: A SocketConnection 'tcp' object and a TCP server.
            When: Calling SocketConnection.open(), .send(), .recv(), and .close()
            Then: send() returns RAW_L3_MAX_PAYLOAD.
             and: Sent and received data is as expected.
            """
        data_to_send = bytes('uuddlrlrba')

        # Given
        server = MiniTestServer()
        server.bind()

        t = threading.Thread(target=server.serve_once)
        t.daemon = True
        t.start()

        uut = SocketConnection(host=socket.gethostname(), port=server.active_port, proto='tcp')
        uut.logger = logging.getLogger("SulleyUTLogger")

        # When
        uut.open()
        send_result = uut.send(data=data_to_send)
>       received = uut.recv(10000)

unit_tests\test_socket_connection.py:265:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <boofuzz.socket_connection.SocketConnection object at 0x00000000187B6940>
max_bytes = 10000

    def recv(self, max_bytes):
        """
            Receive up to max_bytes data from the target.

            :param max_bytes: Maximum number of bytes to receive.
            :type max_bytes: int

            :return: Received data.
            """
        try:
            if self.proto in ['tcp', 'ssl']:
>               data = self._sock.recv(max_bytes)
E               error: [Errno 10054] An existing connection was forcibly closed by the remote host

boofuzz\socket_connection.py:136: error
---------------------------- Captured stderr call -----------------------------
Exception in thread Thread-1:
Traceback (most recent call last):
  File "c:\python27\Lib\threading.py", line 801, in __bootstrap_inner
    self.run()
  File "c:\python27\Lib\threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "C:\Users\josh\code\boofuzz\unit_tests\test_socket_connection.py", line 174, in serve_once
    self.received = client_socket.recv(10000)
error: [Errno 10035] A non-blocking socket operation could not be completed immediately

=============== 1 failed, 99 passed, 6 skipped in 2.07 seconds ================
ERROR: InvocationError: 'C:\\Users\\josh\\code\\boofuzz\\.tox\\py27\\Scripts\\python.EXE -m pytest'
___________________________________ summary ___________________________________
ERROR:   py27: commands failed

Add Colored Output

I've noticed a few issues and questions recently that suggest users may not be noticing failures in the output. Colored output might help:
image

Of course, a better HTML interface would also help, since all that text whizzes by pretty quickly.

AttributeError during fuzzing due to missing property setters

Problem

Property attributes of boofuzz.request.Request have no setters implemented, causing AttributeErrors to
be raised when attempting to set the values of these attributes during fuzzing.

Affected attributes:

  • Request.mutant_index - Caused an unhandled exception during fuzzing
  • Request.name - Noticed when fixing mutant_index

Fix

Implement basic setters for the above properties

Config file

Currently, boofuzz config is done by writing a Python script. When writing such scripts, it is natural to add command line arguments. This results in a lot of redundant fixture code.

One solution is to make the CLI standardized, and each fuzz definition script would be included via a command line parameter.

Config file:

  • Natural to save, even in version control.
  • More readable.
  • Lends itself to somewhat reasonable organization (think ini file, like .gitconfig).

Ideas:
Use .hgrc / .gitconfig file formats:

[testopts]
definitions = udp.py
post_fail = ez_outlet
[ez_outlet]
ip = 192.168.1.103

Parameters could be automatically passed to constructor.

Make s_binary() fuzzable

According to the documentation s_binary() is fuzzable, however it doesn't seems to support the fuzzable=True/False keyword and is not fuzzed during execution.

If it is not fuzzable then how can I represent and fuzz a binary or hex value that I extract directly from a pcap file with network communication?

Make post_send quiet if not specified

If you don't specify a post_send function, boofuzz will tell you... on every single test.

[2016-07-20 19:19:30,638]   Test Step: Calling post_send function:
[2016-07-20 19:19:30,652]     Info: No post_send callback registered.

Consider doing the same if the sleep time is zero seconds:

[2016-07-20 19:19:30,656]   Test Step: Sleep between tests.
[2016-07-20 19:19:30,669]     Info: sleeping for 0.000000 seconds

Self-diagnostics: Default no-error test case

Before fuzzing, run a test case without mutations (test case zero) and verify all checks pass. Consider adding an option to test the reset functionality as well by resetting before this initial test case.

A more advanced approach for complex protocols is to use a number of such tests to discover protocol interoperability.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.