def userassist(cfg, user_hives): rows = [["Target", "Run Count", "Focus (ms)", "Last Run"]] for username, uhive in user_hives.iteritems(): for key in common.find_keys_name( common.safe_open( uhive, "Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist" ), "Count", 2): for value in common.safe_open(uhive, key).values(): vals = {} vals["Target"] = codecs.encode(value.name(), 'rot_13').replace('\0', '') if "UEME_" in vals["Target"]: continue for guid in guids.keys(): up = vals["Target"].upper() if guid in up: vals["Target"] = up.replace(guid, guids[guid]) data = value.value() vals["Run Count"] = struct.unpack("I", data[4:8])[0] vals["Focus (ms)"] = struct.unpack("I", data[12:16])[0] if struct.unpack("Q", data[60:68])[0]: vals["Last Run"] = common.decode_filetime(data[60:68]) output.dict_to_arr(rows, vals) if len(rows) > 1: rows = output.sort_by_col(rows, "Target") output.write_out(cfg, rows, "Userassist - %s" % username, 1)
def sessionmgr(cfg, hives): if "system" in hives.keys(): if "cset" not in cfg.keys(): cfg['cset'] = common.get_control_set(hives['system']) # Pending file ops rows = [["Source", "Destination"]] #https://forensicatorj.wordpress.com/2014/06/25/interpreting-the-pendingfilerenameoperations-registry-key-for-forensics/ ops = common.safe_open( hives["system"], "ControlSet00%s\Control\Session Manager" % cfg['cset'], "PendingFileRenameOperations").value() i = 0 while i < len(ops): if ops[i]: vals = {"Source": ops[i]} if ops[i + 2]: vals["Destination"] = ops[i + 2] elif ops[i + 1] == '' and ops[i + 2] == '': vals["Destination"] = "Delete" output.dict_to_arr(rows, vals) i += 4 output.write_out(cfg, rows, "Pending File Renames", 1) # Environment vars rows = [["Name", "Value"]] for var in common.safe_open( hives["system"], "ControlSet00%s\Control\Session Manager\Environment" % cfg['cset']).values(): vals = {} vals["Name"] = var.name() vals["Value"] = common.multi_string(var) output.dict_to_arr(rows, vals) output.write_out(cfg, rows, "System Environment Variables", 1)
def networks(cfg, hives): if "software" in hives.keys(): rows = [[ 'Name', 'Description', 'Category', 'Type', 'Managed', 'Gateway MAC', 'DNS suffix', 'Created', 'Last connected' ]] for profile in common.safe_open( hives["software"], "Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles" ).subkeys(): vals = {} for value in profile.values(): if value.name() == "ProfileName": vals["Name"] = common.multi_string(value) elif value.name() == "Description": vals["Description"] = common.multi_string(value) elif value.name() == "NameType": n = value.value() if n == 0x06: vals["Type"] = "Wired" elif n == 0x17: vals["Type"] = "Mobile (%d)" % n elif n == 0x47: vals["Type"] = "Wireless" elif n == 0xf3: vals["Type"] = "Mobile (%d)" % n else: vals["Type"] = "Unknown (%d)" % n elif value.name() == "Managed": vals["Managed"] = "Yes" if value.value() else "No" elif value.name() == "Category": n = value.value() if not n: vals["Category"] = "Public" elif n == 1: vals["Category"] = "Private" elif n == 2: vals["Category"] = "Domain" else: vals["Category"] = "Other (%d)" % n elif value.name() == "DateCreated": vals["Created"] = common.decode_systemtime(value.value()) elif value.name() == "DateLastConnected": vals["Last connected"] = common.decode_systemtime( value.value()) sig = common.find_keys_value( hives['software'].open( "Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures" ), profile.name(), 2) if sig: vals["DNS suffix"] = common.safe_open(hives["software"], sig[0], "DnsSuffix").value() vals["Gateway MAC"] = bin_to_mac( common.safe_open(hives["software"], sig[0], "DefaultGatewayMac").value()) output.dict_to_arr(rows, vals) output.write_out(cfg, rows, "Networks", 1)
def osinfo(cfg, hives): if "software" in hives.keys(): rows = [[ "Registered Owner", "Registered Org", "Operating System", "Service Pack", "Product ID", "Install Type", "Install Date", "Build String (ext)", "Install Path", "Source Path" ]] pairs = {} for value in common.safe_open( hives["software"], "Microsoft\Windows NT\CurrentVersion").values(): if value.name() == "ProductName": pairs["Operating System"] = value.value() elif value.name() == "CSDVersion": pairs["Service Pack"] = value.value() elif value.name() == "BuildLabEx": pairs["Build String (ext)"] = value.value() elif value.name() == "InstallDate": pairs["Install Date"] = common.decode_epoch(value.value()) elif value.name() == "ProductId": pairs["Product ID"] = value.value() elif value.name() == "RegisteredOwner": pairs["Registered Owner"] = value.value() elif value.name() == "RegisteredOrganization": pairs["Registered Org"] = value.value() elif value.name() == "PathName": pairs["Install Path"] = value.value() elif value.name() == "SourcePath": pairs["Source Path"] = value.value() elif value.name() == "InstallationType": pairs["Install Type"] = value.value() elif value.name() == "": pairs[""] = value.value() output.dict_to_arr(rows, pairs) output.write_out(cfg, rows, "OS Info")
def geninfo(cfg, hives): if "system" in hives.keys(): if "cset" not in cfg.keys(): cfg["cset"] = common.get_control_set(hives['system']) rows = [["Hostname", "Last Shutdown"]] pairs = {} pairs["Hostname"] = common.safe_open( hives['system'], "ControlSet00%s\\Services\\Tcpip\\Parameters" % cfg['cset'], "Hostname").value() ft = common.safe_open(hives['system'], "ControlSet00%s\\Control\\Windows" % cfg['cset'], "ShutdownTime").value() pairs["Last Shutdown"] = common.decode_filetime(ft) output.dict_to_arr(rows, pairs) output.write_out(cfg, rows, "General Info")
def nobackups(cfg, hives): if "system" in hives.keys(): if "cset" not in cfg.keys(): cfg['cset'] = common.get_control_set(hives['system']) for subkey in common.safe_open( hives['system'], "ControlSet00%s\Control\BackupRestore" % cfg["cset"]).subkeys(): exs = [["Name", "Value"]] if subkey.name() == "FilesNotToBackup": ex_name = "Files not to backup" elif subkey.name() == "FilesNotToSnapshot": ex_name = "Files not to snapshot" elif subkey.name() == "KeysNotToRestore": ex_name = "Keys not to restore" else: continue for value in subkey.values(): # Print a row for each reg_multi_sz string vals = {"Name": value.name()} for i, ex in enumerate(value.value()): if len(ex): vals["Value"] = ex output.dict_to_arr(exs, vals) if len(exs) > 1: rows = [[ "Last write" ], [subkey.timestamp().strftime('%a %b %d %Y %H:%M:%S UTC')]] output.write_out(cfg, rows, ex_name) output.write_out(cfg, exs, "", 1)
def uninstalls(cfg, hives): if "software" in hives.keys(): rows = [[ "Publisher", "Name", "Version", "Installed", "Install Src", "Install Dst" ]] keys = common.safe_open( hives["software"], "Microsoft\Windows\CurrentVersion\Uninstall" ).subkeys() + common.safe_open( hives["software"], "Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall").subkeys( ) for key in common.find_keys_name( common.safe_open( hives['software'], "Microsoft\Windows\CurrentVersion\Installer\UserData"), "InstallProperties", 3): keys.append(common.safe_open(hives['software'], key)) for uninstall in keys: vals = {} vals["Installed"] = uninstall.timestamp().strftime( '%a %b %d %Y %H:%M:%S UTC') for val in uninstall.values(): if val.name() == "DisplayName": vals["Name"] = common.unicode_to_ascii(val.value()) elif val.name() == "DisplayVersion": vals["Version"] = common.unicode_to_ascii(val.value()) elif val.name() == "Publisher": vals["Publisher"] = common.unicode_to_ascii(val.value()) elif val.name() == "InstallSource": vals["Install Src"] = common.unicode_to_ascii(val.value()) elif val.name() == "InstallLocation": vals["Install Dst"] = common.unicode_to_ascii(val.value()) # Skip subkeys with no relevant values if "Name" not in vals.keys() and "Version" not in vals.keys( ) and "Install Dst" not in vals.keys(): continue output.dict_to_arr(rows, vals) dedup(rows) rows = output.sort_by_col(rows, "Name") output.write_out(cfg, rows, "Software", 1)
def autoruns(cfg, hives, user_hives): rows = [['Source', 'Name', 'Run Value']] keys = ["Run", "RunOnce", "RunOnceEx"] if "software" in hives.keys(): for key in keys: for run in common.safe_open( hives["software"], "Microsoft\Windows\CurrentVersion\%s" % key).values(): vals = {"Source": "Software:%s" % key} vals["Name"] = run.name() vals["Run Value"] = run.value() output.dict_to_arr(rows, vals) for username, uhive in user_hives.iteritems(): for key in keys: for run in common.safe_open( uhive, "Software\Microsoft\Windows\CurrentVersion\%s" % key).values(): vals = {"Source": "%s:%s" % (username, key)} vals["Name"] = run.name() vals["Run Value"] = run.value() output.dict_to_arr(rows, vals) output.write_out(cfg, rows, "Autoruns", 1)
def usermounts(cfg, hives, user_hives): for username, uhive in user_hives.iteritems(): rows = [[ "Volume GUID", "Last Mounted", "Mount Point", "Nuke on Delete" ]] for mpkey in common.safe_open( uhive, "Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2" ).subkeys(): vals = {"Volume GUID": mpkey.name()} vals["Last Mounted"] = mpkey.timestamp().strftime( '%a %b %d %Y %H:%M:%S UTC') # Find NukeOnDelete volbb = common.find_keys_name( common.safe_open( uhive, "Software\Microsoft\Windows\CurrentVersion\Explorer\BitBucket\Volume" ), mpkey.name(), 1) if volbb: bbkey = common.safe_open(uhive, volbb[0]) if bbkey.name() and bbkey.value("NukeOnDelete").value(): vals["Nuke on Delete"] = "Yes" elif bbkey.name(): vals["Nuke on Delete"] = "No" # Find mount point if "system" in hives.keys(): for point in hives["system"].open("MountedDevices").values(): if mpkey.name() in point.name(): keys = common.find_value_names( hives["system"].open("MountedDevices"), point.value()) for key in keys: valname = key.split('\\')[-1] ptname = point.name().split('\\')[-1] if valname != ptname: vals["Mount Point"] = key break output.dict_to_arr(rows, vals) output.write_out(cfg, rows, "User Mounts - %s" % username, 1)
def profiles(cfg, hives): rows = [["ID", "Path", "Last Load", "Key Last Write"]] if "software" in hives.keys(): for subkey in common.safe_open(hives["software"], "Microsoft\Windows NT\CurrentVersion\ProfileList").subkeys(): vals = {} vals["ID"] = subkey.name() vals["Path"] = subkey.value("ProfileImagePath").value() vals["Key Last Write"] = subkey.timestamp().strftime('%a %b %d %Y %H:%M:%S UTC') try: a = subkey.value("ProfileLoadTimeLow").value() b = subkey.value("ProfileLoadTimeHigh").value() if a and b: a = struct.pack('II', a, b) vals["Last Load"] = common.decode_filetime(a) except: pass output.dict_to_arr(rows, vals) output.write_out(cfg, rows, "Local Profiles", 1)
def tzinfo(cfg, hives): if "system" in hives.keys(): if "cset" not in cfg.keys(): cfg["cset"] = common.get_control_set(hives['system']) rows = [[ "Timezone name", "Active bias", "Bias", "Standard bias", "Daylight bias" ]] pairs = {} for value in common.safe_open( hives["system"], "ControlSet00%s\Control\TimeZoneInformation" % cfg['cset']).values(): if value.name() == "TimeZoneKeyName": pairs["Timezone name"] = value.value() if value.name() == "ActiveTimeBias": pairs["Active bias"] = utc_bias(value.value()) if value.name() == "Bias": pairs["Bias"] = utc_bias(value.value()) if value.name() == "StandardBias": pairs["Standard bias"] = utc_bias(value.value()) if value.name() == "DaylightBias": pairs["Daylight bias"] = utc_bias(value.value()) output.dict_to_arr(rows, pairs) output.write_out(cfg, rows, "Timezone")
def samusers(cfg, hives): rows = [["RID", "Name", "Flags", "Login Count", "Last Login", "Failed Logins", "Last Failed Login", "Password Created", "Password Expires", "Full Name", "Comment", "Home Dir", "Logon Script", "Profile Path", "Workstations"]] if "sam" in hives.keys(): for usr in common.safe_open(hives["sam"], "SAM\Domains\Account\Users\Names").subkeys(): vals = {} vals["Name"] = usr.name() vals["RID"] = usr.value("(default)").value_type() rid = hives["sam"].open("SAM\Domains\Account\Users\\0000%04X"%vals["RID"]) f = rid.value('F').value() v = rid.value('V').value() try: vals["Last Login"] = common.decode_filetime(f[8:16]) except: pass try: vals["Password Created"] = common.decode_filetime(f[24:32]) except: pass try: vals["Password Expires"] = common.decode_filetime(f[32:40]) except: pass try: vals["Last Failed Login"] = common.decode_filetime(f[40:48]) except: pass # http://www.pigstye.net/forensics/password.html try: vals["Flags"] = [] acb = struct.unpack("H", f[56:58])[0] if acb&0x001: vals["Flags"].append("DISABLED") if acb&0x002: vals["Flags"].append("HOMEDIRREQ") if acb&0x004: vals["Flags"].append("PWNOTREQ") if acb&0x008: vals["Flags"].append("TEMPDUP") #~ if acb&0x010: #~ vals["Flags"].append("NORMAL") if acb&0x020: vals["Flags"].append("MNS") if acb&0x040: vals["Flags"].append("DOMTRUST") if acb&0x080: vals["Flags"].append("WSTRUST") if acb&0x100: vals["Flags"].append("SRVTRUST") if acb&0x200: vals["Flags"].append("PWNOEXP") if acb&0x400: vals["Flags"].append("AUTOLOCK") vals["Flags"] = ", ".join(vals["Flags"]) except: pass counts = struct.unpack("HH",f[64:68]) vals["Failed Logins"] = counts[0] vals["Login Count"] = counts[1] try: username_o = struct.unpack('<L', v[12:16])[0]+0xcc username_l = struct.unpack('<L', v[16:20])[0] fullname_o = struct.unpack('<L', v[24:28])[0]+0xcc fullname_l = struct.unpack('<L', v[28:32])[0] vals["Full Name"] = v[fullname_o:fullname_o+fullname_l].replace('\0','') comment_o = struct.unpack('<L', v[36:40])[0]+0xcc comment_l = struct.unpack('<L', v[40:44])[0] vals["Comment"] = v[comment_o:comment_o+comment_l].replace('\0','') homedrive_o = struct.unpack('<L', v[84:88])[0]+0xcc homedrive_l = struct.unpack('<L', v[88:92])[0] vals["Home Drive"] = v[homedrive_o:homedrive_o+homedrive_l].replace('\0','') homedir_o = struct.unpack('<L', v[72:76])[0]+0xcc homedir_l = struct.unpack('<L', v[76:80])[0] vals["Home Dir"] = v[homedir_o:homedir_o+homedir_l].replace('\0','') vals["Home Dir"] = "%s%s"%(vals["Home Drive"], vals["Home Dir"]) logonscript_o = struct.unpack('<L', v[96:100])[0]+0xcc logonscript_l = struct.unpack('<L', v[100:104])[0] vals["Logon Script"] = v[logonscript_o:logonscript_o+logonscript_l].replace('\0','') profilepath_o = struct.unpack('<L', v[108:112])[0]+0xcc profilepath_l = struct.unpack('<L', v[112:116])[0] vals["Profile Path"] = v[profilepath_o:profilepath_o+profilepath_l].replace('\0','') workstations_o = struct.unpack('<L', v[120:124])[0]+0xcc workstations_l = struct.unpack('<L', v[124:128])[0] vals["Workstations"] = v[workstations_o:workstations_o+workstations_l].replace('\0','') except: pass output.dict_to_arr(rows, vals) rows = output.sort_by_col(rows,"RID") output.write_out(cfg, rows, "Local Users", 1)
def usb(cfg, hives, user_hives): # http://www.forensicmag.com/article/2012/06/windows-7-registry-forensics-part-5 # http://www.forensicmag.com/article/2012/08/windows-7-registry-forensics-part-6 # http://web.archive.org/web/20131227051020/http://studioshorts.com/blog/2012/10/windows-8-device-property-ids-device-enumeration-pnpobject/ if "system" in hives.keys(): if "cset" not in cfg.keys(): cfg['cset'] = common.get_control_set(hives['system']) usbstor = hives["system"].open("ControlSet00%s\Enum\USBSTOR" % cfg["cset"]) rows = [[ "Class", "Friendly Name", "Serial No.", "Vendor Name", "UID", "Volume GUID", "Drive Letter", "First Attached", "Last Attached", "Last mounted (by user)" ]] for vendor in usbstor.subkeys(): for device in vendor.subkeys(): vals = {} vals["Vendor Name"] = vendor.name() vals["UID"] = device.name() vals["ContID"] = device.value("ContainerID").value() vals["Serial No."] = '&'.join(device.name().split('&')[:-1]) if vals["Serial No."][1] == '&': vals["Serial No."] = "N/A (%s)" % vals["Serial No."] # Check properties for first attached time try: # Win ? - 7 fi_key = hives["system"].open( "%s\Properties\{83da6326-97a6-4088-9453-a1923f573b29}\\00000065\\00000000" % (common.norm_path(device.path()))) vals["First Attached"] = common.decode_filetime( fi_key.value("Data").value()) except: # win 8 - ? fi_key = hives["system"].open( "%s\Properties\{83da6326-97a6-4088-9453-a1923f573b29}\\0065" % (common.norm_path(device.path()))) vals["First Attached"] = str( fi_key.value("(default)").value().strftime( '%a %b %d %Y %H:%M:%S UTC')) # Check DeviceClasses for last attached time for dev in hives["system"].open( "ControlSet00%s\Control\DeviceClasses\{53f56307-b6bf-11d0-94f2-00a0c91efb8b}" % cfg["cset"]).subkeys(): if vals["Vendor Name"] in dev.name(): vals["Last Attached"] = dev.timestamp().strftime( '%a %b %d %Y %H:%M:%S UTC') # Parse MountedDevices for point in hives["system"].open("MountedDevices").values(): mduid = "" # Is there a better soln to unpack ASCII? for char in struct.unpack( "<%dH" % (len(point.value()) / 2), point.value()): if char > 32 and char < 127: mduid = "%s%s" % (mduid, chr(char)) # If UID in MountedDevices value, find volume GUID or mount point in name if vals["UID"] in mduid: if point.name()[-1] == '}': vals["Volume GUID"] = point.name()[-38:] elif point.name()[-1] == ':': vals["Drive Letter"] = point.name()[-2:] # Search NTUSER.dat files for most recent mount if "Volume GUID" in vals.keys(): last_time = 0 for user, uhive in user_hives.items(): uguid = common.safe_open( uhive, "Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2\\%s" % vals["Volume GUID"]) # Hives that never mounted this drive will fail if uguid.name(): utime = uguid.timestamp() if not last_time: last_time = utime last_user = user elif last_time < utime: last_time = utime last_user = user if last_time: vals["Last mounted (by user)"] = "%s (%s)" % ( last_time.strftime('%a %b %d %Y %H:%M:%S UTC'), last_user) for value in device.values(): if value.name() == "FriendlyName": vals["Friendly Name"] = value.value() if value.name() == "Class": # Old vals["Class"] = value.value() if value.name() == "ClassGUID": # New cguid = common.safe_open( hives["system"], "ControlSet00%s\Control\Class\%s" % (cfg["cset"], common.multi_string(value))) for valu in cguid.values(): if valu.name() == "Class": vals["Class"] = valu.value() output.dict_to_arr(rows, vals) rows = output.sort_by_col(rows, "Vendor Name") output.write_out(cfg, rows, "USB", 1)
def services(cfg, hives): rows = [["Name", "Type", "Start", "Error Control", "Group", "Service Dll", "Display Name", "Image Path"]] if "system" in hives.keys(): if "cset" not in cfg.keys(): cfg["cset"] = common.get_control_set(hives['system']) for svc in common.safe_open(hives["system"], "ControlSet00%s\Services"%cfg['cset']).subkeys(): vals = {} keypath = '\\'.join(svc.path().split('\\')[1:]) vals["Name"] = svc.name() # http://windowsitpro.com/windows-server/jsi-tip-0324-registry-entries-services # http://nt4ref.zcm.com.au/mansd.htm vals["Type"] = common.safe_open(hives["system"], keypath, "Type").value() if vals["Type"] != '': if vals["Type"] == 0x1: vals["Type"] = "Kernel-mode Driver" elif vals["Type"] == 0x2: vals["Type"] = "Filesystem Driver" elif vals["Type"] == 0x4: vals["Type"] = "Argument Group" elif vals["Type"] == 0x10: vals["Type"] = "Win32 Dedicated" elif vals["Type"] == 0x20: vals["Type"] = "Win32 Shared" elif vals["Type"] == 0x110: vals["Type"] = "Win32 Dedicated Interactive" elif vals["Type"] == 0x120: vals["Type"] = "Win32 Shared Interactive" else: vals["Type"] = "Unknown: 0x%x"%int(vals["Type"]) vals["Start"] = common.safe_open(hives["system"], keypath, "Start").value() if vals["Start"] != '': if vals["Start"] == 0x0: vals["Start"] = "Boot" elif vals["Start"] == 0x1: vals["Start"] = "System" elif vals["Start"] == 0x2: vals["Start"] = "Automatic" elif vals["Start"] == 0x3: vals["Start"] = "Manual" elif vals["Start"] == 0x4: vals["Start"] = "Disabled" else: vals["Start"] = "Unknown: 0x%x"%int(vals["Start"]) vals["Error Control"] = common.safe_open(hives["system"], keypath, "ErrorControl").value() if vals["Error Control"] != '': if vals["Error Control"] == 0x0: vals ["Error Control"] = "Ignore" elif vals["Error Control"] == 0x1: vals ["Error Control"] = "Normal" elif vals["Error Control"] == 0x2: vals ["Error Control"] = "Severe" elif vals["Error Control"] == 0x3: vals ["Error Control"] = "Critical" else: vals["Error Control"] = "Unknown: 0x%x"%int(vals["Error Control"]) vals["Image Path"] = common.multi_string(common.safe_open(hives["system"], keypath, "ImagePath")) vals["Group"] = common.safe_open(hives["system"], keypath, "Group").value() vals["Display Name"] = common.safe_open(hives["system"], keypath, "DisplayName").value() vals["Service Dll"] = common.safe_open(hives["system"], "%s\Parameters"%(keypath), "ServiceDll").value() output.dict_to_arr(rows, vals) output.write_out(cfg, rows, "Services", 1)
def nicinfo(cfg, hives): if "system" in hives.keys(): if "cset" not in cfg.keys(): cfg["cset"] = common.get_control_set(hives['system']) rows = [[ "Name", "Description", "DHCP", "IP Address", "Mask", "Nameserver", "Default Gateway", "Gateway MAC", "Domain", "DHCP Server", "Lease Obtained", "Lease Ends" ]] for i, subkey in enumerate( common.safe_open( hives['system'], "ControlSet00%s\\Services\\Tcpip\\Parameters\\Interfaces" % cfg['cset']).subkeys()): nic = {} # Get connection name conn_key = common.find_keys_name( hives['system'].open("ControlSet00%s\\Control\\Network" % cfg['cset']), subkey.name(), 2) if conn_key: conn_val = common.safe_open(hives['system'], "%s\\Connection" % conn_key[0], "Name").value() nic['Name'] = conn_val # Get description if "software" in hives.keys(): nic_key = common.find_keys_value( hives['software'].open( "Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"), subkey.name(), 1) if nic_key: nic['Description'] = common.safe_open( hives["software"], nic_key[0], "Description").value() # Get everything else for value in subkey.values(): if value.name() == "EnableDHCP": if value.value(): nic["DHCP"] = "Yes" else: nic["DHCP"] = "No" elif value.name() == "DhcpServer": nic["DHCP Server"] = common.multi_string(value) elif value.name() == "GatewayHardware" or value.name( ) == "DhcpGatewayHardware": nic["Gateway MAC"] = ':'.join([ octal.encode('hex') for octal in struct.unpack("<14c", value.value())[-6:] ]) elif value.name() == "NameSever" or value.name( ) == "DhcpNameServer": nic["Nameserver"] = value.value() elif value.name() == "IPAddress" or value.name( ) == "DhcpIPAddress": nic["IP Address"] = common.multi_string(value) elif value.name() == "SubnetMask" or value.name( ) == "DhcpSubnetMask": nic["Mask"] = common.multi_string(value) elif value.name() == "DefaultGateway" or value.name( ) == "DhcpDefaultGateway": nic["Default Gateway"] = common.multi_string(value) elif value.name() == "Domain" or value.name() == "DhcpDomain": nic["Domain"] = value.value() elif value.name() == "LeaseObtainedTime": if value.value(): nic["Lease Obtained"] = common.decode_epoch( value.value()) elif value.name() == "LeaseTerminatesTime": if value.value(): nic["Lease Ends"] = common.decode_epoch(value.value()) output.dict_to_arr(rows, nic) output.write_out(cfg, rows, "TCP/IP", 1)