如何在Python中递归尝试不同的SSH密码?

3 投票
3 回答
2002 浏览
提问于 2025-04-17 19:45

我们这里为测试服务器使用了多组预设的密码。我想试试一个便携的Python SSH库(像下面提到的spur.py),让它依次尝试每一个密码,当然,如果成功连接了就停止,如果都不行,就让我输入密码。我觉得这可能需要用到递归和异常处理。

def ssh_connection(user, host):
    try:
        shell = spur.SshShell(
            hostname=host,
            port=findport(host),
            username=user,
            password="abc123",
            private_key_file= expanduser("~") + "/.ssh/id_rsa",
            missing_host_key=spur.ssh.MissingHostKey.accept
            )
        shell.run(["true"])
        return shell
    except spur.ssh.ConnectionError as error:
        print error
        raise

我之前在Java中会检查对象是否为空,然后遍历一个列表直到结束,最后再询问密码。我现在不太清楚在Python中该怎么做……这里有一个我找到的关于列表部分的例子:

passwords = ['abc123', 'abc456',  'abc789']
for password in passwords:        # Second Example
   print 'trying password :', password

3 个回答

0

我上面的评论被搞乱了,所以这里是@Joe Doherty的建议,结合了Ifthikan的代码 - 谢谢!

def loop_ssh_connection(user, host):
        shell = None
        passw = ['abc123', 'abc456',  'abc789']
        while shell is None:
            shell = ssh_connection(user, host, passw)
        result = shell.run(["ls", "-l"])
        print result.output # prints ouput

def ssh_connection(user, host, passw):
    err = None
    for password in passw:
        try:
            shell = spur.SshShell(
                hostname=host,
                port=findport(host),
                username=user,
                password=password,
                private_key_file= expanduser("~") + "/.ssh/id_rsa",
                missing_host_key=spur.ssh.MissingHostKey.accept
            )
            shell.run(["true"])
            return shell
        except spur.ssh.ConnectionError as error:
            err = error
    if err:
        raise error 
0

我会把它分成两个不同的函数:

def ssh_connection(user, host, password):
    """
    try to connect to user:password@host
    return None if failed
    """

    try:
        shell = spur.SshShell(
            hostname=host,
            port=findport(host),
            username=user,
            password=password,
            private_key_file=expanduser("~") + "/.ssh/id_rsa",
            missing_host_key=spur.ssh.MissingHostKey.accept
            )
        shell.run(["true"])
        return shell
    except spur.ssh.ConnectionError as error:
        print error
        return



def try_connection(user, host, passwords):
    """
    try all password in passwords to connect to host
    if all failed, ask for password via stdin
    """
    for password in passwords:
        conn = ssh_connection(user, host, password)
        if not conn is None:
            break
    else:
        # we never hit the break: ask for passwd
        password = ""
        while conn is None:
            print "please insert password for %s@%s (empty for exit)" % (user,host)
            password = raw_input("passwd:") # todo : insert Term seq for hide passwd and then restor
            if password == "":
                sys.exit(1)
            conn = ssh_connection(user, host, password)
    return conn
2

正如乔在评论中提到的,你可以做一些类似的事情:

def ssh_connection(user, host, passwords):
    err = None
    for password in passwords:
        try:
            shell = spur.SshShell(
                hostname=host,
                port=findport(host),
                username=user,
                password=password,
                private_key_file= expanduser("~") + "/.ssh/id_rsa",
                missing_host_key=spur.ssh.MissingHostKey.accept
            )
            shell.run(["true"])
            return shell
        except spur.ssh.ConnectionError as error:
            err = error
    if err:
        raise error      

撰写回答