0

语境

我用来FINDSTR /C:"portid=" "scanports.xml"从文件中提取这些行:

<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>

问题

  • 如何从这一行中提取2122、和?804433389
  • [0-9]对于除212280和?中443的随机数的相同问题3389

我想通过电子邮件发送通常未打开的所有打开的端口。

4

4 回答 4

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 文件的格式一致,则可以使用 FOR /F 并将 DELIMS 设置为引号字符来提取第 4 个标记。用引号作为分隔符指定 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 * 搜索和替换 op 在字符串中查找 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来发送您的电子邮件。

于 2012-02-08T19:44:21.983 回答
1

您可以使用 FOR/F 来解析行。

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

FOR /F "tokens=3 delims=>=" %%1 in (tmpFile.tmp) DO (
  echo %%~1
)
于 2012-02-08T19:02:22.517 回答
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
于 2012-02-10T02:45:10.350 回答
0

我用jeb 的回答这个链接完成了我的脚本。

代码:

@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 from=x@x.com
SET to=y@y.com

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
)
于 2012-02-08T19:53:25.667 回答