Bash while loop script that runs Nmap with iterating IP and port number - bash

Summary: I'm trying to create a Bash script that selects an IP address and it's associated open ports, then run each IP through Nmap and display/store the results.
The format of the ports file (portsList):
192.168.1.1 53 udp
192.168.1.1 80 tcp
192.168.1.1 1900 tcp
192.168.1.110 135 tcp
192.168.1.115 1080 tcp
The format of the IP file (ipList):
192.168.1.1
192.168.1.110
192.168.1.115
My Bash script:
#!/bin/bash
portsvar="$(cat formattedPorts)"
hostvar="$(cat oneHost)"
while read -r line;
do
echo "$line" > oneHost
grep -wf oneHost portsList | awk '{print $2}' | tr '\n' ',' > formattedPorts
nmap -n -sV -p"$portsvar" "$hostvar" >> scanResults
cat scanResults
done < ipList
I spent several hours, trying multiple variations of this code and tried to find a solution online. But to no avail. The most this script can do is scan and output for the first selected IP and ports.
Additional considerations would be; if a port is UDP, to append 'U:' on the ports option. Also, if there is a way to display the output of Nmap scanning, while it is being redirected '>>' to a file.
Bash is what I'm most familiar with, but I'm open to learning a solution in a different language.
Edit
I tried jhnc's solution below by replacing:
echo "$line" > oneHost
grep -wf oneHost portsList | awk '{print $2}' | tr '\n' ',' > formattedPorts
nmap -n -sV -p"$portsvar" "$hostvar" >> scanResults
cat scanResults
with jhnc's code in the comment below. the resulting output was:
nmap -n -sV -p T:135 192.168.1.110
nmap -n -sV -p T:5985 192.168.1.112
nmap -n -sV -p T:54112,T:60000,T:8009,T:8888 192.168.1.131
nmap -n -sV -p T:5040 192.168.1.132
nmap -n -sV -p T:1041,T:1900,T:20005,T:33344,T:49152,T:49153,T:80 192.168.1.1
This output was echo'ed onto the terminal 5 times. From this I'll try to find a solution to have the input of this group of IP's ran once.

Related

try to save nmap result to txt file

I try to save results from nmap scan to a txt file. I use this command
nmap -n -Pn -p T:3389 -T5 -sS -iR 0 | grep "scan" | awk '{ print $5 }' > test.txt
cat test.txt
the output looks like this :
xx.xx.xx.xx
xx.xx.xx.xx
xx.xx.xx.xx
xx.xx.xx.xx
xx.xx.xx.xx
xx.xx.xx.xx
It is working perfectly.
I want to scan only for open ports, and for this I try to use the --open option like this :
nmap -n -Pn -p T:3389 --open -T5 -sS -iR 0 | grep "scan" | awk '{ print $5 }' > test.txt
It does not work, the test.txt is empty. I try to use tail -f test.txt to see live results, but it's not working. Can someone explain what I'm doing, wrong?
I was expecting to see the result as the first time.
xx.xx.xx.xx
xx.xx.xx.xx
xx.xx.xx.xx
xx.xx.xx.xx
xx.xx.xx.xx
xx.xx.xx.xx
after I want to add the port number after all ip like this
xx.xx.xx.xx:3389
xx.xx.xx.xx:3389
xx.xx.xx.xx:3389
xx.xx.xx.xx:3389
xx.xx.xx.xx:3389
xx.xx.xx.xx:3389
and for that I want to use sed -i s/$/:3389/ test.txt
I wonder if it is possible to get this result with only one command.
I try something like this :
nmap -n -Pn -p T:3389 --open -T5 -sS 192.168.0.1/24 | grep "scan" | awk '{ print $5 }' > test.txt; sed -i s/$/:3389/ test.txt
cat test.txt and this is the result :
192.168.0.2:3389
192.168.0.16:3389
addresses:3389
I do not know why addresses:3389 appear at the end. But this works.
I want to get the same result but whit this command :
nmap -n -Pn -p T:3389 --open -T5 -sS -iR 0 | grep "scan" | awk '{ print $5 }' > test.txt; sed -i s/$/:3389/ test.txt
I try this command but not working. I want to use this command in a bash script. any help or suggestion is appreciated.
nmap -n -Pn -p T:3389 --open -T5 -sS -iR 0
This is the output:
Nmap scan report for 187.3.104.223
Host is up (0.29s latency).
PORT STATE SERVICE
3389/tcp open ms-wbt-server
Nmap scan report for 118.89.215.203
Host is up (0.29s latency).
PORT STATE SERVICE
3389/tcp open ms-wbt-server
I found a way to make it work. This is the command :
nmap -n -Pn -p T:3389 -T5 -sS -iR 5000 --open | grep scan | grep -v addresses | awk '{print $5}' | sed 's/$/:3389/' > test
cat test
The output:
35.190.27.36:3389
35.214.139.176:3389
132.190.70.226:3389
109.228.13.61:3389
103.10.175.4:3389
113.134.99.14:3389
35.168.9.215:3389
167.93.112.130:3389
115.220.6.216:3389
137.32.209.1:3389
35.206.198.136:3389
I can change the -iR 5000 if i need it, and it still works. It doesn't work with 0
I hope to be helpful if someone need it. Thank you all
The "addresses" is from the summary ending line of the Nmap output, 5th word:
Nmap done: 256 IP addresses (10 hosts up) scanned in 3.12 seconds
To remove the addresses from the output run:
nmap -n -Pn -p T:3389 --open -T5 -sS -iR 0 |grep scan|grep -v addresses|awk '{print $5}' | sed 's/$/:3389/' > test.txt
Post your output if it's not what you expected / wanted to get

Append output of grep filter to a file

I am trying to save the output of a grep filter to a file.
I want to run tcpdump for a long time, and filter a certain IP to a file.
tcpdump -i eth0 -n -s 0 port 5060 -vvv | grep "A.B.C."
This works fine. It shows me IP's from my network.
But when I add >> file.dump at the end, the file is always empty.
My script:
tcpdump -i eth0 -n -s 0 port 5060 -vvv | grep "A.B.C." >> file.dump
And yes, it must be grep. I don't want to use tcpdump filters because it gives me millions of lines and with grep I get only one line per IP.
How can I redirect (append) the full output of the grep command to a file?
The output of tcpdump is probably going through stderr, not stdout. This means that grep won't catch it unless you convert it into stdout.
To do this you can use |&:
tcpdump -i eth0 -n -s 0 port 5060 -vvv |& grep "A.B.C."
Then, it may happen that the output is a continuous stream, so that you somehow have to tell grep to use line buffering. For this you have the option --line-buffered option.
All together, say:
tcpdump ... |& grep --line-buffered "A.B.C" >> file.dump

use tcpkill command from an ip list

I have got an ip list in a file called ips:
ip1
ip2
I want to tcpkill from this list. I cannot do it from tcpkill command options. I need a script which will write :
tcpkill -i eth0 -9 host ip1 or host ip2
the list can grow in time.
the only thing I know is that I will need a loop to read the list:
for IP in $(cat list) ; do
echo "tcpkill -i eth0 -9 host $IP " (for
the first element of the list)
echo "or host $IP" (for the rest of
the list).
So my questions are:
1. what would be the right syntax for this purpose?
2. Is there a completely different way of doing this?
Any idea folks ?!
thank you very much.
This single line command would append the IP list to tcpkill command to form the complete command:
tcpkill -i eth0 -9 host $(cat list | xargs | sed 's/ / or host /g')
You can put this command after echo to see how the command gets formed.
echo tcpkill -i eth0 -9 host $(cat list | xargs | sed 's/ / or host /g')

tcpdump: Output only source and destination addresses

Problem description:
I want to print only the source and destination address from a tcpdump[1].
Have one working solution, but believe it could be improved a lot. An example that captures 5 packets, just as an example of what I'm looking for:
tcpdump -i eth1 -n -c 5 ip | \
cut -d" " -f3,5 | \
sed -e 's/^\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)\..* \([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\).*$/\1 > \2/'
Question:
Can this be done in any easier way? Performance is also an issue here.
[1] A part of a test if the snort home_net is correctly defined, or if we see traffic not defined in the home_net.
Solution:
Ok, thanks to everyone who have replied to this one. There have been two concerns related to the answers, one is the compatibility across different linux-versions and the second one is speed.
Here is the results on the speed test I did. First the grep-version:
time tcpdump -l -r test.dmp -n ip 2>/dev/null | grep -P -o '([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*? > ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)' | grep -P -o '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | xargs -n 2 echo >/dev/null
real 0m5.625s
user 0m0.513s
sys 0m4.305s
Then the sed-version:
time tcpdump -n -r test.dmp ip | sed -une 's/^.* \(\([0-9]\{1,3\}\.\?\)\{4\}\)\..* \(\([0-9]\{1,3\}\.\?\)\{4\}\)\..*$/\1 > \3/p' >/dev/null
reading from file test.dmp, link-type EN10MB (Ethernet)
real 0m0.491s
user 0m0.496s
sys 0m0.020s
And the fastest one, the awk-version:
time tcpdump -l -r test.dmp -n ip | awk '{ print gensub(/(.*)\..*/,"\\1","g",$3), $4, gensub(/(.*)\..*/,"\\1","g",$5) }' >/dev/null
reading from file test.dmp, link-type EN10MB (Ethernet)
real 0m0.093s
user 0m0.111s
sys 0m0.013s
Unfortunately I have not been able to test how compatible they are, but the awk needs gnu awk to work due to the gensub function. Anyway, all three solutions works on the two platforms I have tested them on. :)
Here's one way using GNU awk:
tcpdump -i eth1 -n -c 5 ip | awk '{ print gensub(/(.*)\..*/,"\\1","g",$3), $4, gensub(/(.*)\..*/,"\\1","g",$5) }'
Try this:
tcpdump -i eth1 -n -c 5 ip 2>/dev/null | sed -r 's/.* ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).* > ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*/\1 > \2/'
If running from a .sh script, remember to escape \1 & \2 as required.
Warning You have to use unbuffered ou line-buffered output to monitor the output of another command like tcpdump.
But you command seem correct.
To simplify, you could:
tcpdump -i eth1 -n -c 5 ip |
sed -une 's/^.* \(\([0-9]\{1,3\}\.\?\)\{4\}\)\..* \(\([0-9]\{1,3\}\.\?\)\{4\}\)\..*$/\1 > \3/p'
Notice the u switch usefull without -c 5 at tcpdump
tcpdump -ni eth1 ip |
sed -une 's/^.* \(\([0-9]\{1,3\}\.\?\)\{4\}\)\..* \(\([0-9]\{1,3\}\.\?\)\{4\}\)\..*$/\1 > \3/p'
& here is a grep only solution:
tcpdump -l -i eth1 -n -c 5 ip 2>/dev/null | grep -P -o '([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*? > ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)' | grep -P -o '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | xargs -n 2 echo
Note -l, in case you don't want to limit the number of packets using -c.

How to write bash script to search for IP's in a file and put write them to another file?

I need to write a bash script that will take a grepable nmap output file that displays IP addresses with port 80 open and copy the IPs that have port 80 open to another text file. The output looks similar to this:
# Nmap 4.76 scan initiated Thu Dec 3 13:36:29 2009 as: nmap -iL ip.txt -p 80 -r -R -PN --open -oA output
Host: 192.168.1.100 () Status: Up
Host: 192.168.1.100 () Ports: 80/open/tcp//http///
Host: 192.168.1.100 () Status: Up
# Nmap done at Thu Dec 3 13:36:29 2009 -- 3 IP addresses (3 hosts up) scanned in 0.28 seconds
I am fairly new to bash scripting so I am not sure where to start with this. If you can help me with this script it would be much appreciated.
this can be reduced to an awk call:
awk '/80\/open/{print $2}' infile > iplist_port_80
Use grep and sed/awk
grep -e '80/open/tcp' infile | awk '{print $2}' | sort -u > outfile
would be my first attempt.
not being familiar with nmap invocation and output format, but still, this should work:
nmap | grep -e 'Ports:.80\/' |sed 's/Host:.//;s/.(.*//'|sort -u > out

Resources