├── readme.md ├── user_pass_data.py └── weakpass_scan.py /readme.md: -------------------------------------------------------------------------------- 1 | # WeakpassScan 2 | 弱密码扫描工具 3 | 4 | 支持对ssh、postgresql、Redis、MySQL、mongoDB、FTP、sqlserver(mssql)、Dahua(大华)、hikvision(海康威视)进行弱密码扫描,共9个类别; 5 | 仓库代码参考:https://github.com/popmedd/SubDomainsResultDeal/blob/0303d95bd96b8f1e696c6534f686f30809763970/util/unauth/weakPassScan.py 6 | 在原代码的基础上增加到了9中弱密码扫描,并且修改了用户名-密码集合的使用方式,并将代码修改为python3 7 | 8 | # 软件声明 9 | 本工具仅用于测试学习,不可对真实设备进行使用,后果自负; 10 | 11 | # Python版本 12 | Python3 13 | 14 | # 使用方法 15 | python weakpass_scan.py [type] -i [host] -p [port] -o [timeout] -t [thread] 16 | 17 | ​ type: 必选项,ssh or postgresql or redis or mysql or mongodb or ftp or sqlserver or mssql or dahua or hikvision 18 | 19 | ​ -i : 必选项,目标IP 20 | 21 | ​ -p : 必选项,目标端口 22 | 23 | ​ -o : 超时时间,默认5秒 24 | 25 | ​ -t : 线程数量,默认10 26 | 27 | 28 | 29 | # 参考代码 30 | 31 | https://github.com/popmedd/SubDomainsResultDeal/blob/0303d95bd96b8f1e696c6534f686f30809763970/util/unauth/weakPassScan.py 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /user_pass_data.py: -------------------------------------------------------------------------------- 1 | username_dict = { 2 | "ftp": ["ftp", "anonymous"], 3 | # "ftp": ["ftp", "admin", "www", "web", "root", "db", "wwwroot", "data"], 4 | "mysql": ["root", "mysql", "admin", "test"], 5 | "mssql": ["sa"], 6 | # "smb": ["administrator", "admin", "guest"], 7 | # "rdp": ["administrator", "admin", "guest"], 8 | "postgresql": ["postgres", "admin"], 9 | "ssh": ["root", "admin"], 10 | "mongodb": ["root", "admin"], 11 | # "oracle": ["sys", "system", "admin", "test", "web", "orcl"], 12 | "dahua": ["admin", "dahua", "root", "test"], 13 | "hikvision": ["admin"] 14 | } 15 | 16 | 17 | passwords_list = ["123456", "12345", 'asdf1234', 'abc12345', '12345{user}', "{user}12345", '12345abc',"admin", "admin123", "root", 18 | "", "pass123", "pass@123", "password", "123123", "654321", "111111", 19 | "123", "1", "admin@123", "Admin@123", "admin123!@#", "{user}", "{user}1", "{user}111", "{user}123", 20 | "{user}@123", "{user}_123", "{user}#123", "{user}@111", "{user}@2019", "{user}@123#4", "P@ssw0rd!", 21 | "P@ssw0rd", "Passw0rd", "qwe123", "12345678", "test", "test123", "123qwe", "123qwe!@#", "123456789", 22 | "123321", "666666", "a123456.", "123456~a", "123456!a", "000000", "1234567890", "8888888","888888", "!QAZ2wsx", 23 | "1qaz2wsx", "abc123", "abc123456", "1qaz@WSX", "a11111", "a12345", "Aa1234", "Aa1234.", "Aa12345", "a123456", 24 | "a123123", "Aa123123", "Aa123456", "Aa12345.", "sysadmin", "system", "1qaz!QAZ", "2wsx@WSX", "qwe123!@#", 25 | "Aa123456!", "A123456s!", "sa123456", "1q2w3e", "Charge123", "Aa123456789","pwd@123456"] -------------------------------------------------------------------------------- /weakpass_scan.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import ftplib 4 | import queue 5 | import threading 6 | import time 7 | import logging 8 | import socket 9 | from optparse import OptionParser 10 | import pymysql, psycopg2, redis, pymongo, pymssql 11 | import requests 12 | import paramiko 13 | 14 | from user_pass_data import username_dict, passwords_list 15 | 16 | 17 | 18 | #################公有类################# 19 | class CommonFun(object): 20 | """docstring for CommonFun""" 21 | def __init__(self): 22 | super(CommonFun, self).__init__() 23 | 24 | def set_log(self,lname): 25 | logger = logging.getLogger(lname) 26 | logger.setLevel(logging.DEBUG) 27 | 28 | ch = logging.StreamHandler() 29 | ch.setLevel(logging.DEBUG) 30 | 31 | formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 32 | ch.setFormatter(formatter) 33 | 34 | logger.addHandler(ch) 35 | 36 | def show_log(self, lname, msg): 37 | a = logging.getLogger(lname) 38 | a.debug(msg) 39 | 40 | def show_result(self, lname, rlist): 41 | if rlist: 42 | print("###################################################################") 43 | for x in rlist: 44 | self.show_log(lname,x) 45 | else: 46 | print("not found...") 47 | 48 | 49 | #################SSH爆破模块################# 50 | class SshBruter(CommonFun): 51 | def __init__(self, *args): 52 | super(SshBruter, self).__init__() 53 | (options,arg,userlt,pwdlt) = args 54 | self.host = options.host 55 | self.port = int(options.port) 56 | self.ulines = userlt 57 | self.plines = pwdlt 58 | self.threadnum = options.threadnum 59 | self.timeout = options.timeout 60 | self.result = [] 61 | self.set_log(self.host) 62 | self.qlist = queue.Queue() 63 | self.is_exit = False 64 | print(self.host,self.threadnum) 65 | 66 | def get_queue(self): 67 | for name in self.ulines: 68 | for pwd in self.plines: 69 | name = name.strip() 70 | pwd = pwd.strip() 71 | self.qlist.put(name + ':' + pwd) 72 | 73 | def thread(self): 74 | while not self.qlist.empty(): 75 | if not self.is_exit: 76 | name, pwd = self.qlist.get().split(':') 77 | if "{user}" in pwd: 78 | pwd = pwd.replace("{user}", name) 79 | try: 80 | ssh = paramiko.SSHClient() 81 | ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 82 | ssh.connect(hostname=self.host,port=self.port,username=name,password=pwd,timeout=self.timeout) 83 | time.sleep(0.05) 84 | ssh.close() 85 | s = "[OK] %s:%s" % (name,pwd) 86 | self.show_log(self.host,s) 87 | self.result.append(s) 88 | except socket.timeout: 89 | self.show_log(self.host,"Timeout...") 90 | self.qlist.put(name + ':' + pwd) 91 | time.sleep(3) 92 | except Exception as e: 93 | error = "[Error] %s:%s" % (name,pwd) 94 | self.show_log(self.host,error) 95 | pass 96 | else: 97 | break 98 | 99 | def run(self): 100 | self.get_queue() 101 | starttime = time.time() 102 | 103 | threads = [] 104 | for x in range(1,self.threadnum+1): 105 | t = threading.Thread(target=self.thread) 106 | threads.append(t) 107 | t.setDaemon(True) #主线程完成后不管子线程有没有结束,直接退出 108 | t.start() 109 | 110 | try: 111 | while True: 112 | if self.qlist.empty(): 113 | break 114 | else: 115 | time.sleep(1) 116 | except KeyboardInterrupt: 117 | self.is_exit = True 118 | print("Exit the program...") 119 | print("Waiting...") 120 | time.sleep(5) 121 | 122 | self.show_result(self.host,self.result) 123 | finishetime = time.time() 124 | print("Used time: %f" % (finishetime-starttime)) 125 | 126 | 127 | 128 | #################postgresql爆破模块################# 129 | class postgresqlBruter(CommonFun): 130 | def __init__(self, *args): 131 | super(postgresqlBruter, self).__init__() 132 | (options,arg,userlt,pwdlt) = args 133 | self.host = options.host 134 | self.port = int(options.port) 135 | self.ulines = userlt 136 | self.plines = pwdlt 137 | self.threadnum = options.threadnum 138 | self.timeout = options.timeout 139 | self.result = [] 140 | self.set_log(self.host) 141 | self.qlist = queue.Queue() 142 | self.is_exit = False 143 | print(self.host,self.threadnum) 144 | 145 | def get_queue(self): 146 | for name in self.ulines: 147 | for pwd in self.plines: 148 | name = name.strip() 149 | pwd = pwd.strip() 150 | self.qlist.put(name + ':' + pwd) 151 | 152 | def thread(self): 153 | while not self.qlist.empty(): 154 | if not self.is_exit: 155 | name,pwd = self.qlist.get().split(':') 156 | if "{user}" in pwd: 157 | pwd = pwd.replace("{user}", name) 158 | try: 159 | pgscon = psycopg2.connect(host=self.host, port=self.port, user=name, password=pwd) 160 | time.sleep(0.02) 161 | pgscon.close() 162 | s = "[OK] %s:%s" % (name,pwd) 163 | self.show_log(self.host,s) 164 | self.result.append(s) 165 | except socket.timeout: 166 | self.show_log(self.host,"Timeout...") 167 | self.qlist.put(name + ':' + pwd) 168 | time.sleep(3) 169 | except Exception as e: 170 | # print(e) 171 | error = "[Error] %s:%s" % (name,pwd) 172 | self.show_log(self.host,error) 173 | pass 174 | else: 175 | break 176 | 177 | def run(self): 178 | self.get_queue() 179 | starttime = time.time() 180 | 181 | threads = [] 182 | for x in range(1,self.threadnum+1): 183 | t = threading.Thread(target=self.thread) 184 | threads.append(t) 185 | t.setDaemon(True) #主线程完成后不管子线程有没有结束,直接退出 186 | t.start() 187 | 188 | try: 189 | while True: 190 | if self.qlist.empty(): 191 | break 192 | else: 193 | time.sleep(1) 194 | except KeyboardInterrupt: 195 | self.is_exit = True 196 | print("Exit the program...") 197 | print("Waiting...") 198 | time.sleep(5) 199 | 200 | self.show_result(self.host,self.result) 201 | finishetime = time.time() 202 | print("Used time: %f" % (finishetime-starttime)) 203 | 204 | 205 | #################mongedb爆破模块################# 206 | class mongedbBruter(CommonFun): 207 | def __init__(self, *args): 208 | super(mongedbBruter, self).__init__() 209 | (options, arg, userlt, pwdlt) = args 210 | self.host = options.host 211 | self.port = int(options.port) 212 | self.ulines = userlt 213 | self.plines = pwdlt 214 | self.threadnum = options.threadnum 215 | self.timeout = options.timeout 216 | self.result = [] 217 | self.set_log(self.host) 218 | self.qlist = queue.Queue() 219 | self.is_exit = False 220 | print(self.host, self.threadnum) 221 | 222 | def get_queue(self): 223 | for name in self.ulines: 224 | for pwd in self.plines: 225 | name = name.strip() 226 | pwd = pwd.strip() 227 | self.qlist.put(name + ':' + pwd) 228 | 229 | def thread(self): 230 | pymongo_ver = pymongo.version 231 | while not self.qlist.empty(): 232 | if not self.is_exit: 233 | name, pwd = self.qlist.get().split(':') 234 | if "{user}" in pwd: 235 | pwd = pwd.replace("{user}", name) 236 | try: 237 | if int(pymongo_ver.split(".")[0]) >= 4: 238 | conn = pymongo.MongoClient(host=self.host, port=self.port, username=name, password=pwd, socketTimeoutMS=3000) 239 | conn.list_database_names() 240 | else: 241 | conn = pymongo.MongoClient(host=self.host, port=self.port, socketTimeoutMS=3000) 242 | if name or pwd: 243 | db = conn.admin 244 | db.authenticate(name, pwd) 245 | else: 246 | conn.list_database_names() 247 | conn.close() 248 | s = "[OK] %s:%s" % (name,pwd) 249 | self.show_log(self.host,s) 250 | self.result.append(s) 251 | except socket.timeout: 252 | self.show_log(self.host,"Timeout...") 253 | self.qlist.put(name + ':' + pwd) 254 | time.sleep(3) 255 | except Exception as e: 256 | # print(e) 257 | error = "[Error] %s:%s" % (name,pwd) 258 | self.show_log(self.host,error) 259 | pass 260 | else: 261 | break 262 | 263 | def run(self): 264 | self.get_queue() 265 | starttime = time.time() 266 | 267 | threads = [] 268 | for x in range(1,self.threadnum+1): 269 | t = threading.Thread(target=self.thread) 270 | threads.append(t) 271 | t.setDaemon(True) #主线程完成后不管子线程有没有结束,直接退出 272 | t.start() 273 | 274 | try: 275 | while True: 276 | if self.qlist.empty(): 277 | break 278 | else: 279 | time.sleep(1) 280 | except KeyboardInterrupt: 281 | self.is_exit = True 282 | print("Exit the program...") 283 | print("Waiting...") 284 | time.sleep(5) 285 | 286 | self.show_result(self.host,self.result) 287 | finishetime = time.time() 288 | print("Used time: %f" % (finishetime-starttime)) 289 | 290 | 291 | # #################redis爆破模块################# 292 | class RedisBruter(CommonFun): 293 | def __init__(self, *args): 294 | super(RedisBruter, self).__init__() 295 | (options, arg, pwdlt) = args 296 | self.host = options.host 297 | self.port = options.port 298 | self.plines = pwdlt 299 | self.threadnum = options.threadnum 300 | self.timeout = options.timeout 301 | self.result = [] 302 | self.set_log(self.host) 303 | self.qlist = queue.Queue() 304 | self.is_exit = False 305 | print(self.host, self.threadnum) 306 | 307 | def get_queue(self): 308 | for pwd in self.plines: 309 | pwd = pwd.strip() 310 | self.qlist.put(pwd) 311 | 312 | def thread(self): 313 | while not self.qlist.empty(): 314 | pwd = self.qlist.get() 315 | if "{user}" in pwd: 316 | pwd = pwd.replace("{user}", "redis") 317 | try: 318 | conn = redis.Redis(host=self.host, port=self.port, password=pwd) 319 | conn.ping() 320 | # time.sleep(0.05) 321 | s = "[OK] :%s" % (pwd) 322 | if pwd == "": 323 | s += "(no password)" 324 | self.show_log(self.host,s) 325 | self.result.append(s) 326 | except socket.timeout: 327 | self.show_log(self.host,"Timeout...") 328 | self.qlist.put(':' + pwd) 329 | time.sleep(1) 330 | except Exception as e: 331 | error = "[Error] :%s" % (pwd) 332 | self.show_log(self.host,error) 333 | pass 334 | 335 | def run(self): 336 | self.get_queue() 337 | starttime = time.time() 338 | 339 | threads = [] 340 | for x in range(1,self.threadnum+1): 341 | t = threading.Thread(target=self.thread) 342 | threads.append(t) 343 | t.setDaemon(True) #主线程完成后不管子线程有没有结束,直接退出 344 | t.start() 345 | 346 | try: 347 | while True: 348 | if self.qlist.empty(): 349 | break 350 | else: 351 | time.sleep(1) 352 | except KeyboardInterrupt: 353 | self.is_exit = True 354 | print("Exit the program...") 355 | print("Waiting...") 356 | time.sleep(5) 357 | 358 | self.show_result(self.host,self.result) 359 | finishetime = time.time() 360 | print("Used time: %f" % (finishetime-starttime)) 361 | 362 | 363 | #################MySQL爆破模块################# 364 | class MysqlBruter(CommonFun): 365 | """docstring for MysqlBruter""" 366 | def __init__(self, *args): 367 | super(MysqlBruter, self).__init__() 368 | (options, arg, userlt, pwdlt) = args 369 | self.host = options.host 370 | self.port = int(options.port) 371 | self.ulines = userlt 372 | self.plines = pwdlt 373 | self.threadnum = options.threadnum 374 | self.timeout = options.timeout 375 | self.result = [] 376 | self.set_log(self.host) 377 | self.qlist = queue.Queue() 378 | self.is_exit = False 379 | print(self.host, self.threadnum) 380 | 381 | def get_queue(self): 382 | for name in self.ulines: 383 | for pwd in self.plines: 384 | name = name.strip() 385 | pwd = pwd.strip() 386 | self.qlist.put(name + ':' + pwd) 387 | 388 | def thread(self): 389 | while not self.qlist.empty(): 390 | name,pwd = self.qlist.get().split(':') 391 | if "{user}" in pwd: 392 | pwd = pwd.replace("{user}", name) 393 | try: 394 | conn = pymysql.connect(host=self.host, user=name, passwd=pwd, db='mysql', port=self.port) 395 | if conn: 396 | # time.sleep(0.05) 397 | conn.close() 398 | s = "[OK] %s:%s" % (name,pwd) 399 | self.show_log(self.host,s) 400 | self.result.append(s) 401 | except socket.timeout: 402 | self.show_log(self.host,"Timeout") 403 | self.qlist.put(name + ':' + pwd) 404 | time.sleep(3) 405 | except Exception as e: 406 | # print(e) 407 | error = "[Error] %s:%s" % (name,pwd) 408 | self.show_log(self.host,error) 409 | pass 410 | 411 | def run(self): 412 | self.get_queue() 413 | starttime = time.time() 414 | 415 | threads = [] 416 | for x in range(1,self.threadnum+1): 417 | t = threading.Thread(target=self.thread) 418 | threads.append(t) 419 | t.setDaemon(True) #主线程完成后不管子线程有没有结束,直接退出 420 | t.start() 421 | 422 | try: 423 | while True: 424 | if self.qlist.empty(): 425 | break 426 | else: 427 | time.sleep(1) 428 | except KeyboardInterrupt: 429 | self.is_exit = True 430 | print("Exit the program...") 431 | print("Waiting...") 432 | time.sleep(5) 433 | 434 | self.show_result(self.host,self.result) 435 | finishetime = time.time() 436 | print("Used time: %f" % (finishetime-starttime)) 437 | 438 | 439 | #################FTP爆破模块################# 440 | class FtpBruter(CommonFun): 441 | """docstring for MysqlBruter""" 442 | def __init__(self, *args): 443 | super(FtpBruter, self).__init__() 444 | (options, arg, userlt, pwdlt) = args 445 | self.host = options.host 446 | self.port = int(options.port) 447 | self.ulines = userlt 448 | self.plines = pwdlt 449 | self.threadnum = options.threadnum 450 | self.timeout = options.timeout 451 | self.result = [] 452 | self.set_log(self.host) 453 | self.qlist = queue.Queue() 454 | self.is_exit = False 455 | 456 | print(self.host, self.threadnum) 457 | 458 | def get_queue(self): 459 | for name in self.ulines: 460 | for pwd in self.plines: 461 | name = name.strip() 462 | pwd = pwd.strip() 463 | self.qlist.put(name + ':' + pwd) 464 | 465 | def anonymous_login(self): 466 | # 匿名登录 467 | try: 468 | if not self.is_exit: 469 | ftpclient = ftplib.FTP() 470 | ftpclient.connect(host=self.host, port=self.port) 471 | ftpclient.login() 472 | ftpclient.close() 473 | s = "[OK] %s:%s" % ("匿名登录", "匿名登录") 474 | self.show_log(self.host, s) 475 | self.result.append(s) 476 | self.is_exit = True 477 | self.qlist.queue.clear() 478 | except Exception as e: 479 | print("匿名登录error:", e) 480 | 481 | 482 | def thread(self): 483 | while not self.qlist.empty(): 484 | name,pwd = self.qlist.get().split(':') 485 | if "{user}" in pwd: 486 | pwd = pwd.replace("{user}", name) 487 | try: 488 | ftpclient = ftplib.FTP() 489 | ftpclient.connect(host=self.host, port=self.port, timeout=3) 490 | ftpclient.login(name, pwd) 491 | ftpclient.close() 492 | 493 | s = "[OK] %s:%s" % (name,pwd) 494 | self.show_log(self.host,s) 495 | self.result.append(s) 496 | except socket.timeout: 497 | self.show_log(self.host,"Timeout") 498 | self.qlist.put(name + ':' + pwd) 499 | time.sleep(3) 500 | except Exception as e: 501 | print(e) 502 | error = "[Error] %s:%s" % (name,pwd) 503 | self.show_log(self.host,error) 504 | pass 505 | 506 | def run(self): 507 | starttime = time.time() 508 | self.anonymous_login() 509 | if not self.is_exit: 510 | self.get_queue() 511 | starttime = time.time() 512 | threads = [] 513 | for x in range(1,self.threadnum+1): 514 | t = threading.Thread(target=self.thread) 515 | threads.append(t) 516 | t.setDaemon(True) #主线程完成后不管子线程有没有结束,直接退出 517 | t.start() 518 | 519 | try: 520 | while True: 521 | if self.qlist.empty(): 522 | break 523 | else: 524 | time.sleep(1) 525 | except KeyboardInterrupt: 526 | self.is_exit = True 527 | print("Exit the program...") 528 | print("Waiting...") 529 | time.sleep(5) 530 | 531 | self.show_result(self.host,self.result) 532 | finishetime = time.time() 533 | print("Used time: %f" % (finishetime-starttime)) 534 | 535 | 536 | #################Sqlserver(mssql)爆破模块################# 537 | class SqlserverBruter(CommonFun): 538 | def __init__(self, *args): 539 | super(SqlserverBruter, self).__init__() 540 | (options, arg, userlt, pwdlt) = args 541 | self.host = options.host 542 | self.port = int(options.port) 543 | self.ulines = userlt 544 | self.plines = pwdlt 545 | self.threadnum = options.threadnum 546 | self.timeout = options.timeout 547 | self.result = [] 548 | self.set_log(self.host) 549 | self.qlist = queue.Queue() 550 | self.is_exit = False 551 | print(self.host, self.threadnum) 552 | 553 | def get_queue(self): 554 | for name in self.ulines: 555 | for pwd in self.plines: 556 | name = name.strip() 557 | pwd = pwd.strip() 558 | self.qlist.put(name + ':' + pwd) 559 | 560 | def thread(self): 561 | while not self.qlist.empty(): 562 | name,pwd = self.qlist.get().split(':') 563 | if "{user}" in pwd: 564 | pwd = pwd.replace("{user}", name) 565 | try: 566 | conn = pymssql.connect(host=self.host, port=self.port, user=name, password=pwd) 567 | if conn: 568 | # time.sleep(0.05) 569 | conn.close() 570 | s = "[OK] %s:%s" % (name,pwd) 571 | self.show_log(self.host,s) 572 | self.result.append(s) 573 | except socket.timeout: 574 | self.show_log(self.host,"Timeout") 575 | self.qlist.put(name + ':' + pwd) 576 | time.sleep(3) 577 | except Exception as e: 578 | print(e) 579 | error = "[Error] %s:%s" % (name,pwd) 580 | self.show_log(self.host,error) 581 | pass 582 | 583 | def run(self): 584 | self.get_queue() 585 | starttime = time.time() 586 | 587 | threads = [] 588 | for x in range(1,self.threadnum+1): 589 | t = threading.Thread(target=self.thread) 590 | threads.append(t) 591 | t.setDaemon(True) #主线程完成后不管子线程有没有结束,直接退出 592 | t.start() 593 | 594 | try: 595 | while True: 596 | if self.qlist.empty(): 597 | break 598 | else: 599 | time.sleep(1) 600 | except KeyboardInterrupt: 601 | self.is_exit = True 602 | print("Exit the program...") 603 | print("Waiting...") 604 | time.sleep(5) 605 | 606 | self.show_result(self.host,self.result) 607 | finishetime = time.time() 608 | print("Used time: %f" % (finishetime-starttime)) 609 | 610 | 611 | class DahuaBruter(CommonFun): 612 | def __init__(self, *args): 613 | super(DahuaBruter, self).__init__() 614 | (options, arg, userlt, pwdlt) = args 615 | self.host = options.host 616 | self.port = options.port 617 | self.ulines = userlt 618 | self.plines = pwdlt 619 | self.threadnum = options.threadnum 620 | self.timeout = options.timeout 621 | self.result = [] 622 | self.set_log(self.host) 623 | self.qlist = queue.Queue() 624 | self.is_exit = False 625 | print(self.host, self.threadnum) 626 | 627 | def get_queue(self): 628 | for name in self.ulines: 629 | for pwd in self.plines: 630 | name = name.strip() 631 | pwd = pwd.strip() 632 | self.qlist.put(name + ':' + pwd) 633 | 634 | def thread(self): 635 | ip = self.host + ":" + self.port 636 | url = f"http://{ip}/RPC2_Login" 637 | headers = { 638 | 'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", 639 | 'Host': ip, 640 | 'Origin': 'http://' + ip, 641 | 'Referer': 'http://' + ip, 642 | 'Accept': 'application/json, text/javascript, */*; q=0.01', 643 | 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 644 | 'Accept-Encoding': 'gzip, deflate', 645 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 646 | 'Connection': 'close', 647 | 'X-Requested-With': 'XMLHttpRequest', 648 | } 649 | while not self.qlist.empty(): 650 | name,pwd = self.qlist.get().split(':') 651 | if "{user}" in pwd: 652 | pwd = pwd.replace("{user}", name) 653 | print(name,pwd) 654 | _json = { 655 | "method": "global.login", 656 | "params": { 657 | "userName": name, 658 | "password": pwd, 659 | "clientType": "Web3.0", 660 | "loginType": "Direct", 661 | "authorityType": "Default", 662 | "passwordType": "Plain", 663 | }, 664 | "id": 1, 665 | "session": 0, 666 | } 667 | try: 668 | r = requests.post(url, headers=headers, json=_json, verify=False, timeout=5) 669 | if r.status_code == 200 and r.json()['result'] == True: 670 | s = "[OK] %s:%s" % (name,pwd) 671 | self.show_log(self.host,s) 672 | self.result.append(s) 673 | except socket.timeout: 674 | self.show_log(self.host,"Timeout") 675 | self.qlist.put(name + ':' + pwd) 676 | time.sleep(3) 677 | print("Timeout") 678 | except Exception as e: 679 | print(e) 680 | error = "[Error] %s:%s" % (name,pwd) 681 | self.show_log(self.host,error) 682 | pass 683 | 684 | def run(self): 685 | self.get_queue() 686 | starttime = time.time() 687 | 688 | threads = [] 689 | for x in range(1,self.threadnum+1): 690 | t = threading.Thread(target=self.thread) 691 | threads.append(t) 692 | t.setDaemon(True) #主线程完成后不管子线程有没有结束,直接退出 693 | t.start() 694 | 695 | try: 696 | while True: 697 | if self.qlist.empty(): 698 | break 699 | else: 700 | time.sleep(1) 701 | except KeyboardInterrupt: 702 | self.is_exit = True 703 | print("Exit the program...") 704 | print("Waiting...") 705 | time.sleep(5) 706 | 707 | self.show_result(self.host,self.result) 708 | finishetime = time.time() 709 | print("Used time: %f" % (finishetime-starttime)) 710 | 711 | class HikvisionBruter(CommonFun): 712 | def __init__(self, *args): 713 | super(HikvisionBruter, self).__init__() 714 | (options, arg, userlt, pwdlt) = args 715 | self.host = options.host 716 | self.port = options.port 717 | self.ulines = userlt 718 | self.plines = pwdlt 719 | self.threadnum = options.threadnum 720 | self.timeout = options.timeout 721 | self.result = [] 722 | self.set_log(self.host) 723 | self.qlist = queue.Queue() 724 | self.is_exit = False 725 | 726 | def get_queue(self): 727 | for name in self.ulines: 728 | for pwd in self.plines: 729 | name = name.strip() 730 | pwd = pwd.strip() 731 | self.qlist.put(name + ':' + pwd) 732 | 733 | def thread(self): 734 | ip = self.host + ":" + self.port 735 | url = f"http://{ip}/ISAPI/Security/userCheck" 736 | headers = { 737 | 'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", 738 | 'Connection': 'close' 739 | } 740 | while not self.qlist.empty(): 741 | name,pwd = self.qlist.get().split(':') 742 | if "{user}" in pwd: 743 | pwd = pwd.replace("{user}", name) 744 | # print(name,pwd) 745 | try: 746 | r = requests.get(url, auth=(name, pwd), timeout=10, headers=headers, verify=False) 747 | print(r.status_code) 748 | print(r.text) 749 | if r.status_code == 200 and 'userCheck' in r.text and 'statusValue' in r.text and '200' in r.text: 750 | s = "[OK] %s:%s" % (name,pwd) 751 | self.show_log(self.host,s) 752 | self.result.append(s) 753 | except socket.timeout: 754 | self.show_log(self.host,"Timeout") 755 | self.qlist.put(name + ':' + pwd) 756 | time.sleep(3) 757 | print("Timeout") 758 | except Exception as e: 759 | print(e) 760 | # error = "[Error] %s:%s" % (name,pwd) 761 | # self.show_log(self.host,error) 762 | pass 763 | 764 | def run(self): 765 | self.get_queue() 766 | starttime = time.time() 767 | 768 | threads = [] 769 | for x in range(1,self.threadnum+1): 770 | t = threading.Thread(target=self.thread) 771 | threads.append(t) 772 | t.setDaemon(True) #主线程完成后不管子线程有没有结束,直接退出 773 | t.start() 774 | 775 | try: 776 | while True: 777 | if self.qlist.empty(): 778 | break 779 | else: 780 | time.sleep(1) 781 | except KeyboardInterrupt: 782 | self.is_exit = True 783 | print("Exit the program...") 784 | print("Waiting...") 785 | time.sleep(5) 786 | 787 | self.show_result(self.host,self.result) 788 | finishetime = time.time() 789 | print("Used time: %f" % (finishetime-starttime)) 790 | 791 | 792 | def main(): 793 | parser = OptionParser(usage='Usage: python weakpass_scan.py [type] -i [host] -p [port] -o [timeout] -t [thread]') 794 | parser.add_option('-i','--host',dest='host',help='target ip') 795 | parser.add_option('-p','--port',dest='port',help='target port') 796 | parser.add_option('-o','--timeout',type=int,dest='timeout',default=5,help='timeout') 797 | parser.add_option('-t','--thread',type=int,dest='threadnum',default=10,help='threadnum') 798 | 799 | (options, args) = parser.parse_args() 800 | 801 | if not args or not options.host: 802 | parser.print_help() 803 | exit() 804 | 805 | if args[0]=='ssh': 806 | postgresql = SshBruter(options, args, username_dict['ssh'], passwords_list) 807 | postgresql.run() 808 | elif args[0]=='postgresql': 809 | postgresql = postgresqlBruter(options, args, username_dict['postgresql'], passwords_list) 810 | postgresql.run() 811 | elif args[0]=='redis': 812 | redis = RedisBruter(options, args, passwords_list) 813 | redis.run() 814 | elif args[0]=='mysql': 815 | mysql = MysqlBruter(options, args, username_dict['mysql'], passwords_list) 816 | mysql.run() 817 | elif args[0]=='mongodb': 818 | mongo = mongedbBruter(options, args, username_dict['mongodb'], passwords_list) 819 | mongo.run() 820 | elif args[0]=='ftp': 821 | mongo = FtpBruter(options, args, username_dict['ftp'], passwords_list) 822 | mongo.run() 823 | elif args[0]=='sqlserver' or args[0] == "mssql": 824 | # mssql is sqlserver 825 | mongo = SqlserverBruter(options, args, username_dict['mssql'], passwords_list) 826 | mongo.run() 827 | elif args[0]=='dahua': 828 | mongo = DahuaBruter(options, args, username_dict['dahua'], passwords_list) 829 | mongo.run() 830 | elif args[0]=='hikvision': 831 | mongo = HikvisionBruter(options, args, username_dict['hikvision'], passwords_list) 832 | mongo.run() 833 | else: 834 | print("type must be ssh or postgresql or redis or mysql or mongodb or ftp or sqlserver or mssql or dahua or hikvision") 835 | 836 | if __name__ == '__main__': 837 | main() --------------------------------------------------------------------------------