iptable Bad argument `ACCEPT' - bash

I am trygin the following..
#!/bin/bash
NOIPHOST=example.noip.me
LOGFILE=iptables_update.log
Current_IP=$(host $NOIPHOST | cut -f4 -d' ')
if [ $LOGFILE = "" ] ; then
/sbin/iptables -I INPUT -m tcp -p tcp -s $Current_IP -j ACCEPT
echo $Current_IP > $LOGFILE
else
Last_IP=$(cat $LOGFILE)
if [ "$Current_IP" = "$Last_IP" ] ; then
echo IP address has not changed
else
/sbin/iptables -D INPUT -m tcp -p tcp -s $Last_IP -j ACCEPT
/sbin/iptables -I INPUT -m tcp -p tcp -s $Current_IP -j ACCEPT
iptables-persistent save
echo $Current_IP > $LOGFILE
echo iptables have been updated
fi
fi
I am getting this error..
Bad argument ACCEPT' Tryiptables -h' or 'iptables --help' for more
information. iptables have been updated
I have also tried using these..
iptables -D INPUT -m tcp -p tcp -s $Last_IP -j ACCEPT
iptables -I INPUT -m tcp -p tcp -s $Current_IP -j ACCEPT
but still same error.
Anyway to fix this?

Are you sure you don't have any newlines in your $Last_IP variable?
Can you try adding the following before your iptables -D... line?
Last_IP=$(echo $Last_IP|tr -d '\n')

Related

netcat - How do I synchronize my portscan and port listen scripts and how do i export all output to a .txt file?

My goal is to have a port listen script on Host A which listens on predefined ports using netcat.
While this script listens, the port scan script is running on Host B and checks if the ports on Host A or open or not.
The output of the scan script needs to be directed to a separate .txt file and must include all information from the nc -zvv output.
The listen script looks like this:
#!/bin/bash
# Define the four arrays of ports to listen on
ports_1st=(20 21 22 80 443)
ports_2nd=(2000 2001 2002 2003)
ports_3rd=(3000 3001 3002 3003)
ports_4th=(4000 4001 4002 4003)
# Sleep to allow the scan script to start and bind to all ports
echo "Start PortScan.sh as soon as port listen starts!"
sleep 5
echo -e "\n"
echo -e "\n"
# Countdown timer
echo "Start the port scan in:"
for i in 5 4 3 2 1; do
echo "$i..."
sleep 1
done
# Loop through each array of ports and use nc to listen on each port
echo "Listening on 1st ports..."
for ports in ports_1st; do
for port in "${!ports[#]}"; do
nc -l -k -p $port &
done
done
echo -e "\n"
echo "Listening on 1st ports completed"
echo -e "\n"
echo -e "\n"
echo "Listening on 2nd ports..."
for ports in ports_2nd; do
for port in "${!ports[#]}"; do
nc -l -k -p $port &
done
done
echo -e "\n"
echo "Listening on 2nd ports completed"
echo -e "\n"
echo -e "\n"
echo "Listening on 3rd ports..."
for ports in ports_3rd; do
for port in "${!ports[#]}"; do
nc -l -k -p $port &
done
done
echo -e "\n"
echo "Listening on 3rd ports completed"
echo -e "\n"
echo -e "\n"
echo "Listening on 4th ports..."
for ports in ports_4th; do
for port in "${!ports[#]}"; do
nc -l -k -p $port &
done
done
echo -e "\n"
echo "Listening on 4th ports completed"
echo -e "\n"
echo -e "\n"
# Wait for all background nc processes to complete
wait
echo "Portscan has been completed"
echo -e "\n"
echo -e "\n"
And the scanscript looks like this:
#!/bin/bash
# Define the range of ports to scan
ports_1st=(20 21 22 80 443)
ports_2nd=(2000 2001 2002 2003)
ports_3rd=(3000 3001 3002 3003)
ports_4th=(4000 4001 4002 4003)
# Define the IP of the target host
echo "Please enter the server IP of the target host!"
read target_host
echo -e "\n"
echo -e "\n"
# Define current date variable
current_date=$(date +"%Y-%m-%d")
# Loop through the range of ports and use nc to test for a response
echo "Scanning 1st ports..."
for ports in ports_1st; do
for port in "${ports[#]}"; do
nc -zvv -w 1 $target_host $port 2>&1 | tee -a Portscan_$current_date.txt
if [ $? -eq 0 ]; then
echo "Port $port is open" | tee -a Portscan_$current_date.txt
else
echo "Port $port is closed or connection timed out" | tee -a Portscan_$current_date.txt
fi
done
echo "1st port scan completed" | tee -a Portscan_$current_date.txt
echo -e "\n"
echo -e "\n"
echo "Scanning 2nd ports..."
for ports in ports_2nd; do
for port in "${ports[#]}"; do
nc -zvv -w 1 $target_host $port 2>&1 | tee -a Portscan_$current_date.txt
if [ $? -eq 0 ]; then
echo "Port $port is open" | tee -a Portscan_$current_date.txt
else
echo "Port $port is closed or connection timed out" | tee -a Portscan_$current_date.txt
fi
done
echo "2nd scan completed" | tee -a Portscan_$current_date.txt
echo -e "\n"
echo -e "\n"
echo "Scanning 3rd ports..."
for ports in ports_3rd; do
for port in "${ports[#]}"; do
nc -zvv -w 1 $target_host $port 2>&1 | tee -a Portscan_$current_date.txt
if [ $? -eq 0 ]; then
echo "Port $port is open" | tee -a Portscan_$current_date.txt
else
echo "Port $port is closed or connection timed out" | tee -a Portscan_$current_date.txt
fi
done
echo "3rd port scan completed" | tee -a Portscan_$current_date.txt
echo -e "\n"
echo -e "\n"
echo "Scanning 4th ports..."
for ports in ports_4th; do
for port in "${ports[#]}"; do
nc -zvv -w 1 $target_host $port 2>&1 | tee -a Portscan_$current_date.txt
if [ $? -eq 0 ]; then
echo "Port $port is open" | tee -a Portscan_$current_date.txt
else
echo "Port $port is closed or connection timed out" | tee -a Portscan_$current_date.txt
fi
done
echo "4th port scan completed" | tee -a Portscan_$current_date.txt
echo -e "\n"
echo -e "\n"
done
done
done
done
The problem is that the listen script seems to end instantly instead of waiting for all ports to be scanned and the portscan script does not put the proper output to the .txt file.
Do you have any ideas on how to fix this?
Side notes:
Netcat is mandatory to be used.
I am expecting to loop through each port mentioned in the listen script as well as in the scan script.
The scan script is supposed to prompt if the port is open or closed/timeout in a .txt file.

Extracting specific nmap output in bash

I'm getting following nmap output from a scan:
PORT STATE SERVICE
113/tcp closed ident
443/tcp open https
5060/tcp open sip
I want to extract only open ports and save them into a variable while my script progress is below:
#!/bin/bash
echo Please enter your IP/domain address for nmap vulnerability scanning:
read IP
echo Your results against $ip will be output in sometime
nmap -sS -oG output.txt $ip
Grep them
nmap -sS -oG output.txt $ip | grep open
To store in var
open_ports=$(nmap -sS -oG output.txt $ip | grep open)
open_ports=${open_ports//[^0-9]/ } # remove text
Convert to an array
open_ports_arr=( $open_ports )
Here is how you can filter and extract open ports using awk and read the results into a bash array:
#!/usr/bin/env bash
# Read prompt ip address
read \
-p 'Please enter your IP/domain address for nmap vulnerability scanning: ' \
-r ip
# Print format info to user
printf 'Your results against %s will be output in sometime.\n' "$ip"
# Read the output of the nmap | awk commands into the ports array
IFS=$'\n' read -r -d '' -a ports < <(
# Pipe the result of nmap to awk for processing
nmap -sS -oG output.txt "$ip" |
awk -F'/' '
/[[:space:]]+open[[:space:]]+/{
p[$1]++
}
END{
for (k in p)
print k
}'
)
# If the resulting pors array is not empty iterate print format its content
if [ ${#ports[#]} -gt 0 ]; then
printf 'List of open ports on host IP: %s\n' "$ip"
for p in "${ports[#]}"; do
printf '%d\n' "$p"
done
fi

How to properly format an 'if' statement being passed to a remote server in a when using 'while read'?

Ubuntu 18
Bash 4.4.0
I am wanting to pass an if statement to see whether or not a directory exist. If it does, I want to some commands and then a file. I have read through the similar posts but shellcheck complains about my formatting.
Script:
#!/bin/bash
testing="yes"
scriptDir="/root/.work"
wDir="${scriptDir}/.nginx-fix"
if [ "$testing" = "no" ]; then
hostfile="${scriptDir}/.zzz-hostnames"
else
hostfile="${scriptDir}/.zzz-hostnames-tester"
fi
cd "$wDir"
while read fqdn; do
{ clear; echo ""; echo ""; echo "$hostname"; echo ""; }
< /dev/null if ssh -p 34499 root#"${fqdn}" '[ -d /etc/nginx ]'; then
< /dev/null ssh -p 34499 root#"${fqdn}" 'mv /etc/nginx/nginx.conf /etc/nginx/.nginx-sept-30'
< /dev/null scp -P 34499 nginx.conf root#"${fqdn}":/etc/nginx
< /dev/null ssh -p 34499 root#"${fqdn}" 'sed -i "/honeypot/d" /etc/nginx/conf.d/*.conf'
< /dev/null ssh -p 34499 root#"${fqdn}" 'nginx -t'
else
exit 1;
fi
done<"${hostfile}"
Shellcheck complaint:
root#me ~/.work/.nginx-fix # shellcheck .nginx-fixer.sh
In .nginx-fixer.sh line 13:
while read fqdn; do
^-- SC1073: Couldn't parse this while loop.
^-- SC1061: Couldn't find 'done' for this 'do'.
In .nginx-fixer.sh line 15:
< /dev/null if ssh -p 33899 root#"${fqdn}" '[ -d /etc/nginx ]'; then
^-- SC1062: Expected 'done' matching previously mentioned 'do'.
^-- SC1072: Expected "#". Fix any mentioned problems and try again.
I'd appreciate your thoughts.
You can refactor the script to a clearer version and remove all the </dev/null:
while read -r fqdn; do {
{ clear; echo ""; echo ""; echo "$hostname"; echo ""; }
if ssh -p 34499 root#"${fqdn}" '[ -d /etc/nginx ]'; then
ssh -p 34499 root#"${fqdn}" 'mv /etc/nginx/nginx.conf /etc/nginx/.nginx-sept-30'
scp -P 34499 nginx.conf root#"${fqdn}":/etc/nginx
ssh -p 34499 root#"${fqdn}" 'sed -i "/honeypot/d" /etc/nginx/conf.d/*.conf'
ssh -p 34499 root#"${fqdn}" 'nginx -t'
else
exit 1;
fi
} </dev/null; done < "${hostfile}"
Almost invisible to the eye, I have put all the commands inside do ... done inside { .. } </dev/null. That way any command won't read from ${hostfile} and won't mess with while read.
Another option is to use a dedicated file descriptor and pass its number to read:
while read -r -u 10 fqdn; do
{ clear; echo ""; echo ""; echo "$hostname"; echo ""; }
if ssh -p 34499 root#"${fqdn}" '[ -d /etc/nginx ]'; then
ssh -p 34499 root#"${fqdn}" 'mv /etc/nginx/nginx.conf /etc/nginx/.nginx-sept-30'
scp -P 34499 nginx.conf root#"${fqdn}":/etc/nginx
ssh -p 34499 root#"${fqdn}" 'sed -i "/honeypot/d" /etc/nginx/conf.d/*.conf'
ssh -p 34499 root#"${fqdn}" 'nginx -t'
else
exit 1;
fi
done 10<"${hostfile}"
Running the script via 'bash -n' will indicate the 'real' error:
bash -n x.sh
x.sh: line 15: syntax error near unexpected token `then'
x.sh: line 15: ` < /dev/null if ssh -p 34499 root#"${fqdn}" '[ -d /etc/nginx ]' ; then'
You can not place redirection before on the 'if' statement. Move the redirection to the 'ssh' (condition part of the if) command, for example:
# USE:
if ssh < /dev/null -p 34499 root#"${fqdn}" '[ -d /etc/nginx ]' ; then'
# AND NOT:
< /dev/null if ssh -p 34499 root#"${fqdn}" '[ -d /etc/nginx ]' ; then'

Linux telnet shell script

I'm trying to read multiple hosts and ports from a text file (ip.txt) and check if they are connected/failed to connect/timed out, and echo the responses to Telnet_Success.txt/Telnet_Failure.txt/Telnet_Refused.txt files
I have tried the following script, it simply shows all the connection results as failed, but when checking manually one by one, I find some of them connected. any help is appreciated.
Here is the script:
>Telnet_Success.txt
>Telnet_Refused.txt
>Telnet_Failure.txt
file=ip.txt
while read line ; do
ip=$( echo "$line" |cut -d ' ' -f1 )
port=$( echo "$line" |cut -d ' ' -f2 )
if telnet -c $ip $port </dev/null 2>&1 | grep -q Escape; then
echo "$ip $port Connected" >> Telnet_Success.txt
elif telnet -c $ip $port </dev/null 2>&1 | grep -q refused; then
echo "$ip $port Refused" >> Telnet_Refused.txt
else
echo "$ip $port Failed" >> Telnet_Failure.txt
fi
done < ${file}
I can't tell you exactly what's failing from the diagnostics you have provided, but it's definitely a problem that you attempt to call telnet multiple times - you could get different outcomes each time, producing bugs which are hard to troubleshoot. You also have some stylistic issues in your code.
Try this refactoring; see the inline comments.
>Telnet_Success.txt
>Telnet_Refused.txt
>Telnet_Failure.txt
# Why use a variable for something you only reference once anyway?
file=ip.txt
# Use the shell's field splitting facility
# Cope with missing final newline; see
# https://mywiki.wooledge.org/BashFAQ/001#My_text_files_are_broken.21__They_lack_their_final_newlines.21
while read -r ip port _ || [[ -n $port ]]; do
# Run telnet once, capture result for analysis
output=$(telnet -c "$ip" "$port" </dev/null 2>&1)
case $output in
*Escape*)
echo "$ip $port Connected" >> Telnet_Success.txt;;
*refused*)
echo "$ip $port Refused" >> Telnet_Refused.txt;;
*)
echo "$ip $port Failed" >> Telnet_Failure.txt;;
esac
# Always double quote file name variables, just in case
done < "${file}"
Hi looks like the telnet command is the culprit
should be "telnet ip port" not "telnet -c ip port"
file=ip.txt
while read line
do
ip=$( echo "$line" |cut -d ' ' -f1 )
port=$( echo "$line" |cut -d ' ' -f2 )
if telnet $ip $port </dev/null 2>&1 | grep -q Escape
then
echo "$ip $port Connected" >> Telnet_Success.txt
elif telnet $ip $port </dev/null 2>&1 | grep -q refused
then
echo "$ip $port Refused" >> Telnet_Refused.txt
else
echo "$ip $port Failed" >> Telnet_Failure.txt
fi
done < ${file}

Open/close port shell script

I found a script that allows you to open or close any port and save it to the iptables. The problem I am having is it throws a syntax error after I tell it to close, but before I can give it a port number. The issue is right before the first else.
#!/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
clear
echo -e "############################nnnPresent ports opened on this machine are
$(iptables -nL INPUT | grep ACCEPT | grep dpt)
nCompleted listing...nnn#########################"
read -p "To open port enter open, to close etner close) " OPT1
if [[ "$OPT1" == open ]]
then
read -p "Please enter your desired port number to open: " PORT1
if [[ "$PORT1" =~ [0-9]{1,6} ]]
then
iptables -D INPUT $(iptables -nL INPUT --line-numbers | grep "$PORT1" | grep REJECT | awk '{print $1}')
iptables -A INPUT -m tcp -p tcp --dport "$PORT1" -j ACCEPT && { service iptables save;service iptables restart; echo -e "Ports opend through iptables are n$(iptables -nL INPUT | grep ACCEPT | grep dpt)"; }
else
echo "Please enter a valid port(0-65000)"
fi
elif [[ "$OPT1" == close ]]
then
read -p "Please enter your desired port number to close: " PORT1
if [[ "$PORT1" =~ [0-9]{1,6} ]]
then
iptables -D INPUT $(iptables -nL INPUT --line-numbers | grep "$PORT1" | grep ACCEPT | awk '{print $1}')
iptables -A INPUT -m tcp -p tcp --dport "$PORT1" -j REJECT && { service iptables save;service iptables restart; echo -e "Ports closed through iptables are n$(iptables -nL INPUT | grep REJECT | grep dpt)"; }
else
echo "Please enter a valid port(0-65000)"
fi
else
echo "Please enter only open or close..! Exiting script now";exit 1
fi
I don't see any error in the script. Can you paste the error that you are getting? See below
[root#kali ~]# ./ip.sh
######################nnnPresent ports opened on this machine are
nCompleted listing...nnn#########################
To open port enter open, to close etner close) close
Please enter your desired port number to close: 23
iptables: Bad rule (does a matching rule exist in that chain?).
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
Redirecting to /bin/systemctl restart iptables.service
Ports closed through iptables are nREJECT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:23 reject-with icmp-port-unreachable

Resources