Grep the nmap output - linux

I have output my nmap result to a file called test.txt and it looks like this:
Nmap scan report for 192.168.1.5
Host is up (0.13s latency).
PORT STATE SERVICE VERSION
23/tcp open telnet Linux telnetd
--
Nmap scan report for 192.168.1.7
Host is up (0.13s latency).
PORT STATE SERVICE VERSION
80/tcp open http Popper
--
Nmap scan report for 192.168.1.20
Host is up (0.13s latency).
PORT STATE SERVICE VERSION
110/tcp open pop3 Dove
I want to output the results from the file in my terminal using grep and pipe that displays the result in format: IP address followed by the open ports like this:
192.168.10.2
80
223
53
192.168.10.7
80
223

You probably want:
cat test.txt | sed 's/Nmap scan report for //' | sed '/Host is/d' | sed '/Not shown/d' | sed '/All/d' | sed '/PORT /d' | cut -f1 -d"/" | sed '/^$/d' | sed '/--/d'
For nmap -F 192.168.0.1/24 > test.txt:
cat test.txt | tail -n+3 | sed '/Nmap done/d' | awk 'NR>1{print l}{l=$0}' | sed 's/Nmap scan report for //' | sed '/Host is/d' | sed '/Not shown/d' | sed '/All/d' | sed '/PORT /d' | cut -f1 -d"/" | sed '/^$/d'
Joke. It does not make sense... Use nmap with XML Output -oX.
Read: https://nmap.org/book/output-formats-xml-output.html

I'd do the following:
Get a regular expression to match ip's and ports for the nmap output. You can take advantage of the positions of both, i.e ports are at the beginning of the line(^) and end with a '/' character, and ip's are the last item on the line($).
Use grep -o to look for any of that regular expressions (look at the OR operator on the regex (|)). This will reduce the output to just the matches.

Related

Extract IPs from Pcap Which are Matching the String

How can I extract IPs from a PCAP file whose packet has any of these hex strings.
--hex-string '|AF0DFT5F14|'
--hex-string '|AF0DFT5F25|'
--hex-string '|AF0DFT5F45|'
I just need the list of IPs.
I tried to search a lot on web but couldn't get any specific about this. I found out to extract all the IPs from a pcap file using the below command
( tcpdump -n -r m.pcap | grep IP | cut -f 3 "-d " | cut -f1-4 -d.; tcpdump -n -r m.pcap | grep IP | cut -f 5 "-d " | cut -f1-4 -d. ) | sort -u
Grep, awk, anything can do

How to get just the bare IP 4 address from terminal in linux using the new ip command vs ipconfig?

ipconfig does not exist anymore as a command available in Ubuntu 20.04 and later I assume. The new command is just ip. When I run the ip address command I get the entire list of all devices and ip addresses associated. I want just the eth0 device and public ip 4 address associated.
I want just the bare ip address octets only. I want this to work on both Linux and Mac OS.
I found this pipe of cut and sed to work fine to get what I want:
on linux:
ip a | grep eth0 | cut -d " " --fields=6 | sed '2q;d' | awk -F'/' '{print $1}'
on BSD / Darwin / Mac OS:
ip a | grep en0 | tr -s 'inet' ' ' | sed '2q;d' | tr -s '' | awk -F' *? *' '{print $2}' | awk -F '/' '{print $1}'
which results in just the bare ip address I needed. I had to do some trial and error on what field column I actual needed. This probably could be more generalized, but this works for my use case.
Added a public git to just curl and run from anywhere like:
curl -L https://cutt.ly/UUYcT1r | /bin/bash

Parsing nmap -oG output using sed

I have a logfile
...
Host: 111.222.121.123 (111.222.121.123.deploy.static.akamaitechnologies.com) Ports: 80/open/tcp//http//AkamaiGHost (Akamai's HTTP Acceleration|Mirror service)/, 443/open/tcp//ssl|http//AkamaiGHost (Akamai's HTTP Acceleration|Mirror service)/
Host: 1.2.3.4 () Ports: 80/open/tcp//http//cloudflare/, 443/open/tcp//ssl|https//cloudflare/, 2052/open/tcp//clearvisn?///, 2053/open/tcp//ssl|http//nginx/, 2082/open/tcp//infowave?///, 2083/open/tcp//ssl|http//nginx/, 2086/open/tcp//gnunet?///, 2087/open/tcp//ssl|http//nginx/, 2095/open/tcp//nbx-ser?///, 2096/open/tcp//ssl|http//nginx/, 8080/open/tcp//http-proxy//cloudflare/, 8443/open/tcp//ssl|https-alt//cloudflare/, 8880/open/tcp//cddbp-alt?///
Host: 2.3.4.5 (a104-96-1-61.deploy.static.akamaitechnologies.com) Ports: 53/open/tcp//domain//(unknown banner: 29571.61)/
...
I need to extract and convert IPs and http ports to the following format
1.2.3.4:80,443,2083
There are just two types of port fields in the logfile
80/open/tcp//http
2083/open/tcp//ssl|http
Tried to use sed but without success. I ended up with this dysfunctional command
cat ../host_ports.txt | sed -rn 's/Host: ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*?([0-9]{1,5}\/open\/tcp\/\/http|[0-9]{1,5}\/open\/tcp\/\/ssl\|http).*/\1 \2/p'
First handle the repeating ports, and next replace Host/Port to the desired format.
sed -r 's/(Ports:|,) ([0-9]*)[^,]*/\1\2/g;s/Host: ([^ ]*).*Ports:/\1:/' ../host_ports.txt
EDIT:
First I gave all ports of a line with http somewhere, now limit the result to ports with http in its description.
sed -nr 's/Ports: /, /;
s/, ([0-9]*)[^,]*http[^,]*/,\1/g;
s/,[^,]*\/[^,]*//g;
s/Host: ([^ ]*)[^,]*,/\1:/p' ../host_ports.txt
This script will do it for you, and you don't need sed :
#!/bin/bash
while read -r line; do
if echo $line | grep -q "http"; then
host=$(echo "$line" | grep -Po '(?<=^Host: )[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
ports=$(echo "$line" | grep -Po '[0-9]*((?=\/open\/tcp\/\/http)|(?=\/open\/tcp\/\/ssl\|http))' | tr '\n' ',')
echo "$host:${ports:0:-1}"
fi
done < ../log
The first grep will catch the IP address, with the help of Look behind. the -P is to use perl like regex, and the -o is to output only the matching string
The second regex is much like the first, but uses look after instead of look behind. It will only capture ports which are followed by /open/tcp//http or /open/tcp//ssl|http. The tr right after will replace newlines with commas.
the ${ports:0:-1} is just to eliminate the trailing comma.
Hope this helps!

Only get the first part of grep: get ip of ifconfig

ifconfig | grep -m1 "inet addr"
Gives me
inet addr:172.30.1.6 Bcast:172.30.140.255 Mask:255.255.252.0
However, I only want the ip, which is 172.30.1.6. How can I do this?
Note that I have to be using ifconfig, as this is an embedded system with limited functionalities.
Get out your scissors, it's cuttin' time.
echo inet addr:172.30.1.6 Bcast:172.30.140.255 Mask:255.255.252.0 | cut -d : -f 2 | cut -d " " -f 1
One way to do it ..
ifconfig | grep -m1 "inet addr" | awk '{print $2}' | awk -F: '{print $2}'
If all you want to do is obtain the ip address, there might be easier ways of achieving that using say hostname -i ( reference Which terminal command to get just IP address and nothing else? )
Since others have mentioned cut and awk, I will provide a solution using sed :
echo "inet addr:172.30.1.6 Bcast:172.30.140.255 Mask:255.255.252.0" | sed -e "s/.*\(addr:[^ ]*\) .*/\1/"
addr:172.30.1.6
echo "inet addr:172.30.1.6 Bcast:172.30.140.255 Mask:255.255.252.0" | sed -e "s/.*addr:\([^ ]*\) .*/\1/"
172.30.1.6
Use cut with a delimiter
| cut -d':' -f 2 | cut -d' ' -f 1
Is this all you're trying to do?
awk -F'[: ]' '/inet addr/{print $3; exit}'
For example using cat file in place of ifconfig:
$ cat file
inet addr:172.30.1.6 Bcast:172.30.140.255 Mask:255.255.252.0
$ cat file | awk -F'[: ]' '/inet addr/{print $3; exit}'
172.30.1.6
Here's a way to do it with a single sed command, eliminating the call to grep:
ifconfig | sed -n '/inet addr/{s/^.*inet addr:\([^ ]*\).*$/\1/p;q}'
There are a few things going on here:
sed -n tells sed not to print every line like it normally does
/inet addr/ is a sed address - it tells sed to only operate on lines containing "inet addr"
The { and } brackets define a block of commands to be run, with the commands separated by a ;
The s command is fairly straightforward - it just captures the IP and replaces the whole line with just the IP
The p flag at the end of the s command tells sed to print the result of the substitution. This is necessary because we called sed with the -n option.
The q command tells sed to quit, so that it only processes the first line containing "inet addr".
Using the -n option, the /inet addr/ address, the p flag on the s command, and the q command, essentially has the same effect as grep -m1 "inet addr", which makes calling grep unnecessary. In fact, it's worth noting that the following commands produce identical output:
> ifconfig | grep -m1 "inet addr"
inet addr:192.168.1.1 Bcast:192.168.2.255 Mask:255.255.255.0
> ifconfig | sed -n '/inet addr/{p;q}'
inet addr:192.168.1.1 Bcast:192.168.2.255 Mask:255.255.255.0
Here, I've omitted the s/pattern/replacement/p part of the sed command, and replaced it with a p command (which just prints the whole line), just to show the effect of the other parts in isolation.
Just use the command cut.
ip a | grep -m1 "inet addr" | cut -d':' -f 2 | cut -d' ' -f 1
I also advise you to learn the use of other commands such as : wc,sed,tr,sort,uniq. They will help manipulate the output as you please. Here is a small lesson where we present you all these command : https://www.javatpoint.com/linux-filters
I hope to help you.
Using Bash's regex operator =~:
$ [[ $(ifconfig | grep -m1 "inet addr") =~ [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ ]] && echo ${BASH_REMATCH[0]}
172.30.1.6
Update: Something even better in the comments.

Find network interface by IP address - Linux/Bash

I'm wondering how I can query by IP address using sed, and it will show which interface name that is using it.
For example..
ipconfig -a | grep 10.0.0.10
I would expect it to come back with ETH0
ifconfig | grep -B1 10.0.0.10 | grep -o "^\w*"
You should use this comand :
ifconfig | grep -B1 "inet addr:10.0.0.10" | awk '$1!="inet" && $1!="--" {print $1}'
Hope this help !
ip -br -4 a sh | grep 10.0.0.10 | awk '{print $1}'
If you want sed specific solution you may try this. Its little hard to digest how it works , but finally this combination works.
ifconfig | sed -n '/addr:10.0.0.10/{g;H;p};H;x' | awk '{print $1}'
If you want to take it as an argument via script use "$1" or so instead if 10.0.0.10.
Sed manual for reference : http://www.gnu.org/software/sed/manual/sed.html#tail

Resources