Project

General

Profile

Hacking ft6

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 source:tests.py#L226). Each test needs

  • an id
  • a name
  • a description
  • an overridden method execute(), in which the client sents the packets.
  • an overridden method evaluate(list_of_packets), in which the server loops through the list of received packets and creates the human-readable strings to be used by the user interface.

Building your test

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 = []

    found_random = False
    found_other  = False

    # 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:
            found_random = True

        if "someotherword" in tag:
            found_other = True

    # done looping through the packets, now build results for the gui
    if found_random:
        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!")

    if found_other:
        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 the TestManager-class, found in source:tests.py#L38.
Instantiate an object of your new class and register it with the application:

# 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)
self.registerTest(tICMP)

...

tRandomWord = TestRandomWord(42, "My Random Word Test", "Tests for Random Words", self.test_settings, app)
self.registerTest(tRandomWord)

Now the user interface can query the TestManager and will find your new test! That’s it!
We would be happy to learn about your custom tests. Please consider sending a mail to contact <at> idsv6 <dot> de.

Go back to the table of contents.