使用 awk 解析 nmap 输出文件以打印包含所有开放端口的 IP 列表

使用 awk 解析 nmap 输出文件以打印包含所有开放端口的 IP 列表

我想使用命令查找包含所有开放端口的 IP 地址列表awk

我的 nmap 输出文件是:

# Nmap 7.01 scan initiated Sat Mar 18 06:27:08 2017 as: nmap -oG output.txt -T4 -f -iL iplist.txt
Host: 10.0.0.99 ()    Status: Up
Host: 10.0.0.99 ()    Ports: 135/open/tcp//msrpc///, 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds///, 514/filtered/tcp//shell///, 554/open/tcp//rtsp///, 10243/open/tcp//unknown///    

Host: 192.168.0.1 ()    Status: Up
Host: 192.168.0.1 ()    Ports: 135/open/tcp//msrpc///, 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds///, 10243/open/tcp//unknown/// 

Host: 192.168.0.101 ()    Status: Up
Host: 192.168.0.101 ()    Status: Up
# Nmap done at Sat Mar 18 06:29:02 2017 -- 3 IP addresses (3 hosts up) scanned in 113.19 seconds

预期输出:

10.0.0.99   135
10.0.0.99   139
10.0.0.99   445
10.0.0.99   514
10.0.0.99   554
10.0.0.99   10243
192.168.0.1 135
192.168.0.1 139
192.168.0.1 445 
192.168.0.1 10243

输出保存在另一个文件中(例如parse.txt)

答案1

您要求awk,但是使用 Perl 可以很简单地做到这一点,因为它可以轻松地迭代正则表达式的多个匹配项。

$ perl -ne '$host = $1 if /^Host: (\S+)/; while(m,(\d+)/open,g) 
    { print "$host\t$1\n" } ' < nmap.out 
10.0.0.99       135
10.0.0.99       139
...


perl -ne                       # Run the code for each input line
'$host = $1 if /^Host: (\S+)/  # If the line starts with "Host: ", 
                               # save the next non-whitespace string
while( m,(\d+)/open,g ) {      # Go through all matches of `<digits>/open`
                               # on the line, catching the digits
    print "$host\t$1\n"        # Print the saved hostname and the matched digits.
}'                              

答案2

awk 方法:

$ awk -F'[/ ]' '{h=$2; for(i=1;i<=NF;i++){if($i=="open"){print h,$(i-1)}}}' file 
10.0.0.99 135
10.0.0.99 139
10.0.0.99 445
10.0.0.99 554
10.0.0.99 10243
192.168.0.1 135
192.168.0.1 139
192.168.0.1 445
192.168.0.1 10243

-F[/ ]输入字段分隔符设置为/或 空格。这意味着主机 IP $2、端口号和“开放”一词将位于各自的字段中。因此,我们可以迭代一行 ( for(i=1;i<=NF;i++){}) 的所有字段,如果当前字段是open,则打印主机名和前一个字段(端口):if($i=="open"){print h,$(i-1)}

答案3

我认为我无法在这里清楚地表达我的观点。我想强调的是,我们可以piggyback在正则表达式 m// 上为我们执行循环,而不是使用显式循环,为了更清晰,下面是重构的正则表达式:

perl -lne '
    /^
        Host: \s+ (\S+) \s+         # stuff $1 with hostname
        .+?:                        # seek the nearest colon :
        (?:                         # setup a loop
           \s+(\d+)\/open\/\S+      # this pattern should repeat
           (?{ print "$1\t$2" })    # print hostname+digits foreach turn
        )* # (?{ CODE }) does a code execution during regex search
    /x;
' yourfile

相关内容