15

窥探FTP通信细节

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzU3Mzc3NDUyOA%3D%3D&%3Bmid=2247483938&%3Bidx=1&%3Bsn=2c0d99a328793cc9e420675e4038e549
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

MVFjY3e.gif

前几天,老张写了两篇关于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 ftplib

ftp = ftplib.FTP()

ftp.connect("192.168.16.129", 21)

此时使用Wireshark抓包,可以看到:

2MnAfyz.png!web

经过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 传输上传命令:

iqQBjab.png!web

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

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

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

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

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

NJj6veV.jpg!web

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

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

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

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

# 下载服务器文件

with open("download_from_server", "wb") as f:

ftp.retrbinary("RETR server", f.write)

同上传流程类似,这里我们继续拆解。

5.1 传输下载命令:

fUjIFja.png!web

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

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

YbQbAv3.jpg!web

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

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

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

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

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

RvEBrqU.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK