Hack 73 Find All Computers that Are Running a Service

 < Day Day Up > 

figs/moderate.gif figs/hack73.gif

Use this script to find rogue web servers, misconfigured clients , and other potentially insecure systems on your network .

Querying the status of a service across multiple computers can be an extremely useful tool. You can check for the SMS client service, antivirus services, or even viruses/Trojans that run as a service. Under most interfaces, such as WMI or ADSI, you need to check the status of services with an account that has administrator rights on the machine you are targeting. It turns out that in many organizations there are quite a few PCs on the network that have done a phenomenal job of removing most of the IT department's administrator rights. These unmanaged PCs can be a real risk at times.

One day, I noticed that when you query a remote box with the Windows 2000 services snap-in for the MMC, you do not need administrator rights to check on the services that reside on remote boxes. You simply need an account in a trusted domain with simple user -level rights. On further investigation, it was revealed that what in fact was going on was a direct query to the Service Control Manager (SCM), as opposed to some API call through WMI or ADSI. One of the best free third-party tools that also queries the SCM is Psservice from Sysinternals (http://www.sysinternals.com). Although this is strictly a command-line utility, we can tweak it with some parameters and do some fancy parsing to make efficient use of it in a script.

First, the script will search IP addresses by subnet, using a ping response, and find the Windows-based machines by parsing out a NetBIOS call. Then, it will determine if the machine is running a particular service, by querying it with Psservice, and log the results in tab-delimited format. This will retrieve the following data in the log file: IP address, computer name, currently logged-on user, domain or workgroup to which the machine is joined, and the status of the service. The IP address is included even if the node is not pingable and can be treated as a key in most cases. The computer name is resolved with a DNS lookup on the IP address and then, if a NetBIOS name is found, it is switched to that name. Note that this could be blank if both methods fail. The currently logged-on user field should display data if the machine is NetBIOS-compatible and someone is currently logged on. However, if no one is logged on, it will be blank. Note that this logon name could be a domain account or a local account; there is no way to tell. The domain (or workgroup) to which the machine is joined is the domain (or workgroup) associated with the computer account, not the user account.

The status of the service can be any of seven possible values, as shown in Table 8-2.

Table 8-2. Possible values for server status

Status

Description

UnPingable

The IP address does not respond

RUNNING

Service is running

STOPPED

Service is stopped

PENDING

Service is starting or stopping

Blank

Service does not exist

Access is Denied

Your account does not have minimal user-level rights to the box

The RPC server is unavailable

Computer is running Win9x,Win 3.x, or is a Samba box

There are several items you will need before the script will run. First, you need the Psservice utility that comes with the Pstools suite from Sysinternals . Place the psservice.exe utility in the same directory as the script itself. You also need to register the free System Scripting Runtime COM object from Netal (http://www.netal.com/ssr.htm). To register the COM object, copy the DLL to your system32 directory and use regsvr32 to register it. You'll need to do this for every box you run the script from, but this does not need to be done on the remote machines. By the way, I highly suggest reading through the documentation on both of these valuable pieces of software.

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 

Running the Hack

First, create a text file that contains the subnets you wish to query. Each subnet should end with .0 and be on its own line in the file. You can name the file subnets.txt and save it in the same directory as the script. Now, simply run the script by double-clicking on it; it will prompt you for input. The first input is just an introduction to the script. Clicking No will exit the script altogether.

The next input is the name of the service; this is not the same as the display name, so be careful here. Table 8-3 shows some examples of services for which the display name differs greatly from the service name. This information can help you detect rogue web servers running secretly on your network, client machines whose antivirus software has been disabled, or machines with SMS client software disabled, making them difficult to keep updated with security patches and service packs .

Table 8-3. Display names and corresponding service names

Display name

Service name

World Wide Web Publishing Service

w3svc

Norton Antivirus Client

Norton Antivirus Server

SMS Client Service

clisvc

The next prompt is the full path to the text file that contains the subnets. At this point, you can enter a different text file if you wish. Lastly, you have the opportunity to modify the subnets file before you begin. The scan will begin either after you click No or after you close Notepad. You will be notified when the script is finished with a pointer to the log file; there is no progress indicator as the script runs. If you need to cancel the script, go into Task Manager and kill the wscript.exe process.

I have used this script to find machines on which the SMS Client Service has been disabled. I have also found numerous IIS web servers and their owners . Lastly, this utility does a great job of finding the FLC service, which is better known as the FunLove virus. I get a big kick out of sending directors a list of developer machines that have FunLove on their box, have also disabled SMS, and are not running antivirus software.

Always deploy this script in a lab environment first and do your own benchmarking before pinging those 32,000 nodes.


Dennis Abbott

 < Day Day Up > 


Windows Server Hacks
Windows Server Hacks
ISBN: 0596006470
EAN: 2147483647
Year: 2004
Pages: 163
Authors: Mitch Tulloch

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net