Skip to content

Instantly share code, notes, and snippets.

@wqweto wqweto/rdplog.vbs
Created Dec 10, 2013

Embed
What would you like to do?
This script transfers failed logon attempts from Terminal Servers to /var/log/rdp/audit.log on the gateway server. From this point the log file is processed by fail2ban rules.
Const SSH_SERVER_LOG = "/var/log/rdp/audit.log"
Const LOCAL_RDP_GROUP = "Remote Desktop Users"
Const CACHE_AGE_IN_MINUTES = 5
Const DENY_USERS = "Administrator|Administrador|Admin|Admin1|POS|User|UsUser1|system|sys|aspnet|root|sql|post|post1|bank|operator|oper|oper1|test|test1"
Const NOLOG_USERS = "VDC02"
If Not WScript.Arguments.Named.Exists("s") Then
WScript.echo "usage: " & WScript.ScriptName & " /s:server /l:user /i:key_file"
WScript.Quit 1
End if
'--- init args
m_sSshServer = WScript.Arguments.Named("s")
m_sSshPort = WScript.Arguments.Named("p")
m_sSshUser = WScript.Arguments.Named("l")
m_sSshKeyfile = WScript.Arguments.Named("i")
m_sSshPass = WScript.Arguments.Named("pw")
'--- init member vars
Set m_oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set m_oShell = WScript.CreateObject("WScript.Shell")
Set m_oFSO = WScript.CreateObject("Scripting.FileSystemObject")
m_sProcessName = WScript.ScriptName
m_lProcessId = GetCurrentProcessId()
With WScript.CreateObject("WScript.Network")
m_sComputerName = .ComputerName
m_sDomainName = .UserDomain
End With
'--- init regexp
Set m_oSanitizeIP = new RegExp
m_oSanitizeIP.Global = True
m_oSanitizeIP.Pattern = "[^0-9.]"
'--- init known rdp users
Set m_oRdpUsers = GetRdpUsers()
m_dRdpUsersTimestamp = Now
'--- init event sink
sQuery = "SELECT * FROM __InstanceCreationEvent WHERE TargetInstance ISA 'Win32_NTLogEvent'" & _
" AND TargetInstance.Logfile = 'Security' AND TargetInstance.EventType = 5" & _
" AND (TargetInstance.EventIdentifier = 529 OR TargetInstance.EventIdentifier = 4625)" & _
" AND (TargetInstance.SourceName = 'Security' OR TargetInstance.SourceName = 'Microsoft-Windows-Security-Auditing')"
m_oWMI.ExecNotificationQueryAsync WScript.CreateObject("WbemScripting.SWbemSink", "EventSink_"), sQuery
'--- main loop
Do
WScript.Sleep 100
Loop
'= event sinks ==================================================================================
Sub EventSink_OnObjectReady(oEvent, oWbemAsyncContext)
If oEvent.TargetInstance.SourceName = "Microsoft-Windows-Security-Auditing" Then
sUserName = oEvent.TargetInstance.InsertionStrings(5)
sClientIp = oEvent.TargetInstance.InsertionStrings(19)
Else '--- Win2k3
sUserName = oEvent.TargetInstance.InsertionStrings(0)
sClientIp = oEvent.TargetInstance.InsertionStrings(11)
End If
sClientIp = m_oSanitizeIP.Replace(sClientIp, vbNullString)
If LenB(sUserName) <> 0 And LenB(sClientIp) <> 0 Then
If InStr(1, "|" & NOLOG_USERS & "|", "|" & sUserName & "|", vbTextCompare) > 0 Then
'--- do nothing
ElseIf InStr(1, "|" & DENY_USERS & "|", "|" & sUserName & "|", vbTextCompare) > 0 Then
LogEvent "Denied user name " & sUserName & " from " & sClientIp
ElseIf CheckLoginExist(sUserName) Then
LogEvent "Login failed for " & sUserName & " from " & sClientIp
Else
If m_dRdpUsersTimestamp < DateAdd("n", -CACHE_AGE_IN_MINUTES, Now()) Then
On Error Resume Next
Set oUsers = GetRdpUsers()
On Error GoTo 0
If IsObject(oUsers) Then
Set m_oRdpUsers = oUsers
m_dRdpUsersTimestamp = Now
If CheckLoginExist(sUserName) Then
LogEvent "Login failed for " & sUserName & " from " & sClientIp
Exit Sub
End If
End If
End If
LogEvent "Unknown user name " & sUserName & " from " & sClientIp
End If
End If
End Sub
'= functions ====================================================================================
Function CheckLoginExist(sUserName)
If m_oRdpUsers.Exists(m_sDomainName & "\" & sUserName) Then
CheckLoginExist = True
ElseIf m_oRdpUsers.Exists(m_sComputerName & "\" & sUserName) Then
CheckLoginExist = True
Else
CheckLoginExist = (InStr(1, sUserName, "_") > 0)
End If
End Function
Sub LogEvent(sMsg)
sLog = FormatLogDate(Now) & " " & m_sComputerName & " " & m_sProcessName & "[" & CStr(m_lProcessId) & "]: " & sMsg
WScript.echo sLog
sCmd = "plink.exe " & Quote(m_sSshUser & "@" & m_sSshServer) & _
IIf(LenB(m_sSshPort) <> 0, " -P " & Quote(m_sSshPort), vbNullString) & _
IIf(LenB(m_sSshKeyfile) <> 0, " -i " & Quote(m_sSshKeyfile), vbNullString) & _
IIf(LenB(m_sSshPass) <> 0, " -pw " & Quote(m_sSshPass), vbNullString)
m_oShell.Exec sCmd & " echo -e " & Quote(Replace(sLog, "\", "\\")) & " >> " & SSH_SERVER_LOG
End Sub
Function FormatLogDate(d)
FormatLogDate = Split("N/A Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")(Month(d)) & " " & Right(" " & Day(d), 2) & " " & _
Right("0" & Hour(d), 2) & ":" & Right("0" & Minute(d), 2) & ":" & Right("0" & Second(d), 2)
End Function
Function IIf(Cond, TruePart, FalsePart)
If Cond Then IIf = TruePart: Else IIf = FalsePart
End Function
Function Quote(sText)
Quote = """" & Replace(sText, """", "\""") & """"
End Function
Function GetCurrentProcessId()
Const TemporaryFolder = 2
Const ForWriting = 2
With m_oFSO
sTempFile = .BuildPath(.GetSpecialFolder(TemporaryFolder), "$~sleep.vbs")
.OpenTextFile(sTempFile, ForWriting, True).Write "WScript.Sleep 1000"
End With
With m_oShell.Exec("WScript " & sTempFile)
sQuery = "SELECT * FROM Win32_Process WHERE ProcessId=" & .ProcessID
End With
For Each oPrc In m_oWMI.ExecQuery(sQuery)
GetCurrentProcessId = oPrc.ParentProcessId
Exit For
Next
End Function
Function GetRdpUsers()
'--- init local group
Set GetRdpUsers = CreateObject("Scripting.Dictionary")
GetRdpUsers.CompareMode = 1
GetGroupMembers m_sComputerName, LOCAL_RDP_GROUP, GetRdpUsers
'--- loop groups
lIdx = 0
vKeys = GetRdpUsers.Keys
Do While lIdx < GetRdpUsers.Count
If lIdx > UBound(vKeys) Then
vKeys = GetRdpUsers.Keys
End If
vItem = GetRdpUsers.Item(vKeys(lIdx))
GetGroupMembers vItem(0), vItem(1), GetRdpUsers
lIdx = lIdx + 1
Loop
LogEvent "Cached " & GetRdpUsers.Count & " users and groups from " & LOCAL_RDP_GROUP
End Function
Function GetGroupMembers(sDomain, sGroup, oResult)
sQuery = "SELECT * FROM Win32_GroupUser WHERE GroupComponent = ""Win32_Group.Domain='" & sDomain & "',Name='" & sGroup & "'"""
For Each vPath In m_oWMI.ExecQuery(sQuery)
vSplit = Split(vPath.PartComponent, """")
If Not oResult.Exists(vSplit(1) & "\" & vSplit(3)) Then
oResult.Add vSplit(1) & "\" & vSplit(3), Array(vSplit(1), vSplit(3))
End If
Next
End Function
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.