dissect.target 3.20.dev4__py3-none-any.whl → 3.20.dev5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dissect/target/helpers/record.py +7 -2
- dissect/target/plugins/general/network.py +8 -0
- dissect/target/plugins/os/windows/_os.py +1 -22
- dissect/target/plugins/os/windows/network.py +363 -0
- {dissect.target-3.20.dev4.dist-info → dissect.target-3.20.dev5.dist-info}/METADATA +1 -1
- {dissect.target-3.20.dev4.dist-info → dissect.target-3.20.dev5.dist-info}/RECORD +11 -10
- {dissect.target-3.20.dev4.dist-info → dissect.target-3.20.dev5.dist-info}/WHEEL +1 -1
- {dissect.target-3.20.dev4.dist-info → dissect.target-3.20.dev5.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.20.dev4.dist-info → dissect.target-3.20.dev5.dist-info}/LICENSE +0 -0
- {dissect.target-3.20.dev4.dist-info → dissect.target-3.20.dev5.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.20.dev4.dist-info → dissect.target-3.20.dev5.dist-info}/top_level.txt +0 -0
    
        dissect/target/helpers/record.py
    CHANGED
    
    | @@ -144,6 +144,7 @@ EmptyRecord = RecordDescriptor( | |
| 144 144 | 
             
            )
         | 
| 145 145 |  | 
| 146 146 | 
             
            COMMON_INTERFACE_ELEMENTS = [
         | 
| 147 | 
            +
                ("string", "source"),
         | 
| 147 148 | 
             
                ("string", "name"),
         | 
| 148 149 | 
             
                ("string", "type"),
         | 
| 149 150 | 
             
                ("boolean", "enabled"),
         | 
| @@ -151,7 +152,6 @@ COMMON_INTERFACE_ELEMENTS = [ | |
| 151 152 | 
             
                ("net.ipaddress[]", "dns"),
         | 
| 152 153 | 
             
                ("net.ipaddress[]", "ip"),
         | 
| 153 154 | 
             
                ("net.ipaddress[]", "gateway"),
         | 
| 154 | 
            -
                ("string", "source"),
         | 
| 155 155 | 
             
            ]
         | 
| 156 156 |  | 
| 157 157 |  | 
| @@ -165,8 +165,13 @@ WindowsInterfaceRecord = TargetRecordDescriptor( | |
| 165 165 | 
             
                [
         | 
| 166 166 | 
             
                    *COMMON_INTERFACE_ELEMENTS,
         | 
| 167 167 | 
             
                    ("varint", "vlan"),
         | 
| 168 | 
            -
                    (" | 
| 168 | 
            +
                    ("net.ipnetwork[]", "network"),
         | 
| 169 | 
            +
                    ("varint", "metric"),
         | 
| 170 | 
            +
                    ("stringlist", "search_domain"),
         | 
| 171 | 
            +
                    ("datetime", "first_connected"),
         | 
| 169 172 | 
             
                    ("datetime", "last_connected"),
         | 
| 173 | 
            +
                    ("net.ipaddress[]", "subnetmask"),
         | 
| 174 | 
            +
                    ("boolean", "dhcp"),
         | 
| 170 175 | 
             
                ],
         | 
| 171 176 | 
             
            )
         | 
| 172 177 |  | 
| @@ -3,6 +3,7 @@ from __future__ import annotations | |
| 3 3 | 
             
            from typing import Any, Iterator, Union
         | 
| 4 4 |  | 
| 5 5 | 
             
            from flow.record.fieldtypes.net import IPAddress, IPNetwork
         | 
| 6 | 
            +
            from flow.record.fieldtypes.net.ipv4 import Address, addr_long, addr_str, mask_to_bits
         | 
| 6 7 |  | 
| 7 8 | 
             
            from dissect.target.helpers.record import (
         | 
| 8 9 | 
             
                MacInterfaceRecord,
         | 
| @@ -80,3 +81,10 @@ class NetworkPlugin(Plugin): | |
| 80 81 | 
             
                    for interface in self.interfaces():
         | 
| 81 82 | 
             
                        if any(ip_addr in cidr for ip_addr in interface.ip):
         | 
| 82 83 | 
             
                            yield interface
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                def calculate_network(self, ips: int | Address, subnets: int | Address) -> Iterator[str]:
         | 
| 86 | 
            +
                    for ip, subnet_mask in zip(ips, subnets):
         | 
| 87 | 
            +
                        subnet_mask_int = addr_long(subnet_mask)
         | 
| 88 | 
            +
                        cidr = mask_to_bits(subnet_mask_int)
         | 
| 89 | 
            +
                        network_address = addr_str(addr_long(ip) & subnet_mask_int)
         | 
| 90 | 
            +
                        yield f"{network_address}/{cidr}"
         | 
| @@ -99,28 +99,7 @@ class WindowsPlugin(OSPlugin): | |
| 99 99 |  | 
| 100 100 | 
             
                @export(property=True)
         | 
| 101 101 | 
             
                def ips(self) -> list[str]:
         | 
| 102 | 
            -
                     | 
| 103 | 
            -
                    fields = ["IPAddress", "DhcpIPAddress"]
         | 
| 104 | 
            -
                    ips = set()
         | 
| 105 | 
            -
             | 
| 106 | 
            -
                    for r in self.target.registry.keys(key):
         | 
| 107 | 
            -
                        for s in r.subkeys():
         | 
| 108 | 
            -
                            for field in fields:
         | 
| 109 | 
            -
                                try:
         | 
| 110 | 
            -
                                    ip = s.value(field).value
         | 
| 111 | 
            -
                                except RegistryValueNotFoundError:
         | 
| 112 | 
            -
                                    continue
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                                if isinstance(ip, str):
         | 
| 115 | 
            -
                                    ip = [ip]
         | 
| 116 | 
            -
             | 
| 117 | 
            -
                                for i in ip:
         | 
| 118 | 
            -
                                    if i == "0.0.0.0":
         | 
| 119 | 
            -
                                        continue
         | 
| 120 | 
            -
             | 
| 121 | 
            -
                                    ips.add(i)
         | 
| 122 | 
            -
             | 
| 123 | 
            -
                    return list(ips)
         | 
| 102 | 
            +
                    return self.target.network.ips()
         | 
| 124 103 |  | 
| 125 104 | 
             
                def _get_version_reg_value(self, value_name: str) -> Any:
         | 
| 126 105 | 
             
                    try:
         | 
| @@ -0,0 +1,363 @@ | |
| 1 | 
            +
            from __future__ import annotations
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            from enum import IntEnum
         | 
| 4 | 
            +
            from typing import Iterator
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            from dissect.util.ts import wintimestamp
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            from dissect.target.exceptions import (
         | 
| 9 | 
            +
                RegistryKeyNotFoundError,
         | 
| 10 | 
            +
                RegistryValueNotFoundError,
         | 
| 11 | 
            +
            )
         | 
| 12 | 
            +
            from dissect.target.helpers.record import WindowsInterfaceRecord
         | 
| 13 | 
            +
            from dissect.target.helpers.regutil import RegistryKey
         | 
| 14 | 
            +
            from dissect.target.plugins.general.network import NetworkPlugin
         | 
| 15 | 
            +
             | 
| 16 | 
            +
             | 
| 17 | 
            +
            class IfTypes(IntEnum):
         | 
| 18 | 
            +
                OTHER = 1
         | 
| 19 | 
            +
                REGULAR_1822 = 2
         | 
| 20 | 
            +
                HDH_1822 = 3
         | 
| 21 | 
            +
                DDN_X25 = 4
         | 
| 22 | 
            +
                RFC877_X25 = 5
         | 
| 23 | 
            +
                ETHERNET_CSMACD = 6
         | 
| 24 | 
            +
                IS088023_CSMACD = 7
         | 
| 25 | 
            +
                ISO88024_TOKENBUS = 8
         | 
| 26 | 
            +
                ISO88025_TOKENRING = 9
         | 
| 27 | 
            +
                ISO88026_MAN = 10
         | 
| 28 | 
            +
                STARLAN = 11
         | 
| 29 | 
            +
                PROTEON_10MBIT = 12
         | 
| 30 | 
            +
                PROTEON_80MBIT = 13
         | 
| 31 | 
            +
                HYPERCHANNEL = 14
         | 
| 32 | 
            +
                FDDI = 15
         | 
| 33 | 
            +
                LAP_B = 16
         | 
| 34 | 
            +
                SDLC = 17
         | 
| 35 | 
            +
                DS1 = 18
         | 
| 36 | 
            +
                E1 = 19
         | 
| 37 | 
            +
                BASIC_ISDN = 20
         | 
| 38 | 
            +
                PRIMARY_ISDN = 21
         | 
| 39 | 
            +
                PROP_POINT2POINT_SERIAL = 22
         | 
| 40 | 
            +
                PPP = 23
         | 
| 41 | 
            +
                SOFTWARE_LOOPBACK = 24
         | 
| 42 | 
            +
                EON = 25
         | 
| 43 | 
            +
                ETHERNET_3MBIT = 26
         | 
| 44 | 
            +
                NSIP = 27
         | 
| 45 | 
            +
                SLIP = 28
         | 
| 46 | 
            +
                ULTRA = 29
         | 
| 47 | 
            +
                DS3 = 30
         | 
| 48 | 
            +
                SIP = 31
         | 
| 49 | 
            +
                FRAMERELAY = 32
         | 
| 50 | 
            +
                RS232 = 33
         | 
| 51 | 
            +
                PARA = 34
         | 
| 52 | 
            +
                ARCNET = 35
         | 
| 53 | 
            +
                ARCNET_PLUS = 36
         | 
| 54 | 
            +
                ATM = 37
         | 
| 55 | 
            +
                MIO_X25 = 38
         | 
| 56 | 
            +
                SONET = 39
         | 
| 57 | 
            +
                X25_PLE = 40
         | 
| 58 | 
            +
                ISO88022_LLC = 41
         | 
| 59 | 
            +
                LOCALTALK = 42
         | 
| 60 | 
            +
                SMDS_DXI = 43
         | 
| 61 | 
            +
                FRAMERELAY_SERVICE = 44
         | 
| 62 | 
            +
                V35 = 45
         | 
| 63 | 
            +
                HSSI = 46
         | 
| 64 | 
            +
                HIPPI = 47
         | 
| 65 | 
            +
                MODEM = 48
         | 
| 66 | 
            +
                AAL5 = 49
         | 
| 67 | 
            +
                SONET_PATH = 50
         | 
| 68 | 
            +
                SONET_VT = 51
         | 
| 69 | 
            +
                SMDS_ICIP = 52
         | 
| 70 | 
            +
                PROP_VIRTUAL = 53
         | 
| 71 | 
            +
                PROP_MULTIPLEXOR = 54
         | 
| 72 | 
            +
                IEEE80212 = 55
         | 
| 73 | 
            +
                FIBRECHANNEL = 56
         | 
| 74 | 
            +
                HIPPIINTERFACE = 57
         | 
| 75 | 
            +
                FRAMERELAY_INTERCONNECT = 58
         | 
| 76 | 
            +
                AFLANE_8023 = 59
         | 
| 77 | 
            +
                AFLANE_8025 = 60
         | 
| 78 | 
            +
                CCTEMUL = 61
         | 
| 79 | 
            +
                FASTETHER = 62
         | 
| 80 | 
            +
                ISDN = 63
         | 
| 81 | 
            +
                V11 = 64
         | 
| 82 | 
            +
                V36 = 65
         | 
| 83 | 
            +
                G703_64K = 66
         | 
| 84 | 
            +
                G703_2MB = 67
         | 
| 85 | 
            +
                QLLC = 68
         | 
| 86 | 
            +
                FASTETHER_FX = 69
         | 
| 87 | 
            +
                CHANNEL = 70
         | 
| 88 | 
            +
                IEEE80211 = 71
         | 
| 89 | 
            +
                IBM370PARCHAN = 72
         | 
| 90 | 
            +
                ESCON = 73
         | 
| 91 | 
            +
                DLSW = 74
         | 
| 92 | 
            +
                ISDN_S = 75
         | 
| 93 | 
            +
                ISDN_U = 76
         | 
| 94 | 
            +
                LAP_D = 77
         | 
| 95 | 
            +
                IPSWITCH = 78
         | 
| 96 | 
            +
                RSRB = 79
         | 
| 97 | 
            +
                ATM_LOGICAL = 80
         | 
| 98 | 
            +
                DS0 = 81
         | 
| 99 | 
            +
                DS0_BUNDLE = 82
         | 
| 100 | 
            +
                BSC = 83
         | 
| 101 | 
            +
                ASYNC = 84
         | 
| 102 | 
            +
                CNR = 85
         | 
| 103 | 
            +
                ISO88025R_DTR = 86
         | 
| 104 | 
            +
                EPLRS = 87
         | 
| 105 | 
            +
                ARAP = 88
         | 
| 106 | 
            +
                PROP_CNLS = 89
         | 
| 107 | 
            +
                HOSTPAD = 90
         | 
| 108 | 
            +
                TERMPAD = 91
         | 
| 109 | 
            +
                FRAMERELAY_MPI = 92
         | 
| 110 | 
            +
                X213 = 93
         | 
| 111 | 
            +
                ADSL = 94
         | 
| 112 | 
            +
                RADSL = 95
         | 
| 113 | 
            +
                SDSL = 96
         | 
| 114 | 
            +
                VDSL = 97
         | 
| 115 | 
            +
                ISO88025_CRFPRINT = 98
         | 
| 116 | 
            +
                MYRINET = 99
         | 
| 117 | 
            +
                VOICE_EM = 100
         | 
| 118 | 
            +
                VOICE_FXO = 101
         | 
| 119 | 
            +
                VOICE_FXS = 102
         | 
| 120 | 
            +
                VOICE_ENCAP = 103
         | 
| 121 | 
            +
                VOICE_OVERIP = 104
         | 
| 122 | 
            +
                ATM_DXI = 105
         | 
| 123 | 
            +
                ATM_FUNI = 106
         | 
| 124 | 
            +
                ATM_IMA = 107
         | 
| 125 | 
            +
                PPPMULTILINKBUNDLE = 108
         | 
| 126 | 
            +
                IPOVER_CDLC = 109
         | 
| 127 | 
            +
                IPOVER_CLAW = 110
         | 
| 128 | 
            +
                STACKTOSTACK = 111
         | 
| 129 | 
            +
                VIRTUALIPADDRESS = 112
         | 
| 130 | 
            +
                MPC = 113
         | 
| 131 | 
            +
                IPOVER_ATM = 114
         | 
| 132 | 
            +
                ISO88025_FIBER = 115
         | 
| 133 | 
            +
                TDLC = 116
         | 
| 134 | 
            +
                GIGABITETHERNET = 117
         | 
| 135 | 
            +
                HDLC = 118
         | 
| 136 | 
            +
                LAP_F = 119
         | 
| 137 | 
            +
                V37 = 120
         | 
| 138 | 
            +
                X25_MLP = 121
         | 
| 139 | 
            +
                X25_HUNTGROUP = 122
         | 
| 140 | 
            +
                TRANSPHDLC = 123
         | 
| 141 | 
            +
                INTERLEAVE = 124
         | 
| 142 | 
            +
                FAST = 125
         | 
| 143 | 
            +
                IP = 126
         | 
| 144 | 
            +
                DOCSCABLE_MACLAYER = 127
         | 
| 145 | 
            +
                DOCSCABLE_DOWNSTREAM = 128
         | 
| 146 | 
            +
                DOCSCABLE_UPSTREAM = 129
         | 
| 147 | 
            +
                A12MPPSWITCH = 130
         | 
| 148 | 
            +
                TUNNEL = 131
         | 
| 149 | 
            +
                COFFEE = 132
         | 
| 150 | 
            +
                CES = 133
         | 
| 151 | 
            +
                ATM_SUBINTERFACE = 134
         | 
| 152 | 
            +
                L2_VLAN = 135
         | 
| 153 | 
            +
                L3_IPVLAN = 136
         | 
| 154 | 
            +
                L3_IPXVLAN = 137
         | 
| 155 | 
            +
                DIGITALPOWERLINE = 138
         | 
| 156 | 
            +
                MEDIAMAILOVERIP = 139
         | 
| 157 | 
            +
                DTM = 140
         | 
| 158 | 
            +
                DCN = 141
         | 
| 159 | 
            +
                IPFORWARD = 142
         | 
| 160 | 
            +
                MSDSL = 143
         | 
| 161 | 
            +
                IEEE1394 = 144
         | 
| 162 | 
            +
                IF_GSN = 145
         | 
| 163 | 
            +
                DVBRCC_MACLAYER = 146
         | 
| 164 | 
            +
                DVBRCC_DOWNSTREAM = 147
         | 
| 165 | 
            +
                DVBRCC_UPSTREAM = 148
         | 
| 166 | 
            +
                ATM_VIRTUAL = 149
         | 
| 167 | 
            +
                MPLS_TUNNEL = 150
         | 
| 168 | 
            +
                SRP = 151
         | 
| 169 | 
            +
                VOICEOVERATM = 152
         | 
| 170 | 
            +
                VOICEOVERFRAMERELAY = 153
         | 
| 171 | 
            +
                IDSL = 154
         | 
| 172 | 
            +
                COMPOSITELINK = 155
         | 
| 173 | 
            +
                SS7_SIGLINK = 156
         | 
| 174 | 
            +
                PROP_WIRELESS_P2P = 157
         | 
| 175 | 
            +
                FR_FORWARD = 158
         | 
| 176 | 
            +
                RFC1483 = 159
         | 
| 177 | 
            +
                USB = 160
         | 
| 178 | 
            +
                IEEE8023AD_LAG = 161
         | 
| 179 | 
            +
                BGP_POLICY_ACCOUNTING = 162
         | 
| 180 | 
            +
                FRF16_MFR_BUNDLE = 163
         | 
| 181 | 
            +
                H323_GATEKEEPER = 164
         | 
| 182 | 
            +
                H323_PROXY = 165
         | 
| 183 | 
            +
                MPLS = 166
         | 
| 184 | 
            +
                MF_SIGLINK = 167
         | 
| 185 | 
            +
                HDSL2 = 168
         | 
| 186 | 
            +
                SHDSL = 169
         | 
| 187 | 
            +
                DS1_FDL = 170
         | 
| 188 | 
            +
                POS = 171
         | 
| 189 | 
            +
                DVB_ASI_IN = 172
         | 
| 190 | 
            +
                DVB_ASI_OUT = 173
         | 
| 191 | 
            +
                PLC = 174
         | 
| 192 | 
            +
                NFAS = 175
         | 
| 193 | 
            +
                TR008 = 176
         | 
| 194 | 
            +
                GR303_RDT = 177
         | 
| 195 | 
            +
                GR303_IDT = 178
         | 
| 196 | 
            +
                ISUP = 179
         | 
| 197 | 
            +
                PROP_DOCS_WIRELESS_MACLAYER = 180
         | 
| 198 | 
            +
                PROP_DOCS_WIRELESS_DOWNSTREAM = 181
         | 
| 199 | 
            +
                PROP_DOCS_WIRELESS_UPSTREAM = 182
         | 
| 200 | 
            +
                HIPERLAN2 = 183
         | 
| 201 | 
            +
                PROP_BWA_P2MP = 184
         | 
| 202 | 
            +
                SONET_OVERHEAD_CHANNEL = 185
         | 
| 203 | 
            +
                DIGITAL_WRAPPER_OVERHEAD_CHANNEL = 186
         | 
| 204 | 
            +
                AAL2 = 187
         | 
| 205 | 
            +
                RADIO_MAC = 188
         | 
| 206 | 
            +
                ATM_RADIO = 189
         | 
| 207 | 
            +
                IMT = 190
         | 
| 208 | 
            +
                MVL = 191
         | 
| 209 | 
            +
                REACH_DSL = 192
         | 
| 210 | 
            +
                FR_DLCI_ENDPT = 193
         | 
| 211 | 
            +
                ATM_VCI_ENDPT = 194
         | 
| 212 | 
            +
                OPTICAL_CHANNEL = 195
         | 
| 213 | 
            +
                OPTICAL_TRANSPORT = 196
         | 
| 214 | 
            +
                WWANPP = 243
         | 
| 215 | 
            +
                WWANPP2 = 244
         | 
| 216 | 
            +
             | 
| 217 | 
            +
             | 
| 218 | 
            +
            def _try_value(subkey: RegistryKey, value: str) -> str | list | None:
         | 
| 219 | 
            +
                try:
         | 
| 220 | 
            +
                    return subkey.value(value).value
         | 
| 221 | 
            +
                except RegistryValueNotFoundError:
         | 
| 222 | 
            +
                    return None
         | 
| 223 | 
            +
             | 
| 224 | 
            +
             | 
| 225 | 
            +
            class WindowsNetworkPlugin(NetworkPlugin):
         | 
| 226 | 
            +
                def _interfaces(self) -> Iterator[WindowsInterfaceRecord]:
         | 
| 227 | 
            +
                    # Get all the network interfaces
         | 
| 228 | 
            +
                    for keys in self.target.registry.keys(
         | 
| 229 | 
            +
                        "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e972-e325-11ce-bfc1-08002be10318}"
         | 
| 230 | 
            +
                    ):
         | 
| 231 | 
            +
                        for subkey in keys.subkeys():
         | 
| 232 | 
            +
                            device_info = {}
         | 
| 233 | 
            +
             | 
| 234 | 
            +
                            if (net_cfg_instance_id := _try_value(subkey, "NetCfgInstanceId")) is None:
         | 
| 235 | 
            +
                                # if no NetCfgInstanceId is found, skip this network interface
         | 
| 236 | 
            +
                                continue
         | 
| 237 | 
            +
             | 
| 238 | 
            +
                            # Extract the network device configuration for given interface id
         | 
| 239 | 
            +
                            config = self._extract_network_device_config(net_cfg_instance_id)
         | 
| 240 | 
            +
                            if config is None or all(not conf for conf in config):
         | 
| 241 | 
            +
                                # if no configuration is found or all configurations are empty, skip this network interface
         | 
| 242 | 
            +
                                continue
         | 
| 243 | 
            +
             | 
| 244 | 
            +
                            # Extract the network device name for given interface id
         | 
| 245 | 
            +
                            name_key = self.target.registry.key(
         | 
| 246 | 
            +
                                f"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Network\\"
         | 
| 247 | 
            +
                                f"{{4D36E972-E325-11CE-BFC1-08002BE10318}}\\{net_cfg_instance_id}\\Connection"
         | 
| 248 | 
            +
                            )
         | 
| 249 | 
            +
                            if value_name := _try_value(name_key, "Name"):
         | 
| 250 | 
            +
                                device_info["name"] = value_name
         | 
| 251 | 
            +
             | 
| 252 | 
            +
                            # Extract the metric value from the REGISTRY_KEY_INTERFACE key
         | 
| 253 | 
            +
                            interface_key = self.target.registry.key(
         | 
| 254 | 
            +
                                f"HKLM\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\{net_cfg_instance_id}"
         | 
| 255 | 
            +
                            )
         | 
| 256 | 
            +
                            if value_metric := _try_value(interface_key, "InterfaceMetric"):
         | 
| 257 | 
            +
                                device_info["metric"] = value_metric
         | 
| 258 | 
            +
             | 
| 259 | 
            +
                            # Extract the rest of the device information
         | 
| 260 | 
            +
                            device_info["mac"] = _try_value(subkey, "NetworkAddress")
         | 
| 261 | 
            +
                            device_info["vlan"] = _try_value(subkey, "VlanID")
         | 
| 262 | 
            +
             | 
| 263 | 
            +
                            if timestamp := _try_value(subkey, "NetworkInterfaceInstallTimestamp"):
         | 
| 264 | 
            +
                                device_info["first_connected"] = wintimestamp(timestamp)
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                            if type_device := _try_value(subkey, "*IfType"):
         | 
| 267 | 
            +
                                device_info["type"] = IfTypes(int(type_device)).name
         | 
| 268 | 
            +
             | 
| 269 | 
            +
                            # Yield a record for each non-empty configuration
         | 
| 270 | 
            +
                            for conf in config:
         | 
| 271 | 
            +
                                if conf:
         | 
| 272 | 
            +
                                    # Create a copy of device_info to avoid overwriting
         | 
| 273 | 
            +
                                    record_info = device_info.copy()
         | 
| 274 | 
            +
                                    record_info.update(conf)
         | 
| 275 | 
            +
                                    yield WindowsInterfaceRecord(
         | 
| 276 | 
            +
                                        **record_info,
         | 
| 277 | 
            +
                                        source=f"HKLM\\SYSTEM\\{subkey.path}",
         | 
| 278 | 
            +
                                        _target=self.target,
         | 
| 279 | 
            +
                                    )
         | 
| 280 | 
            +
             | 
| 281 | 
            +
                def _extract_network_device_config(
         | 
| 282 | 
            +
                    self, interface_id: str
         | 
| 283 | 
            +
                ) -> list[dict[str, str | list], dict[str, str | list]] | None:
         | 
| 284 | 
            +
                    dhcp_config = {}
         | 
| 285 | 
            +
                    static_config = {}
         | 
| 286 | 
            +
             | 
| 287 | 
            +
                    # Get the registry keys for the given interface id
         | 
| 288 | 
            +
                    try:
         | 
| 289 | 
            +
                        keys = self.target.registry.key(
         | 
| 290 | 
            +
                            f"HKLM\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\{interface_id}"
         | 
| 291 | 
            +
                        )
         | 
| 292 | 
            +
                    except RegistryKeyNotFoundError:
         | 
| 293 | 
            +
                        return None
         | 
| 294 | 
            +
             | 
| 295 | 
            +
                    if not len(keys):
         | 
| 296 | 
            +
                        return None
         | 
| 297 | 
            +
             | 
| 298 | 
            +
                    # Extract DHCP configuration from the registry
         | 
| 299 | 
            +
                    dhcp_gateway = _try_value(keys, "DhcpDefaultGateway")
         | 
| 300 | 
            +
                    if dhcp_gateway not in ["", "0.0.0.0", None, []]:
         | 
| 301 | 
            +
                        dhcp_config["gateway"] = dhcp_gateway
         | 
| 302 | 
            +
             | 
| 303 | 
            +
                    dhcp_ip = _try_value(keys, "DhcpIPAddress")
         | 
| 304 | 
            +
                    if dhcp_ip not in ["", "0.0.0.0", None]:
         | 
| 305 | 
            +
                        dhcp_config["ip"] = [dhcp_ip]
         | 
| 306 | 
            +
             | 
| 307 | 
            +
                    dhcp_dns = _try_value(keys, "DhcpNameServer")
         | 
| 308 | 
            +
                    if dhcp_dns not in ["", "0.0.0.0", None]:
         | 
| 309 | 
            +
                        dhcp_config["dns"] = dhcp_dns.split(" ")
         | 
| 310 | 
            +
             | 
| 311 | 
            +
                    dhcp_subnetmask = _try_value(keys, "DhcpSubnetMask")
         | 
| 312 | 
            +
                    if dhcp_subnetmask not in ["", "0.0.0.0", None]:
         | 
| 313 | 
            +
                        dhcp_config["subnetmask"] = [dhcp_subnetmask]
         | 
| 314 | 
            +
             | 
| 315 | 
            +
                    dhcp_domain = _try_value(keys, "DhcpDomain")
         | 
| 316 | 
            +
                    if dhcp_domain not in ["", None]:
         | 
| 317 | 
            +
                        dhcp_config["search_domain"] = [dhcp_domain]
         | 
| 318 | 
            +
             | 
| 319 | 
            +
                    if len(dhcp_config) > 0:
         | 
| 320 | 
            +
                        dhcp_enable = _try_value(keys, "EnableDHCP")
         | 
| 321 | 
            +
                        dhcp_config["enabled"] = dhcp_enable == 1
         | 
| 322 | 
            +
                        dhcp_config["dhcp"] = True
         | 
| 323 | 
            +
             | 
| 324 | 
            +
                    # Extract static configuration from the registry
         | 
| 325 | 
            +
                    static_gateway = _try_value(keys, "DefaultGateway")
         | 
| 326 | 
            +
                    if static_gateway not in ["", None, []]:
         | 
| 327 | 
            +
                        static_config["gateway"] = static_gateway
         | 
| 328 | 
            +
             | 
| 329 | 
            +
                    static_ip = _try_value(keys, "IPAddress")
         | 
| 330 | 
            +
                    if static_ip not in ["", "0.0.0.0", ["0.0.0.0"], None, []]:
         | 
| 331 | 
            +
                        static_config["ip"] = static_ip if isinstance(static_ip, list) else [static_ip]
         | 
| 332 | 
            +
             | 
| 333 | 
            +
                    static_dns = _try_value(keys, "NameServer")
         | 
| 334 | 
            +
                    if static_dns not in ["", "0.0.0.0", None]:
         | 
| 335 | 
            +
                        static_config["dns"] = static_dns.split(",")
         | 
| 336 | 
            +
             | 
| 337 | 
            +
                    static_subnetmask = _try_value(keys, "SubnetMask")
         | 
| 338 | 
            +
                    if static_subnetmask not in ["", "0.0.0.0", ["0.0.0.0"], None, []]:
         | 
| 339 | 
            +
                        static_config["subnetmask"] = (
         | 
| 340 | 
            +
                            static_subnetmask if isinstance(static_subnetmask, list) else [static_subnetmask]
         | 
| 341 | 
            +
                        )
         | 
| 342 | 
            +
             | 
| 343 | 
            +
                    static_domain = _try_value(keys, "Domain")
         | 
| 344 | 
            +
                    if static_domain not in ["", None]:
         | 
| 345 | 
            +
                        static_config["search_domain"] = [static_domain]
         | 
| 346 | 
            +
             | 
| 347 | 
            +
                    if len(static_config) > 0:
         | 
| 348 | 
            +
                        static_config["enabled"] = None
         | 
| 349 | 
            +
                        static_config["dhcp"] = False
         | 
| 350 | 
            +
             | 
| 351 | 
            +
                    # Combine ip and subnetmask for extraction
         | 
| 352 | 
            +
                    combined_configs = [
         | 
| 353 | 
            +
                        (dhcp_config, dhcp_config.get("ip", []), dhcp_config.get("subnetmask", [])),
         | 
| 354 | 
            +
                        (static_config, static_config.get("ip", []), static_config.get("subnetmask", [])),
         | 
| 355 | 
            +
                    ]
         | 
| 356 | 
            +
             | 
| 357 | 
            +
                    # Iterate over combined ip/subnet lists
         | 
| 358 | 
            +
                    for config, ips, subnet_masks in combined_configs:
         | 
| 359 | 
            +
                        for network_address in self.calculate_network(ips, subnet_masks):
         | 
| 360 | 
            +
                            config.setdefault("network", []).append(network_address)
         | 
| 361 | 
            +
             | 
| 362 | 
            +
                    # Return both configurations
         | 
| 363 | 
            +
                    return [dhcp_config, static_config]
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Metadata-Version: 2.1
         | 
| 2 2 | 
             
            Name: dissect.target
         | 
| 3 | 
            -
            Version: 3.20. | 
| 3 | 
            +
            Version: 3.20.dev5
         | 
| 4 4 | 
             
            Summary: This module ties all other Dissect modules together, it provides a programming API and command line tools which allow easy access to various data sources inside disk images or file collections (a.k.a. targets)
         | 
| 5 5 | 
             
            Author-email: Dissect Team <dissect@fox-it.com>
         | 
| 6 6 | 
             
            License: Affero General Public License v3
         | 
| @@ -61,7 +61,7 @@ dissect/target/helpers/mui.py,sha256=i-7XoHbu4WO2fYapK9yGAMW04rFlgRispknc1KQIS5Q | |
| 61 61 | 
             
            dissect/target/helpers/network_managers.py,sha256=ByBSe2K3c8hgQC6dokcf-hHdmPcD8PmrOj0xs1C3yhs,25743
         | 
| 62 62 | 
             
            dissect/target/helpers/polypath.py,sha256=h8p7m_OCNiQljGwoZh5Aflr9H2ot6CZr6WKq1OSw58o,2175
         | 
| 63 63 | 
             
            dissect/target/helpers/protobuf.py,sha256=b4DsnqrRLrefcDjx7rQno-_LBcwtJXxuKf5RdOegzfE,1537
         | 
| 64 | 
            -
            dissect/target/helpers/record.py,sha256= | 
| 64 | 
            +
            dissect/target/helpers/record.py,sha256=euNDDZi29fo8ENN1gsPycB38OMn35clLM9_K-srZ5E0,5852
         | 
| 65 65 | 
             
            dissect/target/helpers/record_modifier.py,sha256=O_Jj7zOi891HIyAYjxxe6LFPYETHdMa5lNjo4NA_T_w,3969
         | 
| 66 66 | 
             
            dissect/target/helpers/regutil.py,sha256=kX-sSZbW8Qkg29Dn_9zYbaQrwLumrr4Y8zJ1EhHXIAM,27337
         | 
| 67 67 | 
             
            dissect/target/helpers/shell_application_ids.py,sha256=hYxrP-YtHK7ZM0ectJFHfoMB8QUXLbYNKmKXMWLZRlA,38132
         | 
| @@ -184,7 +184,7 @@ dissect/target/plugins/general/config.py,sha256=Mdy9uhWn4OJ96zfXpLgjVifV5SrViqHn | |
| 184 184 | 
             
            dissect/target/plugins/general/default.py,sha256=8W_9JV3jKEeETlyTrB25sACoIIFmmO8wlVU5Zoi51W0,1425
         | 
| 185 185 | 
             
            dissect/target/plugins/general/example.py,sha256=6B_YOqajRBLNWBEOfIL_HnLaEANBF8KKoc0mweihiug,6034
         | 
| 186 186 | 
             
            dissect/target/plugins/general/loaders.py,sha256=6iUxhlSAgo7qSE8_XFxgiihK8sdMiP-s4k0W5Iv8m9k,879
         | 
| 187 | 
            -
            dissect/target/plugins/general/network.py,sha256= | 
| 187 | 
            +
            dissect/target/plugins/general/network.py,sha256=1dCWiVIaVPySquRs3YEsP7PxXXU5voa8CsxyIa7Vh54,2882
         | 
| 188 188 | 
             
            dissect/target/plugins/general/osinfo.py,sha256=RdK5mw3-H9H3sGXz8yP8U_p3wUG1Ww7_HBKZpFdsbTE,1358
         | 
| 189 189 | 
             
            dissect/target/plugins/general/plugins.py,sha256=4URjS6DN1Ey6Cqlbyx6NfFGgQZpWDrqxl8KLcZFODGE,4479
         | 
| 190 190 | 
             
            dissect/target/plugins/general/scrape.py,sha256=Fz7BNXflvuxlnVulyyDhLpyU8D_hJdH6vWVtER9vjTg,6651
         | 
| @@ -262,7 +262,7 @@ dissect/target/plugins/os/unix/log/lastlog.py,sha256=Wq89wRSFZSBsoKVCxjDofnC4yw9 | |
| 262 262 | 
             
            dissect/target/plugins/os/unix/log/messages.py,sha256=CXA-SkMPLaCgnTQg9nzII-7tO8Il_ENQmuYvDxo33rI,4698
         | 
| 263 263 | 
             
            dissect/target/plugins/os/unix/log/utmp.py,sha256=1nPHIaBUHt_9z6PDrvyqg4huKLihUaWLrMmgMsbaeIo,7755
         | 
| 264 264 | 
             
            dissect/target/plugins/os/windows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 265 | 
            -
            dissect/target/plugins/os/windows/_os.py,sha256 | 
| 265 | 
            +
            dissect/target/plugins/os/windows/_os.py,sha256=-x5TD5BvFw-7zEfqT6WG7n04YSeyr7wVLO07y6xkBP8,12476
         | 
| 266 266 | 
             
            dissect/target/plugins/os/windows/activitiescache.py,sha256=Q2aILnhJ2rp2AwEbWwyBuSLjMbGqaYJTsavSbfkcFKE,6741
         | 
| 267 267 | 
             
            dissect/target/plugins/os/windows/adpolicy.py,sha256=qjv0s-gAIGKCznWdVOARJbLXnCKYgvzoFNWoXnq3m1M,7102
         | 
| 268 268 | 
             
            dissect/target/plugins/os/windows/amcache.py,sha256=ZZNOs3bILTf0AGkDkhoatndl0j39DXkstN7oOyxJECU,27188
         | 
| @@ -276,6 +276,7 @@ dissect/target/plugins/os/windows/generic.py,sha256=BSvDPfB9faU0uquMj0guw5tnR_97 | |
| 276 276 | 
             
            dissect/target/plugins/os/windows/jumplist.py,sha256=3gZk6O1B3lKK2Jxe0B-HapOCEehk94CYNvCVDpQC9nQ,11773
         | 
| 277 277 | 
             
            dissect/target/plugins/os/windows/lnk.py,sha256=toEZV00CESLUsF7UmN65-ivWk0Ijg-ZPST0qyD-antY,7860
         | 
| 278 278 | 
             
            dissect/target/plugins/os/windows/locale.py,sha256=yXVdclpUqss9h8Nq7N4kg3OHwWGDfjdfiLiUZR3wqv8,2324
         | 
| 279 | 
            +
            dissect/target/plugins/os/windows/network.py,sha256=nKNgCqVjzjPwkwyXIIgIIECO2UEYnzvM0PzqRVtCGls,10788
         | 
| 279 280 | 
             
            dissect/target/plugins/os/windows/notifications.py,sha256=T1CIvQgpW__qDR0Rq5zpeWmRWwjNDpvdMnvJJ_6tZXs,17378
         | 
| 280 281 | 
             
            dissect/target/plugins/os/windows/prefetch.py,sha256=v4OgSKMwcihz0SOuA0o0Ec8wsAKuiuEmJolqZmHFgJA,10491
         | 
| 281 282 | 
             
            dissect/target/plugins/os/windows/recyclebin.py,sha256=zx58hDCvcrD_eJl9nJmr_i80krSN03ya8nQzWFr2Tw0,4917
         | 
| @@ -364,10 +365,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z | |
| 364 365 | 
             
            dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
         | 
| 365 366 | 
             
            dissect/target/volumes/md.py,sha256=7ShPtusuLGaIv27SvEETtgsuoQyAa4iAAeOR1NEaajI,1689
         | 
| 366 367 | 
             
            dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
         | 
| 367 | 
            -
            dissect.target-3.20. | 
| 368 | 
            -
            dissect.target-3.20. | 
| 369 | 
            -
            dissect.target-3.20. | 
| 370 | 
            -
            dissect.target-3.20. | 
| 371 | 
            -
            dissect.target-3.20. | 
| 372 | 
            -
            dissect.target-3.20. | 
| 373 | 
            -
            dissect.target-3.20. | 
| 368 | 
            +
            dissect.target-3.20.dev5.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
         | 
| 369 | 
            +
            dissect.target-3.20.dev5.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
         | 
| 370 | 
            +
            dissect.target-3.20.dev5.dist-info/METADATA,sha256=mipPixfWzRYRNCdlpu5JgLbNjA68Tb246PTVHNQk54E,12896
         | 
| 371 | 
            +
            dissect.target-3.20.dev5.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
         | 
| 372 | 
            +
            dissect.target-3.20.dev5.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
         | 
| 373 | 
            +
            dissect.target-3.20.dev5.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
         | 
| 374 | 
            +
            dissect.target-3.20.dev5.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         |