Windows Command Shell 底下內建一個亂數變數 %random%
它產生的數值介於 0~32767 之間。
要將它局限在一定區間,以便程式應用!
Windows的事件檢視器可以把大小事都記錄下來,但是卻沒有提供良好的工具去搜尋,所以只好寫程式來輔助。
起始肇因公司要求對某些目錄檔案進行稽核記錄,但是這些檔案使用又非常頻繁,所以當發現需要檢視事件記錄時,常有上萬筆記錄;而事件檢視器並不提供針對檔名或是訊息當中的字串做為篩選條件,只能用事件代碼;要針對某檔案進行稽核時,就成了不可能的任務!
在以下程式中,有幾個參數要設定
strComputer 是指要被搜尋事件檢視器記錄的電腦名稱或 IP Address
strSearchString 是要被搜尋的字串
dtmLogDate 是匯出的檔名,我個人習慣在匯出檔案名稱加上日期,以方便處理;看您個人的習慣囉
| strComputer = "DFS1" Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate,(Security)}!\\" & strComputer & "\root\cimv2") Const ForWriting = 2 Set objFSO = CreateObject("Scripting.FileSystemObject") |
前一陣子公司不斷遭遇到 Cracker 攻擊 Exchange 2003 的 SMTP/POP3 服務,
企圖以暴力方式破解信箱帳號密碼。
由於本公司採用中華電信的資安艦隊服務,所以將 SMTP/POP3 Log Dump 出來之後,寄交中華電信處理。
中華電信將 IPS 的觸發值調低之後,安穩了兩天;兩天之後,卻發現 Cracker 改變攻擊的頻率,變成每兩秒 Try 一次帳號密碼。
當我將此發現告知中華電信資安艦隊服務人員之後,中華電信人員表示,由於駭客攻擊的頻率已經很低,無法攔阻這樣的攻擊,建議加強密碼政策管理來補強。
身為一個網路管理者,看到這樣的 Log 當然很不爽,駭客天天來家門口踩盤子,所以決定自己動手寫程式,強化 Exchange 防護措施
相信很多公司的郵件伺服器都會開放 SMTP 25 Port ,供差旅同仁方便寄信。
但這也給予Cracker / SPAMER SMTP Auth Relay Attack 的機會。
這會造成公司的郵件主機被列入黑名單之中…(網路上還是有不少公司堅持使用這種落伍的黑名單技術來阻擋廣告信)
到時同仁就會一直反應會被退信…
因為從外部透過公司郵件主機 Relay ,需要進行 SMTP 驗證
所以我寫了一支程式去監控事件檢視器,搭配 Exchange 的 SMTP 驗證記錄;如果有 SMTP 驗證成功的訊息,就會在我的電腦 Pop Up 一個提醒視窗。
首先把 Exchange 的 SMTP 驗證事件開啟
接著在本機執行以下程式(請存成 .vbs 檔案,然後執行它)
| strComputer = "MAIL" Set objWMIService = GetObject("winmgmts:{(Security)}\\" & strComputer & "\root\cimv2") Set colMonitoredEvents = objWMIService.ExecNotificationQuery ("Select * from __InstanceCreationEvent Where " & "TargetInstance ISA 'Win32_NTLogEvent' " & "and TargetInstance.EventCode = '1708'") Loop |
其中 1708 是 SMTP 驗證成功的事件代碼
當程式監控到 Event 時,就會跳出如下的視窗。
有人說:DNS MX 記錄指向 AntiSPAM 設備就不會受到 SMTP Auth Attack ,這是一個嚴重的錯誤觀念!
駭客要攻擊都會直接掃瞄 25 Port ,有誰開 25 Port ,就會被 Try…
@echo off
setlocal EnableDelayedExpansion
set Today="%DATE:~0,10%"
for /F %%I in ( 'dir *.dat /b' ) do (
set DT="%%~tI"
set FDT=!DT:~1,10!
if "!FDT!"==%Today% (
echo "%%~I"
) else (
echo wrong
)
)
endlocal
在 for 迴圈中,如果變數是檔名,可以利用以下格式,來讀取檔案相關資訊
(以 %I 為 for 迴圈變數,如果迴圈變數名不是 I,請將以下格式的 I 改掉)
%~I 檔名前後會自動加上雙引號
%~fI 會顯示該檔案的完整路徑+檔名
%~dI 顯示該檔案所在磁碟機代號
%~pI 顯示該檔案的完整路徑 (只有路徑,不含檔名)
%~nI 只顯示檔案名稱 (不含副檔名)
%~xI 只顯示檔案的副檔名 (不含主檔名)
%~sI 以短檔名格式顯示
%~aI 顯示檔案屬性 (AHRS)
%~tI 顯示檔案日期+時間
%~zI 顯示檔案大小
%~$PATH:I 搜尋PATH環境變數的每一個目錄,並顯示第一個符合檔名的完整路徑+檔名
以上的格式參數,可以組合使用。
例如:
%~nzI
以上,必須配合 for 迴圈的 /F 參數使用!
微軟官方網站的說明在此
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/for.mspx?mfr=true
strComputer = "ComputerName"
Set objAdmins = GetObject("WinNT://" & strComputer & "/Administrators")
Set objUser = GetObject("WinNT://DomainName/UserName")
objAdmins.Add(objUser.ADsPath)
要注意的是,使用者已經登入 Windows 後,才透過此程式加入管理者群組,並無法讓該使用者立即取得管理者權限。
使用者必須重新登入系統才會生效。
同樣的,如果使用者已具備管理者權限,即始使用此程式將使用者帳號移出本機管理者群組,管理者權限也不會立即失效,必須重新登入系統才能生效。
| strComputer = "ComputerName" Set objAdmins = GetObject("WinNT://" & strComputer & "/Administrators") objAdmins.Add(objUser.ADsPath) 要注意的是,使用者已經登入 Windows 後,才透過此程式加入管理者群組,並無法讓該使用者立即取得管理者權限。 使用者必須重新登入系統才會生效。 同樣的,如果使用者已具備管理者權限,即始使用此程式將使用者帳號移出本機管理者群組,管理者權限也不會立即失效,必須重新登入系統才能生效。 <html> <HTA:APPLICATION </head> <SCRIPT Language="VBScript"> ' Add Domain Account into Local Administrator Group ' Displays a message box when the button is clicked |
PS.請記得將紅字的 Domain Name 更換成你的網域名稱
在經歷許多環境發現,很多頗具規模的公司(以電腦數量來算),對於網域的管理,以及權限的管理都很鬆散。
隨隨便便一堆人都有本機管理者權限,當然公司會中毒、資料外洩也不足為奇。所以自己只要寫個簡單的小程式,就可以透過網路去檢查別台電腦的本機權限狀況。
MIS完全不用去中斷別人的工作,也不容易引起爭執。
當然在做這個動作之前,你最好先買個保險,由上級主管宣導實施,免得挨槍子。
| strComputer = "ComputerName" Set objGroup = GetObject("WinNT://" & strComputer & "/Administrators") For Each objUser In objGroup.Members |
使用 Exchange 2003 的 SPAM Archive 功能,會發現每天都有一堆信被封存,
才隔幾天,要開啟 Archive Folder時,卻系統卻會停止回應。
因為檔案太多,系統很忙碌的要一次讀取所有的檔案清單,
所以才有寫以下幾支程式的構想。
這支程式一執行,會將 E:\Exchsrvr\UCEArchive目錄下所有封存的 SPAM,按照日期格式 YYYYMMDD 歸檔存到 YYYYMMDD 目錄下,這樣子每個 Folder 的檔案數量不大,開啟資料夾速度就快多了。 ( Batch File )
| @echo off setlocal EnableDelayedExpansion for /F %%a in ( 'dir E:\Exchsrvr\UCEArchive\*.EML /b' ) do ( set FileName=%%a set DateDir=!FileName:~5,8! if not exist E:\Exchsrvr\UCEArchive\!DateDir! mkdir E:\Exchsrvr\UCEArchive\!DateDir! move E:\Exchsrvr\UCEArchive\!FileName! E:\Exchsrvr\UCEArchive\!DateDir! ) |
這支程式只會抓今天的日期,將今天的 SPAM 歸檔 ( Batch File )
| @echo off for /f "tokens=1-3 delims=/ " %%a in ('date /t') do (set date=%%a%%b%%c) if not exist E:\Exchsrvr\UCEArchive\%date% mkdir E:\Exchsrvr\UCEArchive\%date% move E:\Exchsrvr\UCEArchive\ARCH_%date%*.eml E:\Exchsrvr\UCEArchive\%date% |
這支程式會抓昨天的日期,將昨天的 SPAM 歸檔 ( Windows Script Host )
| ' 取得昨天的日期 ' 將昨天的日期取出年份 ' 將昨天的日期取出月份 ' 將昨天的日期取出日期 strYesterday = strYear & strMonth & strDay ' 以昨天的日期來建立目錄 objFolder.NewFolder strYesterday ' 將檔名包含昨天日期的檔案,全數搬移到昨天日期的目錄下 wscript.echo strYesterday & " Job is done !" |
以下這支程式,會跳出視窗,讓您輸入日期,將指定日期的 SPAM 歸檔 ( Windows Script Host )
| strDay = inputbox("請輸入日期 : ") ' 以昨天的日期來建立目錄 objFolder.NewFolder strDay ' 將檔名包含昨天日期的檔案,全數搬移到昨天日期的目錄下 wscript.echo strDay & " Job is done !" |
這是改用 Batch File 語法寫的程式,功能與上一支程式相同
| set /p DateDir="請輸入日期:" |
今天為了客戶寫了一支自動建帳號的程式
該程式將讀取 User 提供的帳號密碼清單來建立帳號
最近為了客戶移機的事,又寫了一支WSH,它是用ping來檢測網路品質,將結果存到CSV File,然後寄到指定的信箱裡。
當我收到這個CSV File時,就可以把它匯入SQL Server,利用Excel來繪製網路品質的圖表。
| On Error Resume Next ' 因為客戶有多個辦公室,所以加上一個Location欄位,以便日後分析 ' 這邊請輸入您自己要測試的端點 Public IP ' 設定 SMTP Server ' 設定供 SMTP驗證的帳號 ' 設定供 SMTP驗證的帳號密碼 |
其實這個功能跟我之前介紹的 ping commander很類似,只是我用WSH寫的,沒有 GUI 介面,而且多了個寄送 Log的功能。但是沒有支援 ping 多個目標的功能。
也許改天有空再改用 HTA來寫 GUI 介面的程式。
後記:
如果該程式的 strLocation最好使用英文,最好不要用中文,以免用戶端如果非繁中語系程式就會出問題!
有很多人(公司或個人),都是使用浮動 IP 的 ADSL,這導致 IT 人員進行遠端管理或維護時的困難。
坊間的解決方案多是使用 DDNS ,其他可以通報 IP 變動的工具大多都是要錢的...
其實這樣的程式也不難,要額外收費實在令人難以接受...
廢話不多說,底下就是我寫的WSH程式,
第一次執行後,會把你的 Public IP Address 寄到你指定的信箱,
之後每五分鐘會再 Check 一次 Public IP,如果IP 有變動,才會再寄信通知。
PS.該程式寄信並不需要你自己架Mail Service,可以在網路上找個 SMTP Server來用即可。
On Error Resume Next strDynamicIP = "xxx.xxx.xxx.xxx" ' 這個網址可以替換成你自己喜好的查詢 IP 地址的網站 Set objHTTP = CreateObject("MSXML2.XMLHTTP") Set objRegEx = CreateObject("VBScript.RegExp") Set objEmail = CreateObject("CDO.Message") while true Set colMatches = objRegEx.Execute(objHTTP.ResponseText) For Each strMatch in colMatches ' 網頁內容沒有 IP Address,考慮換個網站吧 ' 每隔 5 分鐘抓一次網頁,Check Public IP
strURL="http://briian.com/files/act/myip-widget.php"
objRegEx.Global = True
objRegEx.Pattern = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
objHTTP.Open "GET", strURL, FALSE
objHTTP.Send
strPublicIP = strMatch.Value
Next
if colMatches.Count < 1 then
WScript.Echo "IP Address Not Found !"
end if
' 如果抓出來的網頁只有一個 IP Address,而且跟之前抓的不一樣,表示 IP 有變動,要通知囉
if colMatches.Count = 1 and strDynamicIP <> strPublicIP then
objEmail.From = "寄信人信箱地址"
objEmail.To = "收件人信箱地址"
objEmail.Subject = "Your Public IP : " & strPublicIP
objEmail.Textbody = strPublicIP
objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "SMTP Server的FQDN或IP"
objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusername") = "你的E-Mail帳號"
objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "你的e-Mail密碼"
objEmail.Configuration.Fields.Update
objEmail.Send
strDynamicIP = strPublicIP
end if
' 如果抓出來的網頁內容,超過一個 IP Address,就要改程式去分析網頁囉
if colMatches.Count > 1 then
WScript.Echo "Too Many IPs !"
end if
wscript.sleep 300000
wend
使用 Exchange 2003 的 IMF 功能時,
畢竟它還是會誤判,所以保險的作法是將 SPAM Mail 封存,
如果有漏信,再來 SPAM Mail Folder找漏信。
結果,太久沒去看 SPAM Mail Archive Folder,裡面累積了數十萬封廣告信,
每一封廣告信都是 .EML 檔案,純文字格式,可以用 Outlook Express 開啟閱讀。
重點是,在檔案總管一進入此目錄時,就因為檔案太多,造成系統無回應。
為了處理這個狀況,只好在命令提示字元模式下,以指令搬移檔案,但是這樣很花時間,
所以我寫了一支小程式,依照日期建立目錄,同時將每天的廣告信搬到該目錄下,
這樣就不會造成一個目錄底下有太多檔案,系統忙著讀取資訊而沒有回應。
' 取得昨天的日期
dtmYesterday = Date() - 1
' 將昨天的日期取出年份
strYear = left(dtmYesterday,4)
' 將昨天的日期取出月份
' 因為月份小於10時,不會補 0, 這樣目錄看起來會有點亂,所以稍微加工一下
if mid(dtmYesterday,7,1) = "/" then
strMonth = "0" & mid(dtmYesterday,6,1)
else
strMonth = mid(dtmYesterday,6,2)
end if
' 將昨天的日期取出日期
' 因為日期小於 10時,不會補零,這樣目錄看起來會有點亂,所以稍微加工一下
if mid(dtmYesterday,len(dtmYesterday)-1,1) = "/" then
strDay = "0" & right(dtmYesterday,1)
else
strDay = right(dtmYesterday,2)
end if
strYesterday = strYear & strMonth & strDay
' 以昨天的日期來建立目錄
ParentFolder = "E:\Exchsrvr\UCEArchive"
set objShell = CreateObject("Shell.Application")
set objFolder = objShell.NameSpace(ParentFolder)
objFolder.NewFolder strYesterday
' 將檔名包含昨天日期的檔案,全數搬移到昨天日期的目錄下
Set objFSO = CreateObject("Scripting.FileSystemObject")
FileNamePatten = "ARCH_" & strYesterday & "*.EML"
objFSO.MoveFile "E:\Exchsrvr\UCEArchive\" & FileNamePatten , "E:\Exchsrvr\UCEArchive\" & strYesterday
' 這只是告知程式執行完畢的訊息,要不然完全沒有訊息,程式有沒有跑,有沒有完都不知道!
wscript.echo strYesterday & " Job is done !"