ftp协议的分析和扩展
创建时间:2004-04-20 更新时间:2004-04-22
文章属性:转载
文章提交:wlj (wlj_at_uid0.net)

ftp协议的分析和扩展

作者:elly
出处:http://elly.blogdriver.com/index.jsp

>>1.0<< ftp和tcp端口号
根据是使用port模式还是passive模式,ftp使用不同的tcp端口号,在详细描述ftp前,我们来
简单讨论一下tcp端口号的一些基本概念。tcp使用端口号来标识所发送和接收的应用,端口号
可以帮助tcp来分离字节流并且帮相应字节传递给正确的应用程序。
tcp端口号可以是半永久的和暂时的。服务器端监听在半永久的端口上来让客户端访问。客户
端使用暂时的端口在本地标识一个对话,客户端端口只在使用tcp服务时候才存在,而服务器
端口只要服务器在运行就一直在监听。

tcp端口可以归为3类:
1、众所周知的端口来标识在tcp上运行的标准服务,包括ftp、http、telnet、smtp等,这些
     端口号码范围为0-1023;
2、注册端口号用来标识那些已经向iana(internet assigned numbers assigned numbers
     authority)注册的应用,注册端口号为1024-49151;
3、私有端口号是非注册的并且可以动态地分配给任何应用,私有端口为49152-65535;
      注册的端口号本来打算只给注册的应用使用,可近年来端口号已经陷入了到达极限的困境,你
     可能会看到本来应该是给注册应用使用的注册端口被非注册应用用做暂时的端口。rfc1700详
     细标注了众所周知的和注册的端口号,然而不幸的是,这个rfc文档自从1994年以来一直没有
     被更新,然后你仍可以从iana得到一个及时更新的端口列表,详细url为:
     http://www.iana.org/assignments/port-numbers




>>2.0<< ftp port模式和ftp passive模式
当你对一个ftp问题进行排错时候,你首先要问的一个问题是使用的是port模式的还是passive
模式。因为这两种行为迥异,所以这两种模式引起的问题也不同;在过去,客户端缺省为acti
ve(port)模式;近来,由于port模式的安全问题,许多客户端的ftp应用缺省为passive模式。

>>2.1  ftp port模式
port模式的ftp步骤如下:
1、 客户端发送一个tcp syn(tcp同步)包给服务器段众所周知的ftp控制端口21,客户端
      使用暂时的端口作为它的源端口;
2、 服务器端发送syn ack(同步确认)包给客户端,源端口为21,目的端口为客户端上使用
      的暂时端口;
3、 客户端发送一个ack(确认)包;客户端使用这个连接来发送ftp命令,服务器端使用这个
      连接来发送ftp应答;
4、 当用户请求一个列表(list)请求或者发起一个要求发送或者接受文件的请求,客户端软件使用
      port命令,这个命令包含了一个暂时的端口,客户端希望服务器在打开一个数据连接时候使用
      这个暂时端口;port命令也包含了一个ip地址,这个ip地址通常是客户自己的ip地址,而且ft
      p也支持第三方(third-party)模式,第三方模式是客户端告诉服务器端打开与另台主机的连接;
5、 服务器端发送一个syn包给客户端的暂时端口,源端口为20,暂时端口为客户端在port命令中
      发送给服务器端的暂时端口号;
6、 客户端以源端口为暂时端口,目的端口为20发送一个syn ack包;
7、 服务器端发送一个ack包;
8、 发送数据的主机以这个连接来发送数据,数据以tcp段(注:segment,第4层的pdu)形式发送(
      一些命令,如stor表示客户端要发送数据,retr表示服务器段发送数据),这些tcp段都需要
      对方进行ack确认(注:因为tcp协议是一个面向连接的协议)
9、 当数据传输完成以后,发送数据的主机以一个fin命令来结束数据连接,这个fin命令需要另一
      台主机以ack确认,另一台主机也发送一个fin命令,这个fin命令同样需要发送数据的主机以a
      ck确认;
10、 客户端能在控制连接上发送更多的命令,这可以打开和关闭另外的数据连接;有时候客户端结
      束后,客户端以fin命令来关闭一个控制连接,服务器端以ack包来确认客户端的fin,服务器
      同样也发送它的fin,客户端用ack来确认。

下图图示了ftp port模式前几步步骤:
/====================================================================\
|                                                                    |
|       [ ftp client ]                       [ ftp server ]          |
|                                                                    |
|       (tcp:21 连接初始化,控制端口)                                    |
|                              syn                                   |
|        port xxxx   ---------------------->    port 21       [tcp]  |
|                             syn+ack                                |
|        port xxxx   <----------------------    port 21              |
|                              ack                                   |
|        port xxxx   ---------------------->    port 21              |
|                                                                    |
|       (控制操作: 用户列目录或传输文件)                                 |
|                                                                    |
|                       port, ip, port yyyy                          |
|        port xxxx   <----------------------    port 21              |
|                       port seccussful                              |
|        port xxxx   <----------------------    port 21              |
|                       list, retr or stor                           |
|        port xxxx   ---------------------->    port 21              |
|                                                                    |
|                                                                    |
|        (tcp:20 连接初始化,数据端口)                                   |
|                               syn                                  |
|        port yyyy   <----------------------    port 20              |
|                            syn+ack                                 |
|        port yyyy   ---------------------->    port 20              |
|                               ack                                  |
|        port yyyy   <----------------------    port 20              |
|                                                                    |
|                                                                    |
|        (数据操作: 数据传输)                                           |
|                           data + ack                               |
|        port yyyy   <--------------------->    port 20              |
|                               .                                    |
|                               .                                    |
|                               .                                    |
|                                                                    |
\====================================================================/

ftp port模式会给网络管理人员在许多方面带来很多问题,首先,在port命令消息中的ip地址和端
口号的编码不是直白地显示。另外,应用层的协议命令理论上不应该包含网络地址信息(注:
ip地址),因为这打破了协议层的原则并且可能导致协同性和安全性方面的问题。

下图是wildpackets etherpeek协议分析仪解码了port命令的地址参数,地址参数后是端口号,见port
192,168,10,232,6,127;6,127部分的第一个阿拉伯数字乘以256,然后加上第2个阿拉伯数字
就得到端口号,所以客户端指定了端口号为6*256+127=1663;
/====================================================================\
| ip header - internet protocol datagram                             |
|   version:              4                                          |
|   header length:        5  (20  bytes)                             |
|                                                                    |
|   ...............                                                  |
|                                                                    |
|   time to live:         128                                        |
|   protocol:             6  tcp - transmission control protocol     |
|   header checksum:      0xaa36                                     |
|   source ip address:    192.168.0.1  demo                          |
|   dest. ip address:     192.168.0.3  vi                            |
|   no ip options                                                    |
|                                                                    |
| tcp - transport control protocol                                   |
|   source port:          2342  manage-exec                          |
|   destination port:     21  ftp                                    |
|   sequence number:      2435440100                                 |
|   ack number:           9822605                                    |
|   offset:               5  (20  bytes)                             |
|   reserved:             %000000                                    |
|   flags:                %011000                                    |
|                         0. .... (no urgent pointer)                |
|                         .1 .... ack                                |
|                         .. 1... push                               |
|                         .. .0.. (no reset)                         |
|                         .. ..0. (no syn)                           |
|                         .. ...0 (no fin)                           |
|                                                                    |
|   window:               65150                                      |
|   checksum:             0x832a                                     |
|   urgent pointer:       0                                          |
|   no tcp options                                                   |
|                                                                    |
| ftp control - file transfer protocol                               |
|   line  1:              port 192,168,0,1,9,39<cr><lf>              |
|                                                                    |
| fcs - frame check sequence                                         |
|   fcs (calculated):     0xf4c04a4f                                 |
\====================================================================/

下图验证了服务器端的确从端口20打开到端口1663的tcp连接:
/====================================================================\
| tcp - transport control protocol                                   |
|   source port:          20  ftp-data                               |
|   destination port:     1663                                       |
|   sequence number:      2578824336                                 |
|   ack number:           0                                          |
|   offset:               6  (24  bytes)                             |
|   reserved:             %000000                                    |
|   flags:                %000010                                    |
|                         0. .... (no urgent pointer)                |
|                         .0 .... (no ack)                           |
|                         .. 0... (no push)                          |
|                         .. .0.. (no reset)                         |
|                         .. ..1. syn                                |
|                         .. ...0 (no fin)                           |
|                                                                    |
|   window:               3731                                       |
|   checksum:             0x8a4c                                     |
|   urgent pointer:       0                                          |
|   no tcp options                                                   |
|                                                                    |
| tcp options                                                        |
|   options type:         2   maxinum segment size                   |
|   length:               4                                          |
|   mss:                  1460                                       |
|                                                                    |
| fcs - frame check sequence                                         |
|   fcs (calculated):     0x5a1bd023                                 |
\====================================================================/

当使用ftp时候,网络中的防火墙必须要声明相应的端口,防火墙必须要跟踪ftp对话然后检查
port命令,防火墙必须要参与从服务器端到客户端在port命令中指定的端口连接的建立过程。
如果网络中使用了nat(注:网络地址翻译),那么nat的网关同样也需要声明相应的端口,网
关需要把在port命令中指定的ip地址翻译成分配给客户的地址,然后重新计算tcp的checksum
;如果网关没有正确地执行这个操作,ftp就失败了。

黑客可能会利用ftp支持第三方特性这一特点,在port命令中设置ip地址和端口号参数来指定
一台目标主机的地址和端口号(有时候称这种攻击为ftp反弹攻击),例如黑客可以让一台ftp
服务器不断地从它的源端口20发送tcp syn包给一系列目的端口,让ftp服务器看起来正在进行
端口扫描,目的主机不知道攻击来自黑客的主机,看起来攻击象是来自ftp服务器。一些常用的
ftp应用在port命令中设置地址为0.0.0.0,这样做的意图是让ftp服务器只需要与打开控制连接
的相同客户进行数据连接,设置地址为0.0.0.0可能会让防火墙不知所措。例如,cisco pix ios
6.0以上版本的pix(注:cisco硬件防火墙设备,6.0以上版本为其修正了相关的ftp协议)
要求数据连接的ip地址与已经存在的控制连接的ip地址必须相同。这样做的原因是防止黑客用
port命令来攻击别的机器,虽然一些ftp应用设置ip地址为0.0.0.0不是有意图的攻击,但在pi
x修正协议环境下的确引起了一些问题,同时对其他不允许第三方模式和避免ftp反弹攻击的防
火墙来说,这也会引起相同的问题。

>>2.2  ftp passive模式
下面的列表描述了passive模式的ftp的步骤,步骤1到3和port模式ftp相同,步骤9到11同样与
port模式ftp最后三步相同。

1、客户端发送一个tcp syn(tcp同步)包给服务器段众所周知的ftp控制端口21,客户端使
     用暂时的端口作为它的源端口;
2、服务器端发送syn ack(同步确认)包给客户端,源端口为21,目的端口为客户端上使用
     的暂时端口;
3、客户端发送一个ack(确认)包;客户端使用这个连接来发送ftp命令,服务器端使用这个
     连接来发送ftp应答;
4、当用户请求一个列表(list)或者发送或接收文件时候,客户端软件发送pasv命令给服务器端
     表明客户端希望进入passive模式;
5、服务器端进行应答,应答包括服务器的ip地址和一个暂时的端口,这个暂时的端口是客户端
     在打开数据传输连接时应该使用的端口;
6、客户端发送一个syn包,源端口为客户端自己选择的一个暂时端口,目的端口为服务器在pasv
     应答命令中指定的暂时端口号;
7、服务器端发送syn ack包给客户端,目的端口为客户端自己选择的暂时端口,源端口为pasv
     应答中指定的暂时端口号;
8、客户端发送一个ack包;
9、发送数据的主机以这个连接来发送数据,数据以tcp段(注:segment,第4层的pdu)形式发送(
     一些命令,如stor表示客户端要发送数据,retr表示服务器段发送数据),这些tcp段都需要
     对方进行ack确认;
10、当数据传输完成以后,发送数据的主机以一个fin命令来结束数据连接,这个fin命令需要另一
     台主机以ack确认,另一台主机也发送一个fin命令,这个fin命令同样需要发送数据的主机以a
     ck确认;
11、客户端能在控制连接上发送更多的命令,这可以打开和关闭另外的数据连接;有时候客户端结
     束后,客户端以fin命令来关闭一个控制连接,服务器端以ack包来确认客户端的fin,服务器
     同样也发送它的fin,客户端用ack来确认。

下图图示了passive模式ftp的开始几个步骤:
/====================================================================\
|                                                                    |
|       [ ftp client ]                       [ ftp server ]          |
|                                                                    |
|       (tcp:21 连接初始化,控制端口)                                    |
|                              syn                                   |
|        port xxxx   ---------------------->    port 21       [tcp]  |
|                             syn+ack                                |
|        port xxxx   <----------------------    port 21              |
|                              ack                                   |
|        port xxxx   ---------------------->    port 21              |
|                                                                    |
|       (pasv操作: 被动连接数据端口初始化)                               |
|                                                                    |
|                             pasv                                   |
|        port xxxx   ---------------------->    port 21              |
|                     pasv ok, ip, port yyyy                         |
|        port xxxx   <----------------------    port 21              |
|                               syn                                  |
|        port zzzz   ---------------------->    port yyyy            |
|                            syn+ack                                 |
|        port zzzz   <----------------------    port yyyy            |
|                               ack                                  |
|        port zzzz   ---------------------->    port yyyy            |
|                                                                    |
|                                                                    |
|        (数据操作: 数据传输)                                           |
|                       list, retr or stor                           |
|        port xxxx   ---------------------->    port 21              |
|                           data + ack                               |
|        port zzzz   <--------------------->    port yyyy            |
|                               .                                    |
|                               .                                    |
|                               .                                    |
|                                                                    |
\====================================================================/
一个pasv请求要求服务器在服务器选择的一个新的端口上接受数据连接,pasv命令没有任何参
数,服务器端的回应只是一行显示服务器ip地址和服务器接受连接的tcp端口号。

下图显示了服务器对pasv命令的回应,服务器告诉客户端它在端口5365(192,168,179,100,20
,245)上进行监听,计算端口的方法是20*256+245=5365;
/====================================================================\
| tcp - transport control protocol                                   |
|   source port:          21  ftp                                    |
|   destination port:     1249                                       |
|   sequence number:      4239887193                                 |
|   ack number:           36925357                                   |
|   offset:               5  (20  bytes)                             |
|   reserved:             %000000                                    |
|   flags:                %011000                                    |
|                         0. .... (no urgent pointer)                |
|                         .1 .... ack                                |
|                         .. 1... push                               |
|                         .. .0.. (no reset)                         |
|                         .. ..0. (no syn)                           |
|                         .. ...0 (no fin)                           |
|                                                                    |
|   window:               8760                                       |
|   checksum:             0x3eab                                     |
|   urgent pointer:       0                                          |
|   no tcp options                                                   |
|                                                                    |
| ftp control - file transfer protocol                               |
|   line  1:              pasv 192,168,0,1,100,20,245<cr><lf>        |
|                                                                    |
| fcs - frame check sequence                                         |
|   fcs (calculated):     0xbed4346d                                 |
\====================================================================/
当收到pasv命令的回应后,客户端打开一个tcp连接,源端口为一个暂时的端口,目的端口为
服务器提供的暂时端口。

下图显示了客户端的tcp连接建立过程,正如上面所说,目的端口为5365。
/====================================================================\
| tcp - transport control protocol                                   |
|   source port:          1250                
posted on 2010-01-05 00:53  康的瑞  阅读(412)  评论(0编辑  收藏  举报