0

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"
        }
    }
}

migrated from serverfault.com Jun 13 '15 at 11:04

This question came from our site for system and network administrators.

1

You were correct, exp_internal -f passcheck-debug.log 1 pointed me to the problem of not having enough ptys. I added:

close -i $spawn_id
wait -nowait

and it continued beyond that point. I had to add -nowait because if it doesn't have a spawn_id it will wait forever.

0

You may be running out of file descriptors. You probably need to call close on each spawn so you dont run out of resources.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy