diff --git a/docs/index.rst b/docs/index.rst index 005c1938..9881183f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -81,6 +81,7 @@ coverage: - `boofuzz-ftp`_ - `boofuzz-http`_ +- `boofuzz-can`_ If you have an open source boofuzz protocol suite to share, please :ref:`let us know `! @@ -130,6 +131,7 @@ For updates, follow `@b00fuzz`_ on Twitter. .. _@b00fuzz: https://twitter.com/b00fuzz .. _boofuzz-ftp: https://github.com/jtpereyda/boofuzz-ftp .. _boofuzz-http: https://github.com/jtpereyda/boofuzz-http +.. _boofuzz-can: https://github.com/edgecase1/boofuzz-can Indices and tables diff --git a/examples/fuzz_can.py b/examples/fuzz_can.py new file mode 100644 index 00000000..f9c69317 --- /dev/null +++ b/examples/fuzz_can.py @@ -0,0 +1,285 @@ +#!/usr/bin/env python3 +""" +This sample program implements a boofuzz session for a CAN connection. +The program requires a CAN bus (e.g. a virtual CAN bus vcan0). +The system under test, "icsim" listens to the CAN bus. +""" + +from boofuzz import * +import socket +import struct +import time +import can +import scapy +import subprocess +import os +import signal + +#def post_test_callback(target, fuzz_data_logger, session, node, edge, *args, **kwargs): +# print("Testcase finished") +# time.sleep(5) +# return 1 + +class CanConnection(ITargetConnection): + """a connection to the virtual CAN bus vcan0""" + + def __init__(self, interface="vcan0", can_id=0x123): + self.interface = interface + self.can_id = can_id + self.is_alive = False + + def open(self): + """Open CAN raw socket""" + #self.sock = socket.socket(socket.AF_CAN, socket.SOCK_RAW, socket.CAN_RAW) + #self.sock.bind((self.interface,)) + # TODO check if interface exists + self.bus = can.Bus(interface='socketcan', channel='vcan0', bitrate=500000) + self.is_alive = True + + def info(self): + """Return a short description for boofuzz logs/UI.""" + return f"Raw CAN Socket on interface {self.interface}" + + def close(self): + """Close CAN socket""" + print(f"bus {self.interface} is going down") + self.is_alive = False + if self.bus: + self.bus.shutdown() + self.bus = None + + def send(self, data): + """ + `data` is the fuzzed payload and contains the CAN frame containing: + - arbitration ID (aka "CAN ID"), + - data length code (dlc) + - data (payload_bytes) + No padding is employed if not modeled in the Protocol Definition. + """ + # Extract fuzzed fields + can_id = struct.unpack("