使用expect脚本自动检查多个路由器的密码

使用expect脚本自动检查多个路由器的密码

当前的任务是检查多个路由器的密码并更改它,以防任何密码仍设置为默认值,即(例如)登录名:ABC,密码:ABC。

我为此编写了一个期望脚本,但遇到了一些问题。

这是代码:

#!/usr/bin/expect -f

spawn telnet 10.15.160.69 #using a test IP, later it will read IP's from a list.

expect {

 "Login: " {
   send "ABC\r"
   exp_continue
  }
 "Password: " {

    send "ABC\r"
    exp_continue
  }

  "> " {

    send "passwd\r"
    expect "Username: "
    send "ABC\r"
    expect "Password: "
    send "ABC\r"
    expect "New Password: "
    send "n3wp@ss\r"
    expect "Confirm New Password: "
    send "n3wp@ss\r"
    expect "> "
    send "save\r"

  }
}

现在,路由器有一个特殊的行为,即在 3 次密码尝试后不会注销,而是不断提示输入登录名和密码,直到提供正确的凭据或Ctrl+D按下 (EOF)。

请看下面:

Trying 10.15.160.69...
Connected to 10.15.160.69.
Escape character is '^]'.
BCM96816 Broadband Router
Login:     
Password: 
Login incorrect. Try again.
Login: 
Password: 
Login incorrect. Try again.
Login: 
Password: 
Authorization failed after trying 3 times!!!.

Login: Password: 
Login incorrect. Try again.
Login: 
Password: 
Login incorrect. Try again.
Login: 
Password: 
Authorization failed after trying 3 times!!!.
Login: 
Password: 
Login incorrect. Try again.

在脚本中发送 aneof会导致其完全退出。

Expect 脚本是从 bash 脚本调用的:

#!/bin/bash

for host in $(cat ipnmap.txt);do
echo "${host}";

/usr/bin/expect passchange1.sh $host
done

我意识到可以使用 Expect 来实现相同的功能,但我更喜欢在 bash 中完成它。

所需要的是,一旦路由器第二次请求凭据,脚本就应该移动到下一个 IP,因为如果第一次不成功,则意味着路由器没有默认密码,这就是我们要执行的操作。如果需要,我们可以移至下一个 IP/路由器(仅当路由器具有默认用户名/密码时才需要更改密码)。

我将非常感谢为解决此问题提供的任何指导。谢谢

答案1

您可以简单地将登录的每个部分分散到单独的匹配项中,而不是将所有内容都放在单个expect语句中,特别是当您知道将得到什么序列时,因此您不需要一次处理许多可能的回复。例如:

#!/usr/bin/expect 
proc abort { } { send_user "Timeout!" ; exit 2 }
set address [lindex $argv 0]
spawn telnet $address
expect timeout abort "Login: " 
set timeout 5
send "ABC\r"
expect timeout abort "Password: "
send "ABC\r"
expect timeout abort  "Login incorrect" exit  "> "
send "passwd\r"
expect timeout abort "Username: "
send "ABC\r"
expect timeout abort "Password: "
send "ABC\r"
expect timeout abort "New Password: "
send "n3wp@ss\r"
expect timeout abort "Confirm New Password: "
send "n3wp@ss\r"
expect timeout abort "> "
send "save\r"
expect timeout abort "> "
send "quit\r"
expect timeout abort eof

该脚本创建一个函数abort,该函数将打印一条消息,并在调用时以返回码 2 退出。它将变量设置address为传递给脚本的第一个参数。它启动 telnet 命令,然后执行expect登录提示或超时(默认超时为 10 秒。我们稍后将其设置为 5 秒。)。timeout是一个特殊的关键字而不是模式。 Expect 命令的格式为模式命令 模式命令...。最后的命令可以省略,意味着移至脚本中的下一行。这与多行等效:

expect {
  timeout abort
  "Login incorrect" exit 
  "> " 
}

如果没有看到登录提示,超时将调用我们的 abort 并退出,并且在您的 bash 脚本中您可以测试此失败。

如果出现提示,我们将发送用户 ID,然后发送密码。如果我们收到“登录不正确”,我们将退出(退出代码 0),因为这意味着密码不是默认密码,否则我们将设法登录并看到提示>并继续配置。最后可能会有一些有用的命令,例如quit您可以发送以彻底关闭连接并expect eof等待关闭。

相关内容