(2023-2024-1)20232826《Linux内核原理分析与设计》第十二周作业

20232826王朝昆 2023-12-06 21:45:06

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

  1.4 实验效果

          本节实验将实现如下功能的 FTP 弱口令扫描器:

                

 

 2. 具体实验内容

      2.1 认识ftp服务器

       FTP是用来在两台计算机之间传输文件,是Internet中应用非常广泛的服务之一。它可根据实际需要设置各用户的使用权限,同时还具有跨平台的特性,即在UNIX、Linux和Windows等操作系统中都可实现FTP客户端和服务器,相互之间可跨平台进行文件的传输。因此,FTP服务是网络中经常采用的资源共享方式之一。FTP协议有PORT和PASV两种工作模式,即主动模式和被动模式。

       FTP(File Transfer Protocol)即文件传输协议,采用客户/服务器模式。通过FTP协议,用户可以在FTP服务器中进行文件的上传或下载等操作。虽然现在通过HTTP协议下载的站点有很多,但是由于FTP协议可以很好地控制用户数量和宽带的分配,快速方便地上传、下载文件,因此FTP已成为网络中文件上传和下载的首选服务器。同时,它也是一个应用程序,用户可以通过它把自己的计算机与世界各地所有运行FTP协议的服务器相连,访问服务器上的大量程序和信息。FTP服务的功能是实现完整文件的异地传输。特点如下:

(一)FTP使用两个平行连接:控制连接和数据连接。控制连接在两主机间传送控制命令,如用户身份、口令、改变目录命令等。数据连接只用于传送数据。

(二)在一个会话期间,FTP服务器必须维持用户状态,也就是说,和某一个用户的控制连接不能断开。另外,当用户在目录树中活动时,服务器必须追踪用户的当前目录,这样,FTP就限制了并发用户数量。 

(三)FTP支持文件沿任意方向传输。当用户与一远程计算机建立连接后,用户可以获得一个远程文件也可以将一本地文件传输至远程机器。

       FTP是仅基于TCP的服务,不支持UDP。与众不同的是FTP使用2个端口,一个数据端口和一个命令端口(也可叫做控制端口)。通常来说这两个端口是21(命令端口)和20(数据端口)。但FTP 工作方式的不同,数据端口并不总是20。这就是主动与被动FTP的最大不同之处。主要有两种工作模式:

  • 主动FTP

      FTP服务器的控制端口是21,数据端口是20,所以在做静态映射的时候只需要开放21端口即可,他会用20端口和客户端主动的发起连接。

  • 被动FTP

      FTP服务器的控制端口是21,数据端口是随机的,且是客户端去连接对应的数据端口,所以在做静态的映射时只开放21端口是不可以的。此时需要做DMZ。

     2.2 ftp服务器实现方案

本实验开发FTP扫描器主要从以下两个方面着手:

 <1> 扫描匿名FTP:

      FTP匿名登录的扫描主要应用于批量扫描中,单独针对一个FTP服务器进行扫描的话成功几率比较小,不过也不排除成功的可能。很多网站都开放ftp服务方便用户下载资源(这个允许匿名登录不足为奇),更疯狂的是网站管理人员为了方便网站访问软件的更新也开放了ftp匿名登录。这样就给了我们很多机会,尤其后者的服务器很容易就受到攻击,后期我会讲解ftp目录下可以搜到web页面之后怎样拿到shell。

<2> 扫描FTP弱口令:

     FTP弱口令扫描其实就是暴力破解,为何我们不称为暴力破解呢?因为我们只是扫描一些简单的密码组合,并不是所有可能的密码组合,而且我们也没有那么多时间去暴力破解。

     2.3 ftp匿名扫描器的实现

       这里需要用到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()

到此本实验的代码就全部完成了,稍加改动就会使这个扫描器更加强大,比如:主机名可以指定范围实现大范围扫描或者改成分布式暴力破解Ftp用户名密码这样字典的容量就可以更大一些,成功率也会大大增加!

 

 2.4. 实验环境搭建

本实验使用python的第三方库pyftpdlib,可以非常简单的架设一个FTP服务器。

<1> 安装pyftpdlib

     打开终端,输入如下命令:

sudo pip install pyftpdlib

     启动ftp服务器,输入如下命令:

sudo python3 -m pyftpdlib -p 21

     如下图所示: 

           

  这里默认是允许匿名登录。

至此我们的环境就搭建好了,现在可以测试我们的Ftp弱口令扫描器了! 现在我们开始测试吧!运行代码效果如下图所示:

指令: python3 ftpScanner.py -H 127.0.0.1 -f pwd.txt

           

 同时也可以看到,FTP服务器端显示有被扫描到:

           

 

3. 实验总结

本次实验实现了ftp弱口令扫描器,主要用到以下知识点:

  1. FTP 服务器的基本概念
  2. 使用 FTPlib 如何一步一步的实现Ftp弱口令扫描器
  3. 使用 argparse 解析命令行参数
  4. 实验环境的搭建方法

 

...全文
83 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

39

社区成员

发帖
与我相关
我的任务
社区描述
北京电子科技学院 《Linux内核原理与分析》课程
linuxarm开发系统安全 高校 北京·丰台区
社区管理员
  • rocflytosky
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧