• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1% Tests for Scapy's p0fv2 module.
2
3~ p0f
4
5
6############
7############
8+ Basic p0f module tests
9
10= Module loading
11load_module('p0fv2')
12
13= Fetch database
14~ netaccess
15
16try:
17    from urllib.request import urlopen
18except ImportError:
19    from urllib2 import urlopen
20
21def _load_database(file):
22    for i in range(10):
23        try:
24            with open(file, 'wb') as fd:
25                fd.write(urlopen('https://raw.githubusercontent.com/p0f/p0f/4b4d1f384abebbb9b1b25b8f3c6df5ad7ab365f7/' + file).read())
26            break
27        except:
28            raise
29            pass
30
31_load_database("p0f.fp")
32conf.p0f_base = "p0f.fp"
33_load_database("p0fa.fp")
34conf.p0fa_base = "p0fa.fp"
35_load_database("p0fr.fp")
36conf.p0fr_base = "p0fr.fp"
37_load_database("p0fo.fp")
38conf.p0fo_base = "p0fo.fp"
39
40p0f_load_knowledgebases()
41
42############
43############
44+ Default tests
45
46= Test p0f
47~ netaccess
48
49pkt = Ether(b'\x14\x0cv\x8f\xfe(\xd0P\x99V\xdd\xf9\x08\x00E\x00\x0045+@\x00\x80\x06\x00\x00\xc0\xa8\x00w(M\xe2\xf9\xda\xcb\x01\xbbcc\xdd\x1e\x00\x00\x00\x00\x80\x02\xfa\xf0\xcc\x8c\x00\x00\x02\x04\x05\xb4\x01\x03\x03\x08\x01\x01\x04\x02')
50
51assert p0f(pkt) == [('@Windows', 'XP/2000 (RFC1323+, w+, tstamp-)', 0)]
52
53= Test prnp0f
54~ netaccess
55
56with ContextManagerCaptureOutput() as cmco:
57    prnp0f(pkt)
58    assert cmco.get_output() == '192.168.0.119:56011 - @Windows XP/2000 (RFC1323+, w+, tstamp-)\n  -> 40.77.226.249:https (S) (distance 0)\n'
59
60############
61############
62+ Tests for p0f_impersonate
63
64# XXX: a lot of pieces of p0f_impersonate don't have tests yet.
65
66= Impersonate when window size must be multiple of some integer
67sig = ('%467', 64, 1, 60, 'M*,W*', '.', 'Phony Sys', '1.0')
68pkt = p0f_impersonate(IP()/TCP(), signature=sig)
69assert pkt.payload.window % 467 == 0
70
71= Handle unusual flags ("F") quirk
72sig = ('1024', 64, 0, 60, 'W*', 'F', 'Phony Sys', '1.0')
73pkt = p0f_impersonate(IP()/TCP(), signature=sig)
74assert (pkt.payload.flags & 40) in (8, 32, 40)
75
76= Use valid option values from original packet
77sig = ('S4', 64, 1, 60, 'M*,W*,T', '.', 'Phony Sys', '1.0')
78opts = [('MSS', 1400), ('WScale', 3), ('Timestamp', (97256, 0))]
79pkt = p0f_impersonate(IP()/TCP(options=opts), signature=sig)
80assert pkt.payload.options == opts
81
82= Use valid option values when multiples required
83sig = ('S4', 64, 1, 60, 'M%37,W%19', '.', 'Phony Sys', '1.0')
84opts = [('MSS', 37*15), ('WScale', 19*12)]
85pkt = p0f_impersonate(IP()/TCP(options=opts), signature=sig)
86assert pkt.payload.options == opts
87
88= Discard non-multiple option values when multiples required
89sig = ('S4', 64, 1, 60, 'M%37,W%19', '.', 'Phony Sys', '1.0')
90opts = [('MSS', 37*15 + 1), ('WScale', 19*12 + 1)]
91pkt = p0f_impersonate(IP()/TCP(options=opts), signature=sig)
92assert pkt.payload.options[0][1] % 37 == 0
93assert pkt.payload.options[1][1] % 19 == 0
94
95= Discard bad timestamp values
96sig = ('S4', 64, 1, 60, 'M*,T', '.', 'Phony Sys', '1.0')
97opts = [('Timestamp', (0, 1000))]
98pkt = p0f_impersonate(IP()/TCP(options=opts), signature=sig)
99# since option is "T" and not "T0":
100assert pkt.payload.options[1][1][0] > 0
101# since T quirk is not present:
102assert pkt.payload.options[1][1][1] == 0
103
104= Discard 2nd timestamp of 0 if "T" quirk is present
105sig = ('S4', 64, 1, 60, 'M*,T', 'T', 'Phony Sys', '1.0')
106opts = [('Timestamp', (54321, 0))]
107pkt = p0f_impersonate(IP()/TCP(options=opts), signature=sig)
108assert pkt.payload.options[1][1][1] > 0
109
110+ Clear temp files
111
112= Remove fp files
113def _rem(f):
114    try:
115        os.remove(f)
116    except:
117        pass
118
119_rem("p0f.fp")
120_rem("p0fa.fp")
121_rem("p0fr.fp")
122_rem("p0fo.fp")
123