We would like to welcome a new table to the Windows Defender ATP Advanced hunting schema: MachineNetworkInfo.
For each network adapter seen on onboarded machines, this table provides the configured IP addresses, gateways, DNS servers, and more.
Sounds similar to ipconfig? Well, this is actually the intention. The Windows Defender ATP sensor tracks this network configuration information on onboarded machines every 15 minutes. With this comprehensive and up-to-date view of the network status of your machines, you can just imagine all the cool stuff you can do and how this data can enrich your hunting activities.
When you’re ready, let’s explore some simple examples of how you can use this new set of data.
By getting all the IP addresses used by a specific machine at a given point in time, you can pivot your investigations to firewall, IDS or network logs, which record events by IP address. This query returns all IP addresses reported from a specific computer within a 30-minute period:
MachineNetworkInfo // Query for reports sent +-15 minutes around the time we are interested in | where EventTime between ((datetime(2018-08-05T09:51)-15m) .. 30m) // Filter by machine name and select only adapters that are enabled and connected | where ComputerName == "somecomputer.corp.contoso.com" and NetworkAdapterStatus == "Up" // IPAddresses contains a list of the IP addresses configured on the network adapter, their subnets, and more. // Here we expand the list so that each value gets a separate row. All the other columns in the row, such as ComputerName, are duplicated. | mvexpand parse_json(IPAddresses) | project IPAddress=IPAddresses.IPAddress, AddressType=IPAddresses.AddressType, NetworkAdapterType, TunnelType, MacAddress
The results below show that the machine has two connected network adapters: a Wi-Fi adapter and a VPN tunnel. The Wi-Fi adapter has both an IPv4 address and an IPv6 address in this case. Note that the MacAddress field is in a different format than what you see in ipconfig, as it doesn’t contain colons (:).
After you identify a compromised machine, you might wonder where the actual compromise occurred, particularly if the machine is mobile.
Did the compromise happen in your headquarters or in some remote branch? Did the attack go through your perimeter defenses or was the machine infected off-premise? Was the compromise done at the employee’s home, at a partner network, or when the employee connected to some airport Wi-Fi? Was there perhaps an unfamiliar network configuration set on your corpnet-based servers and PCs?
This table includes multiple columns that could help you answer these questions. The simplest approach could be to check the ConnectedNetworks column, where you can see the names and descriptions of connected networks, that are typically provided by DHCP servers.
However, this may not give you the info you need. Using the following query you can identify the relevant network segment in your organization by examining the configured DHCP servers, DNS servers, and default gateways. If you still don’t have an answer, search for other machines seen with those settings, and then identify what is common between the machines.
MachineNetworkInfo | where EventTime between ((datetime(2018-08-05T09:51)-15m) .. 30m)
and MachineId == "c0bfefec0bfefec0bfefec0bfefec0bfefecafe"
and NetworkAdapterStatus == "Up"
| project ConnectedNetworks, DnsAddresses, DefaultGateways, IPv4Dhcp, IPv6Dhcp, NetworkAdapterType | distinct *
You might want to pivot in another direction by starting with network setting information, specifically the IP address, to identify the machine involved in suspicious activity. For example, your IDS alerts you about some suspicious activity originating from an internal IP address, and you want to identify the machine using that IP address during the time of the reported activity.
To do this, all you need is a very simple query:
MachineNetworkInfo | where EventTime between ((datetime(2018-08-05T09:51)-15m) .. 30m) and IPAddresses contains '"192.168.1.5"' and NetworkAdapterStatus == "Up" | project ComputerName, EventTime, IPAddresses
Note that we wrap the IP address in quotes in our filter, to avoid matching events with other IP addresses that have the same initial or trailing as the address we are looking for.
It also helps to include additional filters in the query that identify the network, avoiding matching machines with the same IP address but on a different network. To do this, use the description provided in the ConnectedNetworks column described earlier or use the corresponding DHCP server address.
Let’s take the simple query we had in scenario #3 and amp it up. The first thing we do is add parameters to our query so that it’s easy for different people in your team to use it over long periods of time. With every run, they can use different parameters. The second change is that in addition to getting the machine name, we also query for the users that were logged on to that machine during the specified time period.
let pivotTime = datetime(2018-08-05 09:51:00); let ipAddress = "192.168.1.5"; let matchingMachines = MachineNetworkInfo
| where EventTime between ((pivotTime-15m) ..30m)
and IPAddresses contains strcat("\"", ipAddress, "\"")
and NetworkAdapterStatus == "Up" | project ComputerName, EventTime, IPAddresses,
TimeDifference=abs(EventTime-pivotTime); MachineInfo | where EventTime between ((pivotTime-15m) ..30m) | project ComputerName, EventTime, LoggedOnUsers | join kind=inner (matchingMachines) on ComputerName, EventTime | project EventTime, ComputerName, LoggedOnUsers, TimeDifference, IPAddresses // In case multiple machines have reported from that IP address arround that time, start with the ones reporting closest to pivotTime | sort by TimeDifference asc
The MachineNetworkInfo table includes the IP addresses configured for use by a machine. It is common, however, for a machine to access the internet through a different IP address by way of a proxy or a NAT.
In any of the scenarios we’ve described, you might actually want to query for this public IP address, instead of the local IP address assigned to the machine itself. This can be necessary if a cloud service has notified you of suspicious access from some IP address, or if your national CERT has identified some suspicious activity originating from your network. This could also be useful if you want to do a reverse IP lookup for a certain machine, identifying its geo-location or the network from which it is reporting.
Simply query for the PublicIP column in the MachineInfo table (note the difference between MachineNetworkInfo and MachineInfo). This column includes the IP address that is communicating with Windows Defender ATP cloud when the sensor sends data.
MachineInfo | where EventTime between ((datetime(2018-07-15T19:51)-15m) .. 30m) and MachineId == "c0bfefec0bfefec0bfefec0bfefec0bfefecafe" | project PublicIP, LoggedOnUsers, EventTime
If you prefer to run this query as part of the above queries, try to union the results together.
Our GitHub repository includes related sample queries such as Machine info from IP address and Network info of machine. If you have an interesting query to share, the GitHub repository for Advanced hunting queries is your friend. :smiling_face_with_smiling_eyes:
To go back to the basics of advanced hunting, take a look at this documentation or at our recent tutorial. To learn more about the Kusto Query Language, read the documentation or watch this new Pluralsight training. For more interesting advanced hunting examples, check out the newest hunting tip of the month posts on browser downloads or on PowerShell commands.
If you still haven’t experienced the powerful breach-hunting features of Windows Defender ATP, get your free trial now.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.