I wrote the following script which goes through the Nmap's output and then parses ports grouped as TCP/UDP:
#!/bin/bash
TC=0; #TCP Count
UC=0; #UDP Count
if [ $# -eq 1 ];then
cat $1 | gawk '/[0-9]+\/(tcp|udp)/{ match($1,/([0-9]+)\/(tcp|udp)/,arr); \
if ( arr[2] == 'tcp') {
if ( arr[1] in T == 0){ \
print "Insert ",arr[1]," to T"; \
T[TC]=arr[1];
TC++;
}
}
else if ( arr[2] == 'udp' && (arr[1] in U == 0)){ \
print "Insert ",arr[1]," to U";
U[UC]=arr[1];
UC++;
}
}
END{
print "U:"
for (i in U){print U[i]}
print "T:"
for (j in T){print T[i]}
}'
else
echo 'nmap2ports <NMAP output File>'
fi
The if condition statements in awk are never executing neither for TCP nor for UDP. All I was trying is if the port is TCP (or UDP) and not present in the TCP (or UDP) array, then Insert, and print the array at the end. Thus output would be like [Expected Output]
U:
631
5353
17946
20031
T:
22
80
But insertion is never taking place. What I have tried so far:
if (! arr[1] in T)
if ( arr[1] not in T)
if ( arr[1] in T == 0)
Sample Input file:
Nmap scan report for xx.xx.xx.xx
Host is up (0.47s latency).
Not shown: 1995 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
631/udp open|filtered ipp
5353/udp open|filtered zeroconf
17946/udp open|filtered unknown
MAC Address: 00:50:56:87:9A:10 (VMware)
Aggressive OS guesses: Linux 3.12 (95%), Linux 3.13 (95%), Linux 3.16 (95%), Linux 3.2 - 4.9 (95%), Linux 4.4 (95%), Linux 4.8 (95%), Linux 4.9 (95%), Linux 3.18 (95%), Linux 3.8 - 3.11 (95%), Linux 4.2 (95%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Nmap scan report for xx.xx.xx.xx
Host is up (0.47s latency).
Not shown: 1996 closed ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
631/udp open|filtered ipp
5353/udp open|filtered zeroconf
20031/udp open|filtered bakbonenetvault
MAC Address: 00:50:56:87:E4:54 (VMware)
Aggressive OS guesses: Linux 3.13 (95%), Linux 3.16 (95%), Linux 3.2 - 4.9 (95%), Linux 4.2 (95%), Linux 3.18 (95%), Linux 4.8 (95%), ASUS RT-N56U WAP (Linux 3.4) (95%), Linux 4.9 (95%), Linux 3.12 (94%), Linux 3.8 - 3.11 (94%)
No exact OS matches for host (test conditions non-ideal).
[Current output]
U:
T:
Could you please try following.
awk '
/^[0-9]+\/tcp/{
sub(/\/.*/,"",$1)
if(!tcpVal[$1]++){ a="" }
}
/^[0-9]+\/udp/{
sub(/\/.*/,"",$1)
if(!udpVal[$1]++){ a="" }
}
END{
print "U:"
for(i in udpVal) { print i }
print "T:"
for(j in tcpVal) { print j }
}' Input_file
Explanation: Adding detailed explanation for above.
awk ' ##Starting awk program from here.
/^[0-9]+\/tcp/{ ##Checking condition if line starts from digits then / and tcp then do following.
sub(/\/.*/,"",$1) ##Substituting from / till everything will NULL in 1st field.
if(!tcpVal[$1]++){ a="" } ##Checking condition if $1 is NOT present in tcpVal array then place
##it as an index in it and as a placeholder mentioning a to NULL.
}
/^[0-9]+\/udp/{ ##Checking condition if line starts from digits / udp then do following.
sub(/\/.*/,"",$1) ##Substituting everything from / till last of line with NULL in $1.
if(!udpVal[$1]++){ a="" } ##Checking condition if $1 is NOT present in udpVal array then place
##it as an index in it and as a placeholder mentioning a to NULL.
}
END{ ##Starting END block of this specific awk program.
print "U:" ##Printing U: here as per requested output.
for(i in udpVal) { print i } ##Traversing through array udpVal and printing index value(i).
print "T:" ##Printing T: here as per requested output.
for(j in tcpVal) { print j } ##Traversing through array tcpVal and printing index value(i).
}' Input_file ##Mentioning Input_file name here.