O'Reilly Hacks
oreilly.comO'Reilly NetworkSafari BookshelfConferences Sign In/My Account | View Cart   
Book List Learning Lab PDFs O'Reilly Gear Newsletters Press Room Jobs  


 
Buy the book!
Windows Server Hacks
By Mitch Tulloch
March 2004
More Info

HACK
#73
Find All Computers that Are Running a Service
Use this script to find rogue web servers, misconfigured clients, and other potentially insecure systems on your network
The Code
[Discuss (0) | Link to this hack]

The Code

Type the following script into Notepad (with Word Wrap disabled) and save as FindNTService.vbs. Alternatively, since this is a long one, you're probably better off downloading the source from http://www.oreilly.com/catalog/winsvrhks/.

' Dennis Abbott - speckled_trout@hotmail.com
' you need to register the Scripting System Runtime from www.netal.com in
' your System32 directory on the machine you are running this script from 
' first.
' You also need the utility psservice.exe from www.sysinternals.com in 
' the same directory as this script and you need a text file with the
' subnets listed with a linefeed after each subnet.
'
' example of subnet listing
'
' 192.168.0.0
' 192.168.1.0
' 34.54.78.0
'
' You can view the script in action by opening the log file with a 
' realtime log file viewer such as SMS Trace from Mircosoft.
'
'On Error Resume Next
Option Explicit
Dim Title                  'used for dialog boxes as well as the log file name
Dim PathToScript  'path to the directory that the script is running from
Dim PathToLogFile  'full path including filename of the log file
Dim WshShell  'shell object
Dim WshNet                  'network object
Dim WshFso  'file system object
Dim WshSysEnv                  'environment variable object
Dim ScriptNet                  'System Scripting Runtime object from www.netal.com
Dim ComSpec          'path to cmd.exe
Dim DataFile  'file containing machine names
Dim LogFile          'log file for stats
Dim CompName          'name of the current remote target computer
Dim User                  'user logged on to remote computer
Dim Domain  'domain that the remote computer is joined to
Dim IP  'IP address of remote computer 
Dim CurLine  'used when parsing text files
Dim NbtFile  'file parsed for NetBIOS information
Dim SubnetFileName          'file containing subnets to be searched
Dim I          'counter
Dim SysFolder  'the system folder
Dim TimeOut  'timeout in milliseconds for ping
Dim Go          'gives user option to quit
Dim ServiceToCheck 'name of the service to look for--NOT THE DISPLAY NAME
Dim EditSubnets  'give user option of editing subnet file
Dim File  'File object
Dim Subnet  'current subnet being searched
Dim Service  'Status of the service
Dim ServFile  'file parsed for the service information

Set WshShell = CreateObject("WScript.Shell")
Set WshFso = CreateObject("Scripting.FileSystemObject")
Set WshNet = CreateObject("WScript.Network")
Set ScriptNet = CreateObject("SScripting.IPNetwork")

SysFolder = WshFso.GetSpecialFolder(1)
PathToScript = Left(WScript.ScriptFullName, & _
(Len(WScript.ScriptFullName) - (Len(WScript.ScriptName) + 1)))
Title = "FindNTService"
Set WshSysEnv = WshShell.Environment("SYSTEM")
ComSpec = WshSysEnv("COMSPEC")
Timeout = 125

'collect input
Go = MsgBox("This utility will search the network by subnet to find " & _
"all machines running a particular service." & vbcrlf & _
"To do this you must supply a text file with the subnets and the name of " & _
"the service." & vbcrlf & vbcrlf & "Do you wish to continue?",vbyesno,Title)
Select Case Go
        Case VbYes
        Case VbNo Wscript.Quit(0)
End Select
If WshFso.FileExists(PathToScript & "\psservice.exe") <> True Then
        MsgBox "The PSSERVICE utility does not exist....GOODBYE" & vbcrlf & _
 "You can get PSSERVICE from www.sysinternals.com",vbok + vbcritical, _
 Title Wscript.Quit(0)
End If
If WshFso.FileExists(SysFolder & "\sscrrun.dll") <> True Then
        MsgBox "The sscrrun.dll does not exist....GOODBYE" & vbcrlf & "You can 
get sscrrun.dll from www.netal.com",vbok + vbcritical, Title
        Wscript.Quit(0)
End If
ServiceToCheck = InputBox("enter the service name(not display name) that " & _
"you want to search for.",Title,"w3svc")
If ServiceToCheck = "" Then
        MsgBox "you did not enter a service name....GOODBYE",vbok + vbcritical, Title
        Wscript.Quit(0)
End If
SubnetFileName = InputBox("enter the path to the file that contains " & _
"the subnets.",Title,PathToScript & "\subnets.txt")
If WshFso.FileExists(SubnetFileName) <> True Then
 MsgBox "The subnet file does not exist....GOODBYE", _
 vbok + vbcritical, Title
        Wscript.Quit(0)
End If
EditSubnets = MsgBox("Do you want to edit the subnets file?",vbyesno,Title)
Select Case EditSubnets
        Case vbyes WshShell.Run "notepad " & SubnetFileName,1,True
        Case vbno
End Select

PathToLogFile = PathToScript & "\" & Title & "_" & Month(Now) & "_" 
&  Day(Now) & "_" & Year(Now) & "-" & Hour(Now) & "_" &  
Minute(Now) & ".log"
Set LogFile = WshFso.CreateTextFile(PathToLogFile)
Set File = WshFso.GetFile(SubnetFileName)
Set DataFile = File.OpenAsTextStream(1,0)
LogFile.WriteLine "IPaddress" & vbtab & "ComputerName" & vbtab & _
"LoginName" & vbtab & "Domain" & vbtab & "Status"
Do  While Not DataFile.AtEndOfStream
        Subnet = DataFile.ReadLine
        LogFile.WriteLine subnet & vbtab & vbtab & vbtab & vbtab & _
 "beginning subnet " & Now
        Discover(subnet)

Loop
MsgBox Title & " script is done.  The log file is located here." & _
vbcrlf & PathToLogFile

Function Discover(boundary)
        Subnet = Left(boundary,InstrRev(boundary,"."))
        For i = 1 to 254
                IP = subnet & i
                CompName = Null
                User = Null
                Domain = Null
                Curline = Null
                Service = Null
                If ScriptNet.Ping(ip,,,Timeout) <> 0 Then
                        LogFile.WriteLine IP & vbtab & vbtab & vbtab & vbtab _
          & "UnPingableClient"
                Else
                        CompName = ScriptNet.DNSlookup(IP)
                        If InStr(CompName,".") <> 0 Then
                                CompName = Left(CompName,InStr(CompName,".")-1)
                        End If
                        Call GetNBTstat(IP,User,Domain)
                               Call GetService(IP, Service)
                        Call WriteToLog(IP,CompName,User,Domain,Service)
                End If
        Next
End Function

Function GetNBTstat(IP,User,Domain)        
        WshShell.Run ComSpec & " /c nbtstat -a " & IP & " >" & PathToScript & _
 "\nbt.txt",6,True 
        Set NbtFile = WshFso.OpenTextFile(PathToScript & "\nbt.txt", 1, True)
        Do While NbtFile.AtEndOfStream <> True
                CurLine = NbtFile.ReadLine
                If InStr(CurLine,"---") <> 0 Then
                        CurLine = NbtFile.ReadLine
                        CompName = Trim(Left(CurLine,InStr(CurLine,"<")-1))
                End If
                If InStr(CurLine,"<03>") <> 0 Then
                    If Trim(Left(CurLine,InStr(CurLine,"<03>")-1)) <> _
          UCase(CompName) and Trim(Left(CurLine,InStr(CurLine,"<03>")-1)) <> _
          UCase(CompName) & "$" Then
                                User = Trim(Left(CurLine,InStr(CurLine,"<03>")-1))
                        End If
                End If
                If InStr(CurLine,"<1E>") <> 0 Then
                        If Trim(Left(CurLine,InStr(CurLine,"<1E>")-1)) <> _
          UCase(CompName) and Trim(Left(CurLine,InStr(CurLine,"<1E>")-1)) <> _ 
          UCase(CompName) & "$" Then
                                Domain = Trim(Left(CurLine,InStr(CurLine,"<1E>")-1))
                        End If
                End If
        Loop
        NbtFile.Close
End Function

Function GetService(IP,Service)
        If CompName <> "" and User <> "" or Domain <> "" Then
                WshShell.Run ComSpec & " /c " & PathToScript & "\psservice  \\" _
      & IP & " query " & Chr(34) & ServiceToCheck & Chr(34) & " >" _
      & PathToScript & "\service.txt",6,True
                Set ServFile = WshFso.OpenTextFile(PathToScript _
      & "\service.txt", 1, True)
                Do While ServFile.AtEndOfStream <> True
                        CurLine = ServFile.ReadLine
                        If InStr(CurLine,"STATE") <> 0 Then
                                Service = Trim(Right(CurLine,InStr(CurLine," ")-1))
                        End If
                        If InStr(CurLine,"RPC") <> 0 Then
                                Service = CurLine
                        End If
                        If InStr(CurLine,"Access") <> 0 Then
                                Service = CurLine
                        End If
                        If InStr(CurLine,"function") <> 0 Then
                                Service = CurLine
                        End If
                        If InStr(CurLine,"Unable") <> 0 Then
                                Service = CurLine
                        End If
                Loop
                If InStr(Service,vbcr) <> 0 Then
                        Service = Left(Service,InStr(Service,vbcr)-1)
                End If
        End If
End Function

Function WriteToLog(IP,CompName,User,Domain,Service)
        If IP <> "" Then
                LogFile.Write IP
        End If
        LogFile.Write vbtab
        If CompName <> "" Then
                LogFile.Write CompName
        End If
        LogFile.Write vbtab
        If User <> "" Then
                LogFile.Write User
        End If
        LogFile.Write vbtab
        If Domain <> "" Then
                LogFile.Write Domain
        End If
        LogFile.Write vbtab
        If Service <> "" Then
                LogFile.Write Service
        End If
        LogFile.WriteLine
End Function


O'Reilly Home | Privacy Policy

© 2007 O'Reilly Media, Inc.
Website: | Customer Service: | Book issues:

All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.