2012-02-08 41 views
0

語境

我用FINDSTR /C:"portid=" "scanports.xml"從文件中提取論文線發送郵件:的Nmap:提取不良端口,用於與批次和BLAT

<port protocol="tcp" portid="21"><state state="open" reason="syn-ack" reason_ttl="124"/><service name="ftp" method="table" conf="3"/></port> 
<port protocol="tcp" portid="22"><state state="open" reason="syn-ack" reason_ttl="124"/><service name="ssh" method="table" conf="3"/></port> 
<port protocol="tcp" portid="80"><state state="open" reason="syn-ack" reason_ttl="124"/><service name="http" method="table" conf="3"/></port> 
<port protocol="tcp" portid="443"><state state="open" reason="syn-ack" reason_ttl="124"/><service name="https" method="table" conf="3"/></port> 
<port protocol="tcp" portid="3389"><state state="open" reason="syn-ack" reason_ttl="124"/><service name="ms-term-serv" method="table" conf="3"/></port> 

問題

  • 如何提取2122804433389從這一行?
  • 對於[0-9]中的隨機數,同樣的問題除了21, 22,80,4433389

我想通過電子郵件發送所有打開的端口通常不會打開。

回答

3

您可以使用第二個FINDSTR過濾掉「常開」端口。我顯示的解決方案使用外部文件列出要排除的端口(常開端口)。或者,該列表可以在命令行上指定爲多個/C選項。

ignore.txt(根據需要編輯)

portid="21" 
portid="22" 
portid="80" 
portid="443" 
portid="3389" 

findstr /c:"portid=" test.txt | findstr /r /v /g:"ignore.txt"

沒有與FINDSTR一個錯誤,它可能無法找到匹配,如果有多個不同長度的文字搜索字符串。這就是我選擇使用/R正則表達式選項的原因。

如果XML文件的格式是一致的,那麼您可以將DELIMS中的FOR/F設置爲引號字符來提取第4個標記。用quote作爲分隔符指定FOR/F選項的語法很奇怪:通常情況下,您會執行類似於"tokens=4 delims=,"的操作。但要包括引號作爲分隔符,你必須做一堆轉義:tokens^=4^ delims^=^"

把他們放在一起,你得到

@echo off 
for /f tokens^=4^ delims^=^" %%P in (
    'findstr /c:"portid=" test.txt ^| findstr /r /v /g:"ignore.txt"' 
) do (
    echo unusual open port = %%P 
) 
exit /b 

如果格式(屬性順序)的XML可以改變,那麼該解決方案更爲複雜。您首先使用外部FOR/F將整行讀入變量。您使用SET *搜索並替換操作來查找字符串中的portid位置,然後使用第二個FOR/F來解析出實際的端口。

setlocal enableDelayedExpansion 
for /f "delims=" %%L in (
    'findstr /c:"portid=" test.txt ^| findstr /r /v /g:"ignore.txt"' 
) do (
    set "ln=%%L" 
    for /f delims^=^=^" %%A in ("!ln:*portid=!") do set port=%%A 
    echo unusual open port = !port! 
) 

一旦您將端口ID隔離,您就可以構建郵件消息。我建議使用Blat for Windows發送您的電子郵件。

+0

我完成了我的劇本,但謝謝,我讀了你的答案。 :) – 2012-02-08 19:55:25

+0

真的很抱歉濫用您的時間。 – 2012-02-08 19:57:44

1

您可以使用FOR/F來分析行。

FINDSTR /C:"portid=" "scanports.xml" > tmpFile.tmp 

FOR /F "tokens=3 delims=>=" %%1 in (tmpFile.tmp) DO (
    echo %%~1 
) 
+0

我只需要'21'而不是''。但你的回答幫助了我,謝謝! – 2012-02-08 19:54:36

0

我用jeb's answerthis link完成我的腳本。

代碼:

@ECHO Off 
SETLOCAL ENABLEDELAYEDEXPANSION 

REM Blat options: 
SET blat="C:\Program Files (x86)\blat276\full\blat.exe" 
SET server=127.0.0.1 
SET port=25 
SET [email protected] 
SET [email protected] 

FOR %%i IN (1,1,9) DO ( 
    "C:\Program Files (x86)\Nmap\nmap.exe" server%%i.com -oX scanports%%i.xml 

    FINDSTR /C:"portid=" scanports%%i.xml >> scanports%%itemp.txt 

    FOR /F "tokens=*" %%a IN (scanports%%itemp.txt) DO (
    SET x=%%a 
    SET x=!x:"=/! 
    FOR /f "tokens=4,12 delims=/" %%a IN ("!x!") DO (
     IF NOT %%a==21 IF NOT %%a==22 IF NOT %%a==80 IF NOT %%a==443 IF NOT %%a==3389 (
     %blat% -server %server% -port %port% -f %from% -to %to% -html -s "Port ouvert sur server%%i" -body "Port %%a : %%b" 
    ) 
    ) 
) 

    DEL scanports%%i.xml 
    DEL scanports%%itemp.txt 
) 
1

這有點作弊,但您的批處理文件可以調用一個VBScript腳本:

c:\windows\system32\cscript.exe //nologo scanports.vbs 

哪裏scanports.vbs是下面的腳本:

Option Explicit 
Dim xml, port 
Set xml = CreateObject("Microsoft.XMLDOM") 
xml.load "scanports.xml" 
For Each port in xml.documentElement.selectNodes("//port") 
    WScript.Echo port.getAttribute("portid") 
Next