Python 实现 FTP 弱口令扫描器
1. 实验要求
本次实验通过使用 Python 实现一个 FTP 弱口令扫描器开始,入门 Python 渗透测试技术,实验涉及 FTP 协议原理,ftplib 库的使用等知识点。
1.2 实验知识点
1. 认识ftp服务器
2. ftplib库的使用
3. argparse库的使用
4. Ubuntu下ftp服务器的搭建
1.3 实验环境
Python3.5
pyftpdlib-1.5.4
2. 实验内容
2.1 FTP服务器
FTP(文件传输协议)是一种用于在计算机之间传输文件的标准网络协议。FTP服务器是支持FTP协议的服务器,它允许用户上传和下载文件。以下是一些关于FTP服务器的基本信息:
FTP工作原理: FTP使用客户端-服务器模型。客户端是用户的计算机,而服务器是存储文件的远程计算机。用户可以通过FTP客户端与服务器建立连接,并在两者之间传输文件。
FTP端口: FTP使用两个端口进行通信,一个用于控制连接(通常是端口21),另一个用于数据传输。数据传输端口的具体使用方式取决于FTP服务器的模式,可以是主动模式或被动模式。
FTP安全性: 原始的FTP协议是不安全的,因为它在传输过程中不加密用户名、密码和数据。为了提高安全性,可以使用FTPS(FTP安全)或SFTP(SSH文件传输协议)等安全版本的FTP协议。
FTP服务器软件: 有许多不同的FTP服务器软件可用,包括ProFTPD、vsftpd、FileZilla Server等。这些软件提供不同的功能和配置选项,以满足不同用户的需求。
匿名FTP: FTP服务器可以配置为允许匿名访问,这意味着用户可以使用 "anonymous" 作为用户名,而电子邮件地址可以是任意的。这通常用于提供公开可访问的文件,但有时也可能带来安全风险。
FTP客户端: 用户可以使用各种FTP客户端软件(例如FileZilla、WinSCP、CuteFTP等)来连接到FTP服务器,浏览、上传和下载文件。
FTP模式:
主动模式: 客户端使用一个随机端口建立到服务器端口20的连接来传输数据。
被动模式: 服务器在一个随机端口上等待连接,而客户端使用一个随机端口连接到服务器的控制端口来传输数据。
2.2FTP扫描器实现方案
扫描匿名FTP
FTP匿名登录的扫描主要应用于批量扫描中,单独针对一个FTP服务器进行扫描的话成功几率比较小,不过也不排除成功的可能。
扫描FTP弱口令
FTP弱口令扫描其实就是暴力破解。
3.实验实现
FTP匿名扫描器的实现
3.1实验准备
这里需要用到Python的ftplib库中的FTP这个类,FTP这个类实现了Ftp客户端的大多数功能,比如连接Ftp服务器、查看服务器中的文件、上传、下载文件等功能,详细用法可以查看一下文档,接下来通过定义anonScan(hostname)这个函数以实现扫描可匿名登录的Ftp服务器。代码如下:
#匿名登录扫描
def anonScan(hostname): #参数是主机名
try:
with FTP(hostname) as ftp: #创建Ftp对象
ftp.login() #Ftp匿名登录
print('\n[*] ' + str(hostname) + " FTP Anonymous login successful!") #不抛出异常则表明登录成功
return True
except Exception as e: #抛出异常则表明匿名登录失败
print('\n[-] ' + str(hostname) + " FTP Anonymous logon failure!")
return False
这个代码的思路很简单,首先用主机名构造了一个ftp对象(即ftp),然后用这个ftp调用不带任何参数的login()函数即表示要匿名登录这个ftp服务器,如果登录过程中没有产生异常,则表明匿名登录成功,否则匿名登录失败!
FTP弱口令的扫描依赖于用户名和密码字典,我们的实验环境中会提供 pwd.txt
作为密码字典。字典格式如图所示:
接下来针对字典中的格式来实现FTP弱口令的扫描,创建代码文件 ftpScanner.py
,代码如下:
#暴力破解
def vlcLogin(hostname, pwdFile): #参数(主机名,字典文件)
try:
with open(pwdFile, 'r') as pf: #打开字典文件
for line in pf.readlines(): #循环读取字典文件中的每一行
time.sleep(1) #等待1秒
userName = line.split(':')[0] #从读取的内容中取出用户名
passWord = line.split(':')[1].strip('\r').strip('\n') #从读取的内容中取出密码
print('[+] Trying: ' + userName + ':' + passWord)
try:
with FTP(hostname) as ftp: #以主机名为参数构造Ftp对象
ftp.login(userName, passWord) #使用读取出的用户名密码登录Ftp服务器
#如果没有产生异常则表示登录成功,打印主机名、用户名和密码
print('\n[+] ' + str(hostname) + ' FTP Login successful: '+ \
userName + ':' + passWord)
return (userName, passWord)
except Exception as e:
# 产生异常表示没有登录成功,这里我们不用管它,继续尝试其他用户名、密码
pass
except IOError as e:
print('Error: the password file does not exist!')
print('\n[-] Cannot crack the FTP password, please change the password dictionary try again!')
return (None,None)
基本的代码已经实现完成了,现在把上面的代码整合一下就可以了,代码如下:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from ftplib import *
import argparse
import time
#匿名登录扫描
def anonScan(hostname): #参数是主机名
try:
with FTP(hostname) as ftp: #创建Ftp对象
ftp.login() #Ftp匿名登录
print('\n[*] ' + str(hostname) + " FTP Anonymous login successful!") #不抛出异常则表明登录成功
return True
except Exception as e: #抛出异常则表明匿名登录失败
print('\n[-] ' + str(hostname) + " FTP Anonymous logon failure!")
return False
#暴力破解
def vlcLogin(hostname, pwdFile): #参数(主机名,字典文件)
try:
with open(pwdFile, 'r') as pf: #打开字典文件
for line in pf.readlines(): #循环读取字典文件中的每一行
time.sleep(1) #等待1秒
userName = line.split(':')[0] #从读取的内容中取出用户名
passWord = line.split(':')[1].strip('\r').strip('\n') #从读取的内容中取出密码
print('[+] Trying: ' + userName + ':' + passWord)
try:
with FTP(hostname) as ftp: #以主机名为参数构造Ftp对象
ftp.login(userName, passWord) #使用读取出的用户名密码登录Ftp服务器
#如果没有产生异常则表示登录成功,打印主机名、用户名和密码
print('\n[+] ' + str(hostname) + ' FTP Login successful: '+ \
userName + ':' + passWord)
return (userName, passWord)
except Exception as e:
# 产生异常表示没有登录成功,这里我们不用管它,继续尝试其他用户名、密码
pass
except IOError as e:
print('Error: the password file does not exist!')
print('\n[-] Cannot crack the FTP password, please change the password dictionary try again!')
return (None,None)
def main():
# 这里用描述创建了ArgumentParser对象
parser = argparse.ArgumentParser(description='FTP Scanner')
# 添加-H命令dest可以理解为咱们解析时获取-H参数后面值的变量名,help是这个命令的帮助信息
parser.add_argument('-H',dest='hostName',help='The host list with ","space')
parser.add_argument('-f',dest='pwdFile',help='Password dictionary file')
options = None
try:
options = parser.parse_args()
except:
print(parser.parse_args(['-h']))
exit(0)
hostNames = str(options.hostName).split(',')
pwdFile = options.pwdFile
if hostNames == ['None']:
print(parser.parse_args(['-h']))
exit(0)
for hostName in hostNames:
username = None
password = None
if anonScan(hostName) == True:
print('Host: ' + hostName + ' Can anonymously!')
elif pwdFile != None:
(username,password) = vlcLogin(hostName,pwdFile)
if password != None:
print('\n[+] Host: ' + hostName + 'Username: ' + username + \
'Password: ' + password)
print('\n[*]-------------------Scan End!--------------------[*]')
if __name__ == '__main__':
main()
3.2实验步骤
打开终端,输入如下命令:
sudo pip install pyftpdlib
启动ftp服务器,输入如下命令:
sudo python3 -m pyftpdlib -p 21
这里默认是允许匿名登录。至此我们的环境就搭建好了,现在可以测试我们的Ftp弱口令扫描器了,使用python3 ftpScanner.py -H 127.0.0.1 -f pwd.txt命令
同时也可以看到,FTP服务器端显示有被扫描到:
4.实验总结
本次实验让我了解到了FTP 服务器的基本概念,弱口令扫描器是用于检测系统、服务或应用程序中弱密码的工具。对于FTP(文件传输协议)服务器,弱口令扫描器通常用于识别那些容易被猜测或暴力破解的FTP账户密码组合。以及如何使用 FTPlib 一步一步的实现Ftp弱口令扫描器。