用于提取命令输出的最佳工具

用于提取命令输出的最佳工具

我想以编程方式处理 nmap 输出的结果,但无法弄清楚如何获取输出并仅提取下面两个输出中显示的协议或端口表的详细信息。

我非常有信心我可以使用 awk 来处理表数据 - 但我无法从输出中提取这些数据......可以使用什么工具组合来执行此操作?

$ sudo nmap --open -sO 10.100.0.14
Starting Nmap 7.70 ( https://nmap.org ) at 2021-12-27 19:15 AEDT
Warning: 10.100.0.14 giving up on port because retransmission cap hit (10).
Nmap scan report for teichos.mydomain.net (10.100.0.14)
Host is up (0.00030s latency).
Not shown: 250 filtered protocols, 1 closed protocol
PROTOCOL STATE         SERVICE
1        open          icmp
33       open|filtered dccp
80       open|filtered iso-ip
117      open|filtered iatp
136      open|filtered udplite
MAC Address: 6A:3A:ED:33:9E:00 (Unknown)

输出2:

$ sudo nmap -sS 10.100.0.14 -p-
Starting Nmap 7.70 ( https://nmap.org ) at 2021-12-27 19:30 AEDT
Nmap scan report for teichos.mydomain.net (10.100.0.14)
Host is up (0.00024s latency).
Not shown: 65533 filtered ports
PORT     STATE SERVICE
22/tcp   open  ssh
9090/tcp open  zeus-admin
MAC Address: 6A:3A:ED:33:9E:00 (Unknown)

我正在寻找的输出如下(标题不是必需的):

PROTOCOL STATE         SERVICE
1        open          icmp
33       open|filtered dccp
80       open|filtered iso-ip
117      open|filtered iatp
136      open|filtered udplite

PORT     STATE SERVICE
22/tcp   open  ssh
9090/tcp open  zeus-admin

答案1

如果给定选项,该nmap实用程序允许输出易于解析的 XML -oX,这意味着您可以根据需要重新创建表,或从中提取所需的任何信息。

下面的管道用于xmlstarlet从生成的 XML 文档中提取信息,并重新创建在普通输出中找到的表nmap,并插入一个额外的列,其中插入了给定“状态”的“原因”。

的输出nmap由 解析xmlstarlet,它插入#字符(我们不希望成为输出一部分的任意字符)作为列分隔符,并column用于创建最终的对齐表。

sudo nmap -oX - --open -sO localhost |
xmlstarlet sel -t -m /nmaprun/host/ports/port \
    -v @portid -o '#' \
    -v state/@state -o '#' \
    -v state/@reason -o '#' \
    -v service/@name -nl |
column -s '#' -t

输出示例:

1    open           echo-reply      icmp
4    open|filtered  no-response     ipv4
6    open           proto-response  tcp
17   open           port-unreach    udp
41   open|filtered  no-response     ipv6
50   open|filtered  no-response     esp
51   open|filtered  no-response     ah
97   open|filtered  no-response     etherip
112  open|filtered  no-response     vrrp
137  open|filtered  no-response     mpls-in-ip
240  open|filtered  no-response
255  open|filtered  no-response

再次,但仅提取“过滤”响应:

sudo nmap -oX - --open -sO localhost |
xmlstarlet sel -t -m '/nmaprun/host/ports/port[contains(state/@state,"filtered")]'  \
    -v @portid -o '#' \
    -v state/@state -o '#' \
    -v state/@reason -o '#' \
    -v service/@name -nl |
column -s '#' -t

输出示例:

4    open|filtered  no-response  ipv4
41   open|filtered  no-response  ipv6
50   open|filtered  no-response  esp
51   open|filtered  no-response  ah
97   open|filtered  no-response  etherip
112  open|filtered  no-response  vrrp
137  open|filtered  no-response  mpls-in-ip
240  open|filtered  no-response
255  open|filtered  no-response

答案2

根据您显示的特定输出,我们可以简单地选择以数字或大写字母开头的所有行P(对于标题):

sudo nmap ... | grep -E '^([0-9]|P)'

我创建了两个文本文件,nmap1nmap2使用您的问题的两个输出进行测试,并得到:

$ grep -E '^([0-9]|P)' nmap1 
PROTOCOL STATE         SERVICE
1        open          icmp
33       open|filtered dccp
80       open|filtered iso-ip
117      open|filtered iatp
136      open|filtered udplite

$ grep -E '^([0-9]|P)' nmap2
PORT     STATE SERVICE
22/tcp   open  ssh
9090/tcp open  zeus-admin

awk如果您愿意,您也可以这样做:

sudo nmap ... | awk '/^([0-9]|P)/' 

答案3

$ awk '/^(PROTOCOL|PORT)/{f=1} /^MAC/{f=0} f' file
PROTOCOL STATE         SERVICE
1        open          icmp
33       open|filtered dccp
80       open|filtered iso-ip
117      open|filtered iatp
136      open|filtered udplite

$ awk '/^(PROTOCOL|PORT)/{f=1} /^MAC/{f=0} f' file
PORT     STATE SERVICE
22/tcp   open  ssh
9090/tcp open  zeus-admin

相关内容