解析 nmap 输出
Parsing nmap output
我正在从事的一个让自己熟悉的项目是解析 nmap
结果。
(我知道 -oG
选项,但我在这里使用 grep
、awk
、for
和 while
循环) .
下面是我要解析的内容:
Starting Nmap 7.60 ( https://nmap.org ) at 2017-12-05 11:26 EST
Nmap scan report for house.router.nick (192.168.1.1)
Host is up (0.00059s latency).
Not shown: 995 closed ports
PORT STATE SERVICE
22/tcp open ssh
53/tcp open domain
427/tcp open svrloc
1900/tcp open upnp
MAC Address: 50:C7:BF:A8:CF:C8 (Tp-link Technologies)
Nmap scan report for 192.168.1.2
Host is up (0.00034s latency).
Not shown: 996 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
139/tcp open netbios-ssn
445/tcp open microsoft-ds
MAC Address: 48:F8:B3:C9:AE:BB (Cisco-Linksys)
我想得到的是:
22/ssh
====
192.168.1.1
192.168.1.2
http
===
192.168.1.2
到目前为止,我有这个:
grep -E "tcp.*open" nmap.txt | awk '{ print }' | sort | uniq
对于我的一生,我无法弄清楚如何将其放入各种循环并从上面获得所需的输出。
能否请您帮助我学习并解释您为什么得出您所做的解决方案?如果我无法理解其背后的逻辑,那么获得潜在解决方案毫无意义。
您最好使用通用编程语言(python、perl、awk),您可以在看到 "scan report for" 关键字时捕获 IP 地址,然后维护一个将服务名称映射到 IP 地址列表的数据结构 运行 这些服务。
例如,给定该输出,这个 perl 单行代码(提供但没有解释)
perl -ne '
if (/Nmap scan report for .*?(\d+\.\d+\.\d+\.\d+)/) {
$ip =
}
elsif (/^(\d+)\/tcp\s+open\s+(.*)/) {
push @{$services{"/"}}, $ip
}
END {
for $svc (sort {$a <=> $b} keys %services) {
printf "%s\n%s\n\n", $svc, join("\n", @{$services{$svc}})
}
}
'
生产
22/ssh
192.168.1.1
192.168.1.2
53/domain
192.168.1.1
80/http
192.168.1.2
139/netbios-ssn
192.168.1.2
427/svrloc
192.168.1.1
445/microsoft-ds
192.168.1.2
1900/upnp
192.168.1.1
$ cat tst.awk
BEGIN { FS="[[:space:]/]+" }
/Nmap scan report/ {
ip = $NF
gsub(/[()]/,"",ip)
}
/tcp.*open/ {
key = "/"
ips[key] = (key in ips ? ips[key] ORS : "") ip
}
END {
for (key in ips) {
print key
print "===="
print ips[key]
print ""
}
}
.
$ awk -f tst.awk file
80/http
====
192.168.1.2
1900/upnp
====
192.168.1.1
427/svrloc
====
192.168.1.1
445/microsoft-ds
====
192.168.1.2
53/domain
====
192.168.1.1
22/ssh
====
192.168.1.1
192.168.1.2
139/netbios-ssn
====
192.168.1.2
我认为它的作用非常明显,但如果您在浏览了 awk 手册页后有任何疑问,请随时提问。
以上内容在每个 UNIX 系统上都可以使用任何 shell 中的任何 awk。
我正在从事的一个让自己熟悉的项目是解析 nmap
结果。
(我知道 -oG
选项,但我在这里使用 grep
、awk
、for
和 while
循环) .
下面是我要解析的内容:
Starting Nmap 7.60 ( https://nmap.org ) at 2017-12-05 11:26 EST
Nmap scan report for house.router.nick (192.168.1.1)
Host is up (0.00059s latency).
Not shown: 995 closed ports
PORT STATE SERVICE
22/tcp open ssh
53/tcp open domain
427/tcp open svrloc
1900/tcp open upnp
MAC Address: 50:C7:BF:A8:CF:C8 (Tp-link Technologies)
Nmap scan report for 192.168.1.2
Host is up (0.00034s latency).
Not shown: 996 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
139/tcp open netbios-ssn
445/tcp open microsoft-ds
MAC Address: 48:F8:B3:C9:AE:BB (Cisco-Linksys)
我想得到的是:
22/ssh
====
192.168.1.1
192.168.1.2
http
===
192.168.1.2
到目前为止,我有这个:
grep -E "tcp.*open" nmap.txt | awk '{ print }' | sort | uniq
对于我的一生,我无法弄清楚如何将其放入各种循环并从上面获得所需的输出。
能否请您帮助我学习并解释您为什么得出您所做的解决方案?如果我无法理解其背后的逻辑,那么获得潜在解决方案毫无意义。
您最好使用通用编程语言(python、perl、awk),您可以在看到 "scan report for" 关键字时捕获 IP 地址,然后维护一个将服务名称映射到 IP 地址列表的数据结构 运行 这些服务。
例如,给定该输出,这个 perl 单行代码(提供但没有解释)
perl -ne '
if (/Nmap scan report for .*?(\d+\.\d+\.\d+\.\d+)/) {
$ip =
}
elsif (/^(\d+)\/tcp\s+open\s+(.*)/) {
push @{$services{"/"}}, $ip
}
END {
for $svc (sort {$a <=> $b} keys %services) {
printf "%s\n%s\n\n", $svc, join("\n", @{$services{$svc}})
}
}
'
生产
22/ssh
192.168.1.1
192.168.1.2
53/domain
192.168.1.1
80/http
192.168.1.2
139/netbios-ssn
192.168.1.2
427/svrloc
192.168.1.1
445/microsoft-ds
192.168.1.2
1900/upnp
192.168.1.1
$ cat tst.awk
BEGIN { FS="[[:space:]/]+" }
/Nmap scan report/ {
ip = $NF
gsub(/[()]/,"",ip)
}
/tcp.*open/ {
key = "/"
ips[key] = (key in ips ? ips[key] ORS : "") ip
}
END {
for (key in ips) {
print key
print "===="
print ips[key]
print ""
}
}
.
$ awk -f tst.awk file
80/http
====
192.168.1.2
1900/upnp
====
192.168.1.1
427/svrloc
====
192.168.1.1
445/microsoft-ds
====
192.168.1.2
53/domain
====
192.168.1.1
22/ssh
====
192.168.1.1
192.168.1.2
139/netbios-ssn
====
192.168.1.2
我认为它的作用非常明显,但如果您在浏览了 awk 手册页后有任何疑问,请随时提问。
以上内容在每个 UNIX 系统上都可以使用任何 shell 中的任何 awk。