Here was a fun little exercise… in attempting to impose more restrictive firewall rules on our central Windows server subnets, I wanted to enumerate all of the servers which require “public” CIFS protocol access. Naturally we want to take a programmatic approach to save time.
Here is what I came up with… it is not the work of a networking genius, but it worked:
- GnuWin32 “cut.exe” defined in your %PATH%, GnuWin32 XARGS (optional)
- Remote registry rights on all systems to be queried
- A windows CMD console, ’cause I am lame and can’t take the time to learn PowerShell.
First, we want to discover all of the servers in a network range that have valid registered DNS names:
FOR /L %d in ([starting octet],1,254) DO nslookup [network].%d | find “Name:” | cut.exe -c 10-100 >> networkhosts.txt
This command will use the FOR command to run “nslookup” on the IP address “[network].%D” several times, starting with [starting octet], incrementing by one, then terminating at “254”. The output of the lookup is sent to the windows (not GnuWin32) “find” command, which will locate the output line containing “Name:” (this will be the actual DNS name of the system). The output line is trimmed of all information except the DNS name using “cut” (DNS names start at the 10th character of the NSLookup output). Output is sent to a file for later use.
Next we test to see if the discovered host names are available. By doing so, we prevent wasting time on operations against servers that are not available:
FOR /F %d in (networkhosts.txt) do ping -n 1 %d && echo %d >> availablehosts.txt
We use FOR again to ping all of the host in the file that we create above. If the ping succeeds (meaning the host is there), repeat the host name with an “echo”, and send that output to a file.
Now we actually need to see if the hosts have any publicly available network shares… One approach would be use the the old-school “net view” command to display visible shares on the remote hosts:
FOR /F %S in (avaiablehosts.txt) DO net view \%S >> VizShares.txt
This is useful, although it will not disclose “hidden shares”. To get around the “hidden” shares problem, we can perform a remote registry query to see all shares (other than the defaults) which are made available at the startup of the “server” service. These shares are published in:
We will use “reg.exe” and another FOR loop to see what hidden shares exist:
FOR /F %H in (availablehosts.txt) DO echo %H >> hiddenhosts.txt & reg query \%HHKEY_LOCAL_MACHINESYSTEMCurrentControlSetServiceslanmanserverShares /v /f *$ | find “$” | cut.exe -d$ -f1 >> hiddenhosts.txt
We start this loop with an ECHO command so that we can insert the name of the host being investigated into our output file. The /v flag in REG.exe returns only values under the selected key, and /f *$ filters the output to lines containing only share names ending in “$” (in other words, hidden shares). Output is passed though “find” to filter out all but the lines that have the actual share name in them. Output is then sent through “cut” to trim everything but the actual share name from output, and then send the trimmed output to our final file for human analysis.
An industrious admin would chain these commands in a single task. However, I wanted to check each output file for validity before proceeding… we have some old DNS entries that were making trouble with the remote registry commands. If I had not removed them, the script could have taken many hours to complete. If you want to do this, the GnuWin32 tool “xargs” will be invaluable, as it will allow you to pass standard output into commands that do not support standard input, such as “net view”, and “reg.exe”. For example, we could nest the second “FOR” loop above into the first, and then pipe the output to XARGS NET VIEW”
| Xargs.exe net view