I have written an expect script that works perfect for testing passwords on our network until it has looped through my list quite a bit, then the debug output shows that there is nothing to match.
Here is some debug that shows the buffer with data in it, then the next spawn with no data:
ssh: connect to host 12.23.34.56 port 22: No route to host
expect: does "ssh: connect to host 12.23.34.56 port 22: No route to host\r\r\n" (spawn_id exp69) match glob pattern "(yes/no)? "? no
"assword: "? no
"]# "? no
"oute to host"? yes
expect: set expect_out(0,string) "oute to host"
expect: set expect_out(spawn_id) "exp69"
expect: set expect_out(buffer) "ssh: connect to host 12.23.34.56 port 22: No route to host"
spawn ssh -o PreferredAuthentications=password -o NumberOfPasswordPrompts=3 admin@x.x.x.x
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {26418}
expect: does "" (spawn_id exp70) match glob pattern "(yes/no)? "? no
"assword: "? no
"]# "? no
"oute to host"? no
"onnection refused"? no
"isconnected from"? no
expect: timed out
Every spawn_id after exp69 has nothing in the does "" match section.
I think this is related to the buffer some how, but I've tried:
match_max 200000
match_max 600000
And this didn't seem to make any difference. I've removed the real ips and changed it to x.x.x.x. I"m not actually testing x.x.x.x (but the 12.23.34.56 did slip into my list of servers to check)
The script itself is running expect and loops over another file called "servers.txt" and tries line by line to execute a series of commands on that server. It logs what worked and what didn't. Here is what is in the script:
#!/usr/bin/expect
# where to log info, open "writable", this is our homegrown log
# unlike the others that follow
set logfile [open "passcheck-results" "w"]
# clobber and log
log_file -noappend passcheck-logfile
# disable user viewing of process as it happens
# 1=on, 0=off
# disables screen output only, recommended 0
log_user 1
# enable verbose debugging, from expect
# 1=on, 0=off
# useful for debugging the script itself, recommended: 0
exp_internal -f debug.log 0
# default waits for 10s, and if no response, kills process
# too low and machines may not respond fast enough
# in particular real timeouts are not registered if too low
# set to -1 for infinite, real timeouts can take 60s or more
# instead of waiting 60s for EVERY failure, set this lower
# recommend the 10s default
set timeout 10
# if you do not get all the response, you expect, increase buffer
match_max 600000
# get by argv functions instead
# set nohistory save on CLI/bash
set passwords { password1 password2 password3 }
# open the list of servers to process
# warning, no error checking on file open
set input [open "servers.txt" "r"]
# loop over the list of servers with prompt logic
foreach ip [split [read $input] "\n"] {
# slowing it down a bit
sleep 2
# had to change =password to get results I wanted
# loop over line of servers
spawn ssh -o PreferredAuthentications=password \
-o NumberOfPasswordPrompts=[llength $passwords] admin@$ip
# verify where exactly to reset this count
set try 0
# account for other possibilities
expect {
"(yes/no)? " {
# new host detected
sleep 1
send "yes\r"
exp_continue
}
"assword: " {
if { $try >= [llength $passwords] } {
puts $logfile "Bad_Passwords $ip"
#send_error ">>> wrong passwords\n"
exit 1
}
sleep 1
send [lindex $passwords $try]\r
incr try
exp_continue
}
"\]\# " {
puts $logfile "succeeded_$try $ip"
sleep 1
send "exit\r"
}
"oute to host" {
puts $logfile "No_Route_to_Host $ip"
}
"onnection refused" {
puts $logfile "Refused $ip"
}
"isconnected from" {
puts $logfile "Disconnected $ip"
}
timeout {
puts $logfile "timed_out_or_fail $ip"
}
}
}