Home | History | Annotate | Download | only in test
      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 
     11 class TimeOutSelector(SelectableObject):
     12     def check_recv(self):
     13         return False
     14 
     15 assert select_objects([TimeOutSelector()], 0) == []
     16 assert select_objects([TimeOutSelector()], 1) == []
     17 
     18 ############
     19 ############
     20 + Windows Networking tests
     21 
     22 = Mocked read_routes6() calls
     23 
     24 import mock
     25 from scapy.tools.UTscapy import Bunch
     26 from scapy.arch.windows import _read_routes6_post2008
     27 
     28 def 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 
     38 def 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")
     56 def 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 = """
     60 ifIndex           : 3
     61 DestinationPrefix : ff00::/8
     62 NextHop           : ::
     63 RouteMetric       : 0
     64 InterfaceMetric   : 1
     65 
     66 ifIndex           : 16
     67 DestinationPrefix : ff00::/8
     68 NextHop           : ::
     69 RouteMetric       : 0
     70 InterfaceMetric   : 1
     71 
     72 ifIndex           : 13
     73 DestinationPrefix : ff00::/8
     74 NextHop           : ::
     75 RouteMetric       : 0
     76 InterfaceMetric   : 1
     77 
     78 ifIndex           : 1
     79 DestinationPrefix : ff00::/8
     80 NextHop           : ::
     81 RouteMetric       : 0
     82 InterfaceMetric   : 1
     83 
     84 ifIndex           : 13
     85 DestinationPrefix : fe80::dc1d:24e8:af00:125e/128
     86 NextHop           : ::
     87 RouteMetric       : 20
     88 InterfaceMetric   : 256
     89 
     90 ifIndex           : 3
     91 DestinationPrefix : fe80::9402:5804:cb16:fb3b/128
     92 NextHop           : ::
     93 RouteMetric       : 1
     94 InterfaceMetric   : 0
     95 
     96 ifIndex           : 16
     97 DestinationPrefix : fe80::100:7f:fffe/128
     98 NextHop           : ::
     99 RouteMetric       : 1
    100 InterfaceMetric   : 0
    101 
    102 ifIndex           : 3
    103 DestinationPrefix : fe80::/64
    104 NextHop           : ::
    105 RouteMetric       : 0
    106 InterfaceMetric   : 1
    107 
    108 ifIndex           : 16
    109 DestinationPrefix : fe80::/64
    110 NextHop           : ::
    111 RouteMetric       : 0
    112 InterfaceMetric   : 1
    113 
    114 ifIndex           : 13
    115 DestinationPrefix : fe80::/64
    116 NextHop           : ::
    117 RouteMetric       : 0
    118 InterfaceMetric   : 1
    119 
    120 ifIndex           : 13
    121 DestinationPrefix : 2a01:e35:2f17:fe60:dc1d:24e8:af00:125e/128
    122 NextHop           : ::
    123 RouteMetric       : 20
    124 InterfaceMetric   : 256
    125 
    126 ifIndex           : 13
    127 DestinationPrefix : 2a01:e35:2f17:fe60::/64
    128 NextHop           : ::
    129 RouteMetric       : 30
    130 InterfaceMetric   : 256
    131 
    132 ifIndex           : 1
    133 DestinationPrefix : ::1/128
    134 NextHop           : ::
    135 RouteMetric       : 0
    136 InterfaceMetric   : 256
    137 
    138 ifIndex           : 13
    139 DestinationPrefix : ::/0
    140 NextHop           : fe80::224:d4ff:fea0:a6d7
    141 RouteMetric       : 0
    142 InterfaceMetric   : 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 
    159 test_read_routes6_windows()
    160 
    161 = Test _read_routes_post2008 with missing InterfaceMetric
    162 
    163 from 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")
    169 def test_missing_ifacemetric(mock_dev_from_index, mock_winpcapylist, mock_exec_query, mock_get_metrics):
    170     exc_query_output = """ifIndex           : 3
    171 DestinationPrefix : 255.255.255.255/0
    172 NextHop           : 192.168.103.1
    173 RouteMetric       : 10
    174 InterfaceMetric   : 256
    175 
    176 ifIndex           : 13
    177 DestinationPrefix : 255.255.255.255/32
    178 NextHop           : 0.0.0.0
    179 RouteMetric       : 20
    180 InterfaceMetric   :
    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 
    194 test_missing_ifacemetric()
    195 
    196 = Test _get_metrics with weird netsh length
    197 
    198 from scapy.arch.windows import _get_metrics
    199 
    200 @mock.patch("scapy.arch.windows.POWERSHELL_PROCESS.query")
    201 def test_get_metrics(mock_exec_query):
    202     exc_query_output = """Interface Loopback Pseudo-Interface 1 Parameters
    203 -------------------------------
    204 IfLuid : loopback_0
    205 IfIndex : 1
    206 State : connected
    207 Metric : 75
    208 Link MTU : 4294967295 byt
    209 Reachable Time : 40500 ms
    210 Base Reachable Time : 30000 ms
    211 Retransmission Interval : 1000 ms
    212 DAD Transmits : 0
    213 Site Prefix Length : 64
    214 Site Id : 1
    215 Forwarding : disabled
    216 Advertising : disabled
    217 Neighbor Discovery : disabled
    218 Neighbor Unreachability Detection : disabled
    219 Router Discovery : dhcp
    220 Managed Address Configuration : enabled
    221 Other Stateful Configuration : enabled
    222 Weak Host Sends : disabled
    223 Weak Host Receives : disabled
    224 Use Automatic Metric : enabled
    225 Ignore Default Routes : disabled
    226 Advertised Router Lifetime : 1800 seconds
    227 Advertise Default Route : disabled
    228 Current Hop Limit : 0
    229 Force ARPND Wake up patterns : disabled
    230 Directed MAC Wake up patterns : disabled
    231 ECN capability : application
    232 
    233 Interface Wi-Fi Parameters
    234 -------------------------------
    235 IfLuid : wireless_32768
    236 IfIndex : 7
    237 State : connected
    238 Metric : 55
    239 Link MTU : 1500 bytes
    240 Reachable Time : 43500 ms
    241 Base Reachable Time : 30000 ms
    242 Retransmission Interval : 1000 ms
    243 DAD Transmits : 3
    244 Site Prefix Length : 64
    245 Site Id : 1
    246 Forwarding : disabled
    247 Advertising : disabled
    248 Neighbor Discovery : enabled
    249 Neighbor Unreachability Detection : enabled
    250 Router Discovery : dhcp
    251 Managed Address Configuration : enabled
    252 Other Stateful Configuration : enabled
    253 Weak Host Sends : disabled
    254 Weak Host Receives : disabled
    255 Use Automatic Metric : enabled
    256 Ignore Default Routes : disabled
    257 Advertised Router Lifetime : 1800 seconds
    258 Advertise Default Route : disabled
    259 Current Hop Limit : 0
    260 Force ARPND Wake up patterns : disabled
    261 Directed MAC Wake up patterns : disabled
    262 ECN 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 
    269 test_get_metrics()
    270 
    271 ############
    272 ############
    273 + Windows arch unit tests
    274 
    275 = Test PowerShell availability
    276 from scapy.config import conf
    277 assert conf.prog.powershell != None
    278 
    279 = Store powershell results
    280 import mock
    281 from scapy.config import conf
    282 
    283 ps_ip = get_ip_from_name(conf.iface.name)
    284 ps_if_list = get_windows_if_list()
    285 ps_read_routes = read_routes()
    286 
    287 # Turn on VBS mode
    288 conf.prog.powershell = None
    289 
    290 = Test get_ip_from_name with VBS
    291 ps_ip
    292 
    293 assert get_ip_from_name(conf.iface.name) == ps_ip
    294 
    295 = Test get_windows_if_list with VBS
    296 ps_if_list
    297 
    298 def 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 
    306 vbs_if_list = get_windows_if_list()
    307 vbs_if_list
    308 _correct = True
    309 for i in vbs_if_list:
    310     if not is_in_if_list(i, ps_if_list):
    311         _correct = False
    312         break
    313 
    314 assert _correct
    315 
    316 = Test read_routes with VBS
    317 ps_read_routes
    318 
    319 def 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 
    330 vbs_read_routes = read_routes()
    331 vbs_if_list
    332 _correct = True
    333 for i in vbs_read_routes:
    334     if not is_in_route_list(i, ps_read_routes):
    335         _correct = False
    336         break
    337 
    338 assert _correct
    339 
    340 conf.prog._reload()
    341 
    342 = show_interfaces
    343 
    344 from scapy.arch import show_interfaces
    345 
    346 with 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 
    356 from scapy.config import conf
    357 
    358 assert dev_from_pcapname(conf.iface.pcap_name).guid == conf.iface.guid
    359 
    360 = test pcap_service_status
    361 
    362 status = pcap_service_status()
    363 status
    364 assert status[0] in ["npcap", "npf"]
    365 assert status[2] == True
    366 
    367 = test pcap_service_stop
    368 
    369 pcap_service_stop()
    370 assert pcap_service_status()[2] == False
    371 
    372 = test pcap_service_start
    373 
    374 pcap_service_start()
    375 assert pcap_service_status()[2] == True
    376 
    377 = Test auto-pcap start UI
    378 
    379 old_ifaces = IFACES.data
    380 
    381 @mock.patch("scapy.arch.windows.get_if_list")
    382 def _test_autostart_ui(mocked_getiflist):
    383     mocked_getiflist.side_effect = lambda: []
    384     IFACES.reload()
    385     assert IFACES.data == {}
    386 
    387 _test_autostart_ui()
    388 
    389 IFACES.data = old_ifaces