This post explains a trick that I have been using for a few years to discover application endpoints on Windows quickly.
It's a simple trick:
Code is at:
Update May 2020: If you are doing this in a Hyper-V guest virtual machine,
it will not work. The default DNS server for a Hyper-V guest is the server. And
it does not populate the local DNS cache (I do not know the reason). The fix is
to manually configure a DNS server (e.g., 8.8.8.8
) in the guest's network
adapter.
Results in a Hyper-V guest with the default DNS server
Discovering application endpoints is one of the starting steps in thick client proxying. I have written about it so many times that I will just make a list here. Off the top of my head I can think of:
TCP/UDP Connect/Send/Receive
.You can interact with the DNS cache in different ways. Most common ways are:
ipconfig /displaydns
ipconfig /flushdns
We will use PowerShell because the output of commands are objects. We can format the output at-will.
The first iteration of our commands is completely manual. We copy/paste the following command into the PowerShell console (or ISE during development):
Clear-DnsClientCache
ping google.com
$dns1 = Get-DnsClientCache
$dns2 = Get-DnsClientCache
Compare-Object -ReferenceObject $dns2 -DifferenceObject $dns1
Results of PasteOps
We have successfully discovered that the thick client (browser) has contacted
example.net
.
In a real scenario, we want to clear the cache just right before starting the
application. In our PasteOps, $dns1
might be empty if we call it just
right after clearing the cache and that will return an error when doing the
compare.
Error when comparing with a null result
Looking at the Get-DnsClientCache documentation, we can see it returns MSFT_DnsClientCache:
class MSFT_DNSClientCache : CIM_ManagedElement
{
string InstanceId;
string Caption;
string Description;
string ElementName;
string Entry;
string Name;
uint16 Type;
uint32 TimeToLive;
uint16 DataLength;
uint8 Section;
string Data;
uint32 Status;
};
As we will see later, not all fields are populated for every record.
Table output in PowerShell is usually truncated but we can format the output as objects unlike Bash1.
Using Format Commands to Change Output View is a good introduction to different output formats.
We can use Format-Table
to get the output in a table and see truncated
results (it's fixable):
Get-DnsClientCache | Format-Table
Truncated results
We probably don't need to see all the fields, let's modify our command:
Get-DnsClientCache | Format-Table -Property Entry,RecordName,Data
RecordName does not exist
Wait, what? RecordName
column is in the original output but does not exist
here. You might have also observed that you could use tab-complete for
the other two field names (e.g., -Pro [tab] Ent [tab]
to get
-Property Entry
) but not RecordName
.
We have to use field names based on the return value which is
MSFT_DNSClientCache
.
Get-DnsClientCache | Format-Table -Property Entry,Name,Type,Data
Columns based on object fields
Some field values like Type
are different from the original command
output. Objects have some default printing formats. See the following link for
a similar command:
We have enough to write a PowerShell script to do the job. We can get the output of both commands and then remove the duplicates with Compare-Object.
The output of Compare-Object
is a PSCustomObject
that wraps the original
object with a slide indicator.
$ Compare-Object -ReferenceObject $dns2 -DifferenceObject $dns1
InputObject SideIndicator
----------- -------------
MSFT_DNSClientCache (Entry = "example.net", Name = "example.net") <=
The -PassThru
switch will spit out the unwrapped objects.
$ Compare-Object -ReferenceObject $dns2 -DifferenceObject $dns1 -PassThru
Entry RecordName Record Status Section TimeTo Data Data
Type Live Length
----- ---------- ------ ------ ------- ------ ------ ----
example.net example.net A Success Answer 77102 4 93.184.216.34
Wrapped objects are not useful here. Let's add -PassThru
to our PasteOps.
|
|
We can directly work on objects and format the output in different ways or export them with something like Export-Csv for later use.
The next step after PasteOps is combining all these commands into a PowerShell script.
|
|
If we run the script and open up Google Chrome when prompted, we can see:
Endpoints used by Google Chrome
We can pass the command output (which is a list of objects) to pipes and manipulate it:
Manipulating command output
Any connection method that does not end up in the DNS cache is not discoverable by this method. This usually happens when the application:
Full automation might be an issue. It's definitely feasible to integrate the script into an automation framework and harvest the endpoints. It will miss endpoints unless you know that your framework can call all application functionality.