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

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

Related

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

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.

Extract IP address from /etc/hosts file with SED command

I would like to extract the IP v4 address only from my /etc/hosts file with shell sed command.
I managed to isolate those line with localhost at the end of the line with the following command:
$ sed -E '/localhost$/!d ' host_1 | sed -n 1p
which gave me the following output :
# 127.0.0.1 localhost
How can I only extract the IP v4 address alone form the above result?
The test data:
$ cat file
127.0.0.1 localhost
# 127.0.0.2 localhost
127 127.0.0.3 localhost
The sed:
$ sed -n 's/\(.*[^0-9]\|\)\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\).*/\2/p' file
The output:
127.0.0.1
127.0.0.2
127.0.0.3
The sed with the -E switch:
$ sed -nE 's/(.*[^0-9]|)([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*/\2/p' file
I tried this command and it works fine.
$ sed -E '/localhost$/!d' host_1 | sed -n 1p |grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"
output: 127.0.0.1
Nonetheless I am still curious about how can I substitute the grep by a sed command.
sed -E '/localhost$/!d ' /etc/hosts | awk '{print $1}' | grep -v :
Late but you can try this :
sed -E '/localhost$/!d ' host_1 | sed -n 1p | sed -r 's/\localhost//g'
The last part replaces the grep used by 4everLRG
If you need to extract localhost IP from /etc/hosts make sure to replace host_1 with /etc/hosts

netcat to return the result of a command (run when connection happens)

I want to use netcat to return the result of a command on a server. BUT here is the trick, I want the command to run when the connection is made. Not when I start the netcat.
Here is a simplified single shell example. I want the ls to run when I connect to 1234 (which I would normally do from a remote server, obviously this example is pointless I could do an ls locally)
max $ ls | nc -l 1234 &
[1] 36685
max $ touch file
max $ nc 0 1234
[1]+ Done ls | nc -l 1234
max $ ls | nc -l 1234 &
[1] 36699
max $ rm file
max $ nc 0 1234
file
[1]+ Done ls | nc -l 1234
You can see the ls runs when I start the listener, not when I connect to it. So in the first instance I had no file when I started it and created the file, then made the connection and it reported the state of the filesystem when the listen command started (empty), not the current state. And the second time around when file was already gone it showed it as still present.
Something similar to the way it works when you redirect from a file. eg:
max $ touch file
max $ nc -l 1234 < file &
[1] 36768
max $ echo content > file
max $ nc 0 1234
content
[1]+ Done nc -l 1234 < file
The remote connection gets the latest content of the file, not the content when the listen command started.
I tried using the "file redirect" style with a subshell and that doesn't work either.
max $ nc -l 1234 < <(cat file) &
[1] 36791
max $ echo bar > file
max $ nc 0 1234
content
[1]+ Done nc -l 1234 < <(cat file)
The only thing I can think of is adding my command |netcat to xinetd.conf/systemd... I was probably going to have to add it to systemd as a service anyway.
(Actual thing I want to do : provide the list of users of the VPN to a network port for a remote service to get a current user list. My command to generate the list looks like :
awk '/Bytes/,/ROUTING/' /etc/openvpn/openvpn-status.log | cut -f1 -d. | tail -n +2 | tac | tail -n +2 | sort -b | join -o 2.2 -j1 - <(sort -k1b,1 /etc/openvpn/generate-new-certs.sh)
)
I think you want something like this, which I actually did with socat:
# Listen on port 65500 and exec '/bin/date' when a connection is received
socat -d -d -d TCP-LISTEN:65500 EXEC:/bin/date
Then in another Terminal, a few seconds later:
echo Hi | nc localhost 65500
Note: For macOS users, you can install socat with homebrew using:
brew install socat

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

Bash broken pipe with tcpdump

I use the following command to send pinging IP's to a script:
sudo tcpdump -ne -l -i eth0 icmp and icmp[icmptype]=icmp-echo \
| cut -d " " -f 10 | xargs -L2 ./pong.sh
Unfortunately this gives me:
tcpdump: Unable to write output: Broken pipe
To dissect my commands:
Output the ping's from the traffic:
sudo tcpdump -ne -l -i eth0 icmp and icmp[icmptype]=icmp-echo
Output:
11:55:58.812177 IP xxxxxxx > 127.0.0.1: ICMP echo request, id 50776, seq 761, length 64
This will get the IP's from the tcpdump output:
cut -d " " -f 10 # output: 127.0.0.1
Get the output to the script:
xargs -L2 ./pong.sh
This will mimic the following example command:
./pong.sh 127.0.0.1
The strange thing is that the commands work seperate (on their own)...
I tried debugging it but I have no experience with debugging pipes. I checked the commands but they seem fine.
It would seem that's cut stdio buffering is interfering here, i.e. replace | xargs ... by | cat in your cmdline to find out.
Fwiw below cmdline wfm (pipe straight to xargs then use the shell itself to get the nth arg), note btw the extra tcpdump args : -c10 (just to limit to 10pkts, then show the 10/2 lines) and -Q in (only inbound pkts):
$ sudo tcpdump -c 10 -Q in -ne -l -i eth0 icmp and icmp[icmptype]=icmp-echo 2>/dev/null | \
xargs -L2 sh -c 'echo -n "$9: "; ping -nqc1 $9 | grep rtt'
192.168.100.132: rtt min/avg/max/mdev = 3.743/3.743/3.743/0.000 ms
192.168.100.132: rtt min/avg/max/mdev = 5.863/5.863/5.863/0.000 ms
192.168.100.132: rtt min/avg/max/mdev = 6.167/6.167/6.167/0.000 ms
192.168.100.132: rtt min/avg/max/mdev = 4.256/4.256/4.256/0.000 ms
192.168.100.132: rtt min/avg/max/mdev = 1.545/1.545/1.545/0.000 ms
$ _
For those coming across this (like me), tcpdump buffering is the issue.
From the man page:
-l Make stdout line buffered. Useful if you want to see the data
while capturing it. For example:
# tcpdump -l | tee dat
or
# tcpdump -l > dat & tail -f dat

Resources