窥探FTP通信细节

前几天,老张写了两篇关于FTP的文章:

给大家介绍了FTP的通信机制,然后又带大家写了一个玩具版的FTP服务端代码。

今天继续给大家带来FTP系列的第三篇《窥探FTP通信细节》,通过抓包FTP的通信,将FTP的扒的底裤都不剩。


 


 

环境准备:

  • FTP客户端测试脚本:依然选择Python自带的Ftplib来编写测试脚本

  • Wireshark:一个网络层的抓包工具

  • 一台主机:用于运行FTP客户端脚本和Wireshark。ip为192.168.16.1

  • 一台Linux虚拟机:运行Vsftpd作为FTP服务端。ip为192.168.16.129

  • FTP服务器的模式:选择主动模式,使用Binary模式传输数据。

 注:为什么不用老张的玩具版?使用成熟通用的Vsftpd是为了能够更好的帮助大家理解,避免不必要的歧义。

 

OK,请各位系好安全带,马上开车了!

 

1. 连接FTP服务器,建立命令通道通道

import ftplibftp = ftplib.FTP()ftp.connect("192.168.16.129", 21)此时使用Wireshark抓包,可以看到:

经过TCP的三次握手,命令通道建立。此时FTP服务器会向客户端发送一条220状态码的消息,表示命令通道已建立。但是注意,此时还没有登录鉴权。

 

2. 客户端发送账号密码

ftp.connect("192.168.16.129", 21)ftp.login("root", "root")  # 此处密码并非正式密码,抓包时老张也机智的把密码抹去了此时报文消息如下:

可以看到账号和密码是通过两条消息分别发送的。

3. 客户端设置本次连接使用主动模式:

ftp.set_pasv(False)

此行为完全是客户端本地行为,没有同服务器之间进行信息交换。

4. 将本地文件上传至服务器:

# 将本地文件上传至服务器with open("client", 'rb') as f:    ftp.storbinary("STOR upload_from_client", f, 1024)虽然看起来只有一个STOR命令,但是此时却是客户端和服务器之间信息交换最繁忙的时候,为了能够讲清楚,老张将整个过程拆解了一下。

4.1 传输上传命令:

 

首先,客户端通过命令通道通知服务端,本次数据传输将使用Binary模式。

然后,客户端将自己为数据通道准备的host及port发送给服务器。

注:关于端口号port的传输格式,可以参考上一篇的代码实现。

最后,客户端才发送上传命令,通知服务器文件需要保存在默认文件夹,使用“upload_from_client”作为文件名。

4.2 建立数据通道,传递数据:

 

可以看到,数据通道是需要时才会建立,并不是一开始就建立好的,并且在数据传输完成之后立刻关闭。

还有另一个细节,主动模式下,服务器在收到上传命令后,响应上传命令和建立数据通道是同步进行的,这一点是我们的单线程玩具版不能比拟的。

4.3 服务器通知客户端,上传完成:

 

5. 下载服务器文件至本地:

# 下载服务器文件with open("download_from_server", "wb") as f:    ftp.retrbinary("RETR server", f.write)同上传流程类似,这里我们继续拆解。

5.1 传输下载命令:

到这里有没有发现,其实下载和上传的流程是几乎一模一样的。

5.2 建立数据通道,传递数据:

必须指出的是,每次客户端建立数据通道使用的端口号并不是固定不变的。

5.3 服务器通知客户端,下载完成:

一旦数据传输完成,服务器依然会发送一条消息通知客户端。


6. 程序退出,命令通道关闭:

 


 

以上就是FTP的通信细节,不知道各位同学看完有没有一丝疑惑?没错,老张之前也给大家强调过FTP协议是明文传输,你所有的秘密都不是秘密!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值