ft6 is released under CC BY-NC-SA. That means you are free to improve it and implement your own tests!
To write your own test, create a new subclass of class Test (see test.py). Each test needs
In this example we’ll build our own test, to see if packets containing the string “randomword” can traverse the firewall. First, we create a new class:
class TestRandomWord(Test):
def __init__(self, id, name, description, test_settings, app):
super(TestRandomWord, self).__init__(id, name, description, test_settings, app)
Note the neccessity to call the parent constructor. The variable test_settings provides access to the information the user entered in the user interface. You have access to:
# IPv6 addresses:
test_settings.dst
test_settings.src
# link local addresses needed for MLD:
test_settings.target_ll
test_settings.source_ll
# port numbers:
test_settings.open_port
test_settings.closed_port
The app-variable is needed to communicate with the user interface. You can just pass it along. Next, we’ll implement the execute method. You’ll see a lot of scapy code there, so if you don’t understand that, check the official documentation:
def execute(self):
e = Ether(dst=self.test_settings.router_mac)
ip = IPv6(dst=self.test_settings.dst, src=self.test_settings.src)
udp= UDP(dport=self.test_settings.open_port, sport=12345)
payload = "ipv6-qab"*128
packet = e/ip/udp/(payload + "randomword")
sendp(packet)
packet = e/ip/udp(payload + "someotherword")
sendp(packet)
We’ve built a packet, and given it the marker “ipv6-qab” (don’t ask :)). We’ve also added the “randomword” we’re trying to smuggle through the firewall and given the packet to scapy’s sendp-function. While you could craft the packets in binary, by hand, we suggest that you also use scapy to create packets. It’s so easy, it’s almost ridiculous! Client and server will perform their handshake and send the packets. After the server eventually receives the “EndTest”-command it will call the test’s evaluate method and pass a list of all packets received as a parameter. We need to return a list of results, the strings that will be displayed in the user interface. So let’s write that method now:
def evaluate(self, packets):
results = []
# iterate over the packets, filter those that belong to the test
for p in packets:
tag = str(p.lastlayer())
if not "ipv6-qab" in tag:
continue
# check our randomword packet made it
if "randomword" in tag:
results.append("Success", "Your firewall forwarded a packet with a random word!")
else:
results.append("Failure", "Your firewall dropped a packet with a random word!")
# check if the evil someotherword packet made it
if "someotherword" in tag:
results.append("Warning", "Your firewall forwarded packet a with some other word. That's very weird!")
else:
results.append("Success", "Your firewall dropped a packet with some other word. Well done firewall!")
return results
Please note the three different states (“Success”, “Failure” or “Warning”) that a result can have. You’ll need to provide one of those. That’s it. Congratulation on writing your first test! Finally, we need to make the test available to the user interface. This is done in test.py, in the TestManager-class. Instantiate an object of your new class and add it to the dictionary:
# create test classes, store them in the dictionary so they can later be called by their id
tICMP = TestICMP(1, "ICMPv6 Filtering", "The ICMP Test", self.test_settings, app)
...
tRandomWord = TestRandomWord(42, "My Random Word Test", "Tests for Random Words", self.test_settings, app)
self.tests = dict([
(tICMP.id, tICMP), ..., (tRandomWord.id, tRandomWord)])
Now the user interface can query the TestManager and will find your new test! That’s it!