• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1% Regression tests on Windows only for Scapy
2
3# More informations at http://www.secdev.org/projects/UTscapy/
4
5############
6############
7+ Networking tests
8
9= Automaton - SelectableSelector system timeout
10
11class TimeOutSelector(SelectableObject):
12    def check_recv(self):
13        return False
14
15assert select_objects([TimeOutSelector()], 0) == []
16assert select_objects([TimeOutSelector()], 1) == []
17
18############
19############
20+ Windows Networking tests
21
22= Mocked read_routes6() calls
23
24import mock
25from scapy.tools.UTscapy import Bunch
26from scapy.arch.windows import _read_routes6_post2008
27
28def check_mandatory_ipv6_routes(routes6):
29    """Ensure that mandatory IPv6 routes are present."""
30    if len([r for r in routes6 if r[0] == "::" and r[4] == ["::1"]]) < 1:
31        return False
32    if len([r for r in routes6 if r[0] == "fe80::" and (r[1] == 64 or r[1] == 32)]) < 1:
33        return False
34    if len([r for r in routes6 if in6_islladdr(r[0]) and r[1] == 128]) < 1:
35        return False
36    return True
37
38def dev_from_index_custom(if_index):
39    if_list = [{'mac': 'D0:50:99:56:DD:F9', 'win_index': '13', 'guid': '{C56DFFB3-992C-4964-B000-3E7C0F76E8BA}', 'name': 'Killer E2200 Gigabit Ethernet Controller', 'description': 'Ethernet'}, {'mac': '00:FF:0E:C7:25:37', 'win_index': '3', 'guid': '{0EC72537-B662-4F5D-B34E-48BFAE799BBE}', 'name': 'TAP-Windows Adapter V9', 'description': 'Ethernet 2'}]
40    values = {}
41    for i in if_list:
42        try:
43            interface = NetworkInterface(i)
44            values[interface.guid] = interface
45        except (KeyError, PcapNameNotFoundError):
46            pass
47    for devname, iface in values.items():
48        if iface.win_index == str(if_index):
49            return iface
50    raise ValueError("Unknown network interface index %r" % if_index)
51
52@mock.patch("scapy.arch.windows.construct_source_candidate_set")
53@mock.patch("scapy.arch.windows.get_if_list")
54@mock.patch("scapy.arch.windows.dev_from_index")
55@mock.patch("scapy.arch.windows.POWERSHELL_PROCESS.query")
56def test_read_routes6_windows(mock_comm, mock_dev_from_index, mock_winpcapylist, mock_utils6cset):
57    """Test read_routes6() on Windows"""
58    # 'Get-NetRoute -AddressFamily IPV6 | select ifIndex, DestinationPrefix, NextHop'
59    get_net_route_output = """
60ifIndex           : 3
61DestinationPrefix : ff00::/8
62NextHop           : ::
63RouteMetric       : 0
64InterfaceMetric   : 1
65
66ifIndex           : 16
67DestinationPrefix : ff00::/8
68NextHop           : ::
69RouteMetric       : 0
70InterfaceMetric   : 1
71
72ifIndex           : 13
73DestinationPrefix : ff00::/8
74NextHop           : ::
75RouteMetric       : 0
76InterfaceMetric   : 1
77
78ifIndex           : 1
79DestinationPrefix : ff00::/8
80NextHop           : ::
81RouteMetric       : 0
82InterfaceMetric   : 1
83
84ifIndex           : 13
85DestinationPrefix : fe80::dc1d:24e8:af00:125e/128
86NextHop           : ::
87RouteMetric       : 20
88InterfaceMetric   : 256
89
90ifIndex           : 3
91DestinationPrefix : fe80::9402:5804:cb16:fb3b/128
92NextHop           : ::
93RouteMetric       : 1
94InterfaceMetric   : 0
95
96ifIndex           : 16
97DestinationPrefix : fe80::100:7f:fffe/128
98NextHop           : ::
99RouteMetric       : 1
100InterfaceMetric   : 0
101
102ifIndex           : 3
103DestinationPrefix : fe80::/64
104NextHop           : ::
105RouteMetric       : 0
106InterfaceMetric   : 1
107
108ifIndex           : 16
109DestinationPrefix : fe80::/64
110NextHop           : ::
111RouteMetric       : 0
112InterfaceMetric   : 1
113
114ifIndex           : 13
115DestinationPrefix : fe80::/64
116NextHop           : ::
117RouteMetric       : 0
118InterfaceMetric   : 1
119
120ifIndex           : 13
121DestinationPrefix : 2a01:e35:2f17:fe60:dc1d:24e8:af00:125e/128
122NextHop           : ::
123RouteMetric       : 20
124InterfaceMetric   : 256
125
126ifIndex           : 13
127DestinationPrefix : 2a01:e35:2f17:fe60::/64
128NextHop           : ::
129RouteMetric       : 30
130InterfaceMetric   : 256
131
132ifIndex           : 1
133DestinationPrefix : ::1/128
134NextHop           : ::
135RouteMetric       : 0
136InterfaceMetric   : 256
137
138ifIndex           : 13
139DestinationPrefix : ::/0
140NextHop           : fe80::224:d4ff:fea0:a6d7
141RouteMetric       : 0
142InterfaceMetric   : 256
143"""
144    mock_comm.return_value = get_net_route_output.split("\n")
145    mock_winpcapylist.return_value = [u'\\Device\\NPF_{0EC72537-B662-4F5D-B34E-48BFAE799BBE}', u'\\Device\\NPF_{C56DFFB3-992C-4964-B000-3E7C0F76E8BA}']
146    # Mocked in6_getifaddr() output
147    mock_dev_from_index.side_effect = dev_from_index_custom
148    # Random
149    mock_utils6cset.side_effect = lambda x,y,z: ["::1"] if x=="::" else ["fdbb:d995:ddd8:51fc::"]
150    # Test the function
151    routes = _read_routes6_post2008()
152    for r in routes:
153        print(r)
154    print(len(routes))
155    assert(len(routes) == 9)
156    assert(check_mandatory_ipv6_routes(routes))
157
158
159test_read_routes6_windows()
160
161= Test _read_routes_post2008 with missing InterfaceMetric
162
163from scapy.arch.windows import _read_routes_post2008
164
165@mock.patch("scapy.arch.windows._get_metrics")
166@mock.patch("scapy.arch.windows.POWERSHELL_PROCESS.query")
167@mock.patch("scapy.arch.windows.get_if_list")
168@mock.patch("scapy.arch.windows.dev_from_index")
169def test_missing_ifacemetric(mock_dev_from_index, mock_winpcapylist, mock_exec_query, mock_get_metrics):
170    exc_query_output = """ifIndex           : 3
171DestinationPrefix : 255.255.255.255/0
172NextHop           : 192.168.103.1
173RouteMetric       : 10
174InterfaceMetric   : 256
175
176ifIndex           : 13
177DestinationPrefix : 255.255.255.255/32
178NextHop           : 0.0.0.0
179RouteMetric       : 20
180InterfaceMetric   :
181"""
182    mock_exec_query.side_effect = lambda *args, **kargs: exc_query_output.split("\n")
183    mock_winpcapylist.return_value = [u'\\Device\\NPF_{0EC72537-B662-4F5D-B34E-48BFAE799BBE}', u'\\Device\\NPF_{C56DFFB3-992C-4964-B000-3E7C0F76E8BA}']
184    mock_dev_from_index.side_effect = dev_from_index_custom
185    mock_get_metrics.side_effect = lambda: {'16': 0, '13': 123}
186    routes = _read_routes_post2008()
187    for r in routes:
188        print(r)
189    assert len(routes) == 2
190    # Test if metrics were correctly read/guessed
191    assert routes[0][5] == 266
192    assert routes[1][5] == 143
193
194test_missing_ifacemetric()
195
196= Test _get_metrics with weird netsh length
197
198from scapy.arch.windows import _get_metrics
199
200@mock.patch("scapy.arch.windows.POWERSHELL_PROCESS.query")
201def test_get_metrics(mock_exec_query):
202    exc_query_output = """Interface Loopback Pseudo-Interface 1 Parameters
203-------------------------------
204IfLuid : loopback_0
205IfIndex : 1
206State : connected
207Metric : 75
208Link MTU : 4294967295 byt
209Reachable Time : 40500 ms
210Base Reachable Time : 30000 ms
211Retransmission Interval : 1000 ms
212DAD Transmits : 0
213Site Prefix Length : 64
214Site Id : 1
215Forwarding : disabled
216Advertising : disabled
217Neighbor Discovery : disabled
218Neighbor Unreachability Detection : disabled
219Router Discovery : dhcp
220Managed Address Configuration : enabled
221Other Stateful Configuration : enabled
222Weak Host Sends : disabled
223Weak Host Receives : disabled
224Use Automatic Metric : enabled
225Ignore Default Routes : disabled
226Advertised Router Lifetime : 1800 seconds
227Advertise Default Route : disabled
228Current Hop Limit : 0
229Force ARPND Wake up patterns : disabled
230Directed MAC Wake up patterns : disabled
231ECN capability : application
232
233Interface Wi-Fi Parameters
234-------------------------------
235IfLuid : wireless_32768
236IfIndex : 7
237State : connected
238Metric : 55
239Link MTU : 1500 bytes
240Reachable Time : 43500 ms
241Base Reachable Time : 30000 ms
242Retransmission Interval : 1000 ms
243DAD Transmits : 3
244Site Prefix Length : 64
245Site Id : 1
246Forwarding : disabled
247Advertising : disabled
248Neighbor Discovery : enabled
249Neighbor Unreachability Detection : enabled
250Router Discovery : dhcp
251Managed Address Configuration : enabled
252Other Stateful Configuration : enabled
253Weak Host Sends : disabled
254Weak Host Receives : disabled
255Use Automatic Metric : enabled
256Ignore Default Routes : disabled
257Advertised Router Lifetime : 1800 seconds
258Advertise Default Route : disabled
259Current Hop Limit : 0
260Force ARPND Wake up patterns : disabled
261Directed MAC Wake up patterns : disabled
262ECN capability : application
263"""
264    mock_exec_query.side_effect = lambda *args, **kargs: exc_query_output.split("\n")
265    metrics = _get_metrics()
266    print(metrics)
267    assert metrics == {'1': 75, '7': 55}
268
269test_get_metrics()
270
271############
272############
273+ Windows arch unit tests
274
275= Test PowerShell availability
276from scapy.config import conf
277assert conf.prog.powershell != None
278
279= Store powershell results
280import mock
281from scapy.config import conf
282
283ps_ip = get_ip_from_name(conf.iface.name)
284ps_if_list = get_windows_if_list()
285ps_read_routes = read_routes()
286
287# Turn on VBS mode
288conf.prog.powershell = None
289
290= Test get_ip_from_name with VBS
291ps_ip
292
293assert get_ip_from_name(conf.iface.name) == ps_ip
294
295= Test get_windows_if_list with VBS
296ps_if_list
297
298def is_in_if_list(i, list):
299    if not i["mac"]:
300        return True
301    for j in list:
302        if j["guid"] == i["guid"] and j["name"] == i["name"]:
303            return True
304    return False
305
306vbs_if_list = get_windows_if_list()
307vbs_if_list
308_correct = True
309for i in vbs_if_list:
310    if not is_in_if_list(i, ps_if_list):
311        _correct = False
312        break
313
314assert _correct
315
316= Test read_routes with VBS
317ps_read_routes
318
319def is_in_route_list(i, list):
320    # Ignore all empty IP or macs
321    if i[4] == '':
322        return True
323    if i[3].mac == '' or i[3].guid == '' or i[3].ip == '':
324        return True
325    for j in list:
326        if j[2] == i[2] and j[4] == i[4] and j[3].guid == i[3].guid:
327            return True
328    return False
329
330vbs_read_routes = read_routes()
331vbs_if_list
332_correct = True
333for i in vbs_read_routes:
334    if not is_in_route_list(i, ps_read_routes):
335        _correct = False
336        break
337
338assert _correct
339
340conf.prog._reload()
341
342= show_interfaces
343
344from scapy.arch import show_interfaces
345
346with ContextManagerCaptureOutput() as cmco:
347    show_interfaces()
348    lines = cmco.get_output().split("\n")[1:]
349    for l in lines:
350        if not l.strip():
351            continue
352        int(l[:2])
353
354= dev_from_pcapname
355
356from scapy.config import conf
357
358assert dev_from_pcapname(conf.iface.pcap_name).guid == conf.iface.guid
359
360= test pcap_service_status
361
362status = pcap_service_status()
363status
364assert status[0] in ["npcap", "npf"]
365assert status[2] == True
366
367= test pcap_service_stop
368
369pcap_service_stop()
370assert pcap_service_status()[2] == False
371
372= test pcap_service_start
373
374pcap_service_start()
375assert pcap_service_status()[2] == True
376
377= Test auto-pcap start UI
378
379old_ifaces = IFACES.data
380
381@mock.patch("scapy.arch.windows.get_if_list")
382def _test_autostart_ui(mocked_getiflist):
383    mocked_getiflist.side_effect = lambda: []
384    IFACES.reload()
385    assert IFACES.data == {}
386
387_test_autostart_ui()
388
389IFACES.data = old_ifaces