You are on page 1of 5

' Scan DHCP Script(scanDHCP.

vbs)
' By: Ed Levin
' 9 / 3 /09
'
' DESCRIPTION: This script will scan a given IP range for DHCP servers (port UDP
67) by using the ScanLine command line port scanner from Foundstone, Inc. The I
P range to be scanned is to be provided on the
' first line in a text file. Optionally, a list of valid DHCP servers can be sup
plied starting from the second line of the same file, one per line, as "IP,MAC"
(comma-delimited pair). Some examples:
'
' Example 1:
'
' 192.168.1.100
'
' Example 2:
'
' 192.168.1.1-254
' 192.168.1.100,00-a2-b3-71-3c-aa
'
' Following the scan, the script will attempt to match white-listed DHCP server
MAC address(es), provided in the input file (if any), with the MAC addresses for
the same IPs obtained from the local ARP cache.
' VALID_ON_NO_MAC constant below can be set to TRUE to treat cases where only an
IP match could be made with the input file (a MAC address cannot be found in th
e ARP cache) as valid.
'
' ARGUMENTS: The script requires 2 arguments which are the path to the temp/outp
ut files and an input file containing the IP range to scan and optionally a list
of valid DHCP server IP and MAC addresses:
'
' Example:
'
' scanDHCP.vbs c:\temp input.txt
'
' REQUIREMENTS: The script has to be executed on an a Widnows XP/2003 (no Vista
or 2008) locally and sl.exe (ScanLine port scanner) needs to be present in the s
pecified path.
'
' PURPOSE:
' Customize these as needed
Const VALID_ON_NO_MAC = FALSE
Const OUTPUT_FILE = "dhcp-result.txt"
Const SCAN_RESULT_FILE = "scan-result.txt"
Const ARP_RESULT_FILE = "arp-result.txt"
Const EventErrorID = 910
' Dont touch these
Const SCANLINE_EXE = "sl.exe"
Const ARP_EXE_FILE = "arp.exe"
Const EVENTCREATE_EXE = "eventcreate.exe"
Const EventLog = "APPLICATION"
Const EventErrorType = "ERROR"
Const EventSource = "ScanDHCPScript"
Const DHCP_SERVER_PORT = 67
Const ReadOnlyOverride = TRUE
Const Quit = TRUE
Const DontQuit = FALSE
Const GENERAL_FAILURE = 2
Const WaitOnReturn = TRUE
Const Overwrite = TRUE
Const ForReading = 1
Const SYSTEM32 = &H25&
Set ArgObj = WScript.Arguments
If ArgObj.Count <> 2 Then
Wscript.Echo "Incorrect number of arguments provided."
Wscript.Quit(GENERAL_FAILURE)
End If
' Set filesystem variables
localPath = argObj(0)
dhcpInputFile = localPath & "\" & argObj(1)
outputFile = localPath & "\" & OUTPUT_FILE
slProgram = localPath & "\" & SCANLINE_EXE
scanResultFile = localPath & "\" & SCAN_RESULT_FILE
arpResultFile = localPath & "\" & ARP_RESULT_FILE
' Initialize objects
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set Command = WScript.CreateObject("WScript.Shell")
' Get local system name
Set objSysInfo = CreateObject ("WinNTSystemInfo")
hostName = objSysInfo.ComputerName
' Retrieve and set ARP.EXE path
Set objShell = CreateObject("Shell.Application")
Set objArpFolder = objShell.Namespace(SYSTEM32)
Set objArpFolderItem = objArpFolder.Self
ARP_EXE = objArpFolderItem.Path & "\" & ARP_EXE_FILE
' Open log file
On Error Resume Next
Set objResultFile = objFSO.CreateTextFile(outputFile,Overwrite)
If Err.Number <> 0 Then
errMsg = "Creating " & UCase(outputFile) & ": " & Err.Description
Wscript.Echo "The following error was encountered: " & VbCrLf
Wscript.Echo errMsg
Wscript.Echo "Error Code: " & Err.Number & VbCrLf
Wscript.Echo "Exiting..."
Wscript.Quit(Err.Number)
End If
On Error Goto 0
' Log file header
objResultFile.WriteLine "DHCP scan started on " & UCase(hostName) & " on " & Dat
e() & " at " & Time() & VbCrLf
objResultFile.WriteLine "-------------------------------------------------------
----------" & VbCrLf
' Open valid DHCP file
On Error Resume Next
Set objValidDHCPfile = objFSO.OpenTextFile(dhcpInputFile,ForReading)
If Err.Number <> 0 Then
Call ErrorHandler("Opening valid DHCP file: " & Err.Description,Err.Numb
er,Quit)
End If
On Error Goto 0
' Read subnet/range from first line of valid DHCP file
subnet = objValidDHCPfile.ReadLine
Set validDHCPservers = CreateObject("Scripting.Dictionary")
' Read valid DHCP file
Do Until objValidDHCPfile.AtEndOfStream
currentLine = objValidDHCPfile.ReadLine
arrDHCP = split(currentLine,",")
validDHCPservers.Add arrDHCP(0),arrDHCP(1)
Loop
objValidDHCPfile.Close
' Run ScanLine
slCommand = slProgram & " -hpjs -o """ & scanResultFile & """ -u " & DHCP_SERVER
_PORT & " " & subnet
ReturnCode = Command.Run(slCommand,7,WaitOnReturn)
' Run ARP
arpCommand = "%comspec% /c " & ARP_EXE & " -a > """ & arpResultFile & """"
ReturnCode = Command.Run(arpCommand,7,WaitOnReturn)
' Open arp result file
On Error Resume Next
Set objArpResultFile = objFSO.OpenTextFile(arpResultFile,ForReading)
If Err.Number <> 0 Then
Call ErrorHandler("Opening ARP result file: " & Err.Description,Err.Numb
er,Quit)
End If
On Error Goto 0
Set arpEntries = CreateObject("Scripting.Dictionary")
objArpResultFile.ReadLine
objArpResultFile.ReadLine
objArpResultFile.ReadLine
' Read arp result file
Do Until objArpResultFile.AtEndOfStream
currentLine = objArpResultFile.ReadLine
arrIP = split(currentLine," ")
IP = arrIP(2)
arrMAC = split(currentLine,"-")
MAC = RIGHT(arrMAC(0),2) & "-" & arrMAC(1) & "-" & arrMAC(2) & "-" & arr
MAC(3) & "-" & arrMAC(4) & "-" & LEFT(arrMAC(5),2)
arpEntries.Add IP,MAC
Loop
objArpResultFile.Close
' Open scan result file
On Error Resume Next
Set objScanResultFile = objFSO.OpenTextFile(scanResultFile,ForReading)
If Err.Number <> 0 Then
Call ErrorHandler("Opening scan result file: " & Err.Description,Err.Num
ber,Quit)
End If
On Error Goto 0
' Read scan result file and process
invalidCount = 0
header = objScanResultFile.ReadLine
Do Until objScanResultFile.AtEndOfStream
currentLine = objScanResultFile.ReadLine
If InStr(currentLine,"" & DHCP_SERVER_PORT & "") <> 0 Then
arrDHCP = split(currentLine,",")
DHCP = arrDHCP(0)
' Get the MAC
foundMAC = FALSE
arpKeys = arpEntries.Keys
For j = 0 to arpEntries.Count - 1
If strcomp(DHCP,arpKeys(j)) = 0 Then
arpMAC = arpEntries.Item(arpKeys(j))
foundMAC = TRUE
Exit For
End If
Next
' Compare scan results against valid DHCP servers
validDHCPKeys = validDHCPservers.Keys
For i = 0 to validDHCPservers.Count - 1
match = FALSE
If strcomp(DHCP,validDHCPKeys(i)) = 0 Then
match = TRUE
If foundMAC = TRUE Then
validMAC = validDHCPservers.Item(validDH
CPKeys(i))
If strcomp(LCase(validMAC),LCase(arpMAC)
) = 0 Then
objResultFile.WriteLine DHCP & "
/ " & arpMAC & " : valid"
Else
objResultFile.WriteLine DHCP & "
/ " & arpMAC & " : invalid (MAC mismatch, possible IP impersonation)"
invalidCount = invalidCount + 1
End If
Else
If VALID_ON_NO_MAC = TRUE Then
objResultFile.WriteLine DHCP & "
: valid (no MAC found in ARP cache, IP match only)"
Else
objResultFile.WriteLine DHCP & "
: invalid (no MAC found in ARP cache, IP match only)"
invalidCount = invalidCount + 1
End If
End If
Exit For
End If
Next
If (match = FALSE) AND (foundMAC = TRUE) Then
objResultFile.WriteLine DHCP & " / " & arpMAC & " : inva
lid"
invalidCount = invalidCount + 1
End If
If (match = FALSE) AND (foundMAC = FALSE) Then
objResultFile.WriteLine DHCP & " : invalid (no MAC found
in ARP cache)"
invalidCount = invalidCount + 1
End If
End If
Loop
objScanResultFile.Close()
' Create an Event Log alert if need
If (invalidCount > 0) Then
eventLogCommand = "%comspec% /c " & EVENTCREATE_EXE & " /L " & EventLog
& " /T " & EventErrorType & " /SO " & EventSource & " /ID " & EventErrorID & " /
D """ & invalidCount & " invalid DHCP server(s) detected while scanning " & subn
et & ". Please see log ('Get File' in Kaseya) for details."""
returnCode = Command.Run(eventLogCommand,7,WaitOnReturn)
End If
' Delete temp result files
On Error Goto 0
objFSO.DeleteFile(arpResultFile)
If Err.Number <> 0 Then
Call ErrorHandler("Deleting ARP result file: " & Err.Description,Err.Num
ber,DontQuit)
End If
objFSO.DeleteFile(scanResultFile)
If Err.Number <> 0 Then
Call ErrorHandler("Deleting scan result file: " & Err.Description,Err.Nu
mber,DontQuit)
End If
On Error Goto 0
objResultFile.Close()
' Record errors in the log file
Sub ErrorHandler(errMsg,errCode,exitFlag)
objResultFile.Write VbCrLf & "ERROR: "
objResultFile.Write errMsg & ", "
objResultFile.WriteLine "Error Code: " & errCode & VbCrLf
If exitFlag = TRUE Then
objResultFile.WriteLine "Exiting..."
objResultFile.Close
Wscript.Quit(errCode)
End If
End Sub

You might also like