引言 ftp 工作原理 FTP 客户端思考练习 网络程序设计 (FTP) 孙永科 西南林业大学 2010 年 9 月 17 日 1 / 29
引言 ftp 工作原理 FTP 客户端思考练习 要点回顾 1 ip 地址结构 2 字节顺序转换函数 3 IP 格式转换函数 2 / 29
引言 ftp 工作原理 FTP 客户端思考练习 本节重点 1 ftp 工作原理数据分析 TCPdump 过程分析 wireshark 过程分析 2 FTP 客户端主要过程 FTP 代码改进代码密码安全 3 思考练习 3 / 29
引言 ftp 工作原理 FTP 客户端思考练习数据分析 TCPdump 过程分析 wireshark 过程分析 FTP 工作原理 两种通信模式 1 主动 (active) 套接字 : 服务器主动把数据发给客户端 ; 2 被动 (passive) 套接字 : 服务器端将套接字配置为等待接入 ; 二者的不同在于应用程序的使用方式 ; 但是它们的创建方式是相同的 4 / 29
引言 ftp 工作原理 FTP 客户端思考练习数据分析 TCPdump 过程分析 wireshark 过程分析 active 模式通信实例 -ftp Server Client 20 21 1531 1532 data cmd cmd data 1 2 3 4 特点 两个命令端口之间的连接由客户端发起 ; 1 服务只打开固定的两个端口 20 和 21; 两个数据端口之间的连接由服务器发起 2 FTP 客户端随机开启一个大于 1024 的端口 N 向服务器的 21 号端口发起连接, 然后开放 N+1 号端口进行监听, 并向服务器发出 PORT N+1 命令 ; 3 服务器接收到命令后, 会用其本地的 FTP 数据端口 ( 通常是 20) 来连接客户端指定的端口 N+1, 进行数据传输 5 / 29
引言 ftp 工作原理 FTP 客户端思考练习数据分析 TCPdump 过程分析 wireshark 过程分析 passive 模式通信 -ftp 20 data Server 2004 data Client 21 1531 1532 cmd cmd data 1 2 3 4 特点 数据端口和命令端口之间的连接 均由客户端发起 1 服务只打开固定的端口 21; 2 FTP 库户端随机开启一个大于 1024 的端口 N 向服务器的 21 号端口发起连接, 同时会开启 N+1 号端口 3 然后向服务器发送 PASV 命令, 通知服务器自己处于被动 模式 4 服务器收到命令后, 会开放一个大于 1024 的端口 P 进行监听, 然后用 PORT P 命令通知客户端, 自己的数据端口是 P 5 客户端收到命令后, 会通过 N+1 号端口连接服务器的端口 P, 然后在两个端口之间进行数据传输 6 / 29
引言 ftp 工作原理 FTP 客户端思考练习数据分析 TCPdump 过程分析 wireshark 过程分析 数据分析工具 1 tcpdump prints out a description of the contents of packets on a network interface that match the boolean expression tcpdump [ -AdDefIKlLnNOpqRStuUvxX ] [ -B buffer_size ] [ -c count ] [ -C file_size ] [ -G rotate_seconds ] [ -F file ] [ -i interface ] [ -m module ] [ -M secret ] [ -r file ] [ -s snaplen ] [ -T type ] [ -w file ] [ -W filecount ] [ -E spi@ipaddr algo:secret, ] [ -y datalinktype ] [ -z postrotate-command ] [ -Z user ] [ expression ] 2 wireshark Wireshark is a GUI network protocol analyzer It lets you interactively browse packet data from a live network or from a previously saved capture file Wireshark s native capture file format is libpcap format, which is also the format used by tcpdump and various other tools 7 / 29
引言 ftp 工作原理 FTP 客户端思考练习数据分析 TCPdump 过程分析 wireshark 过程分析 TCPdump tcpdump 提供了很多的命令选项, 在这里我只简单介绍几个 : -A 将每个数据包以美国信息互换标准代码 ASCII 的格式打印出来 -c N 如果这个 N 是一个数字, 这个选项表示 tcpdump 将在 N 个数据包后退 出 -i interface 捕获指定网络端口的数据包 -n 不将地址进行解析 -q 提供较少的 ( 安静 ) 输出, 这样的输出路线会比较短 -r filename( 文件名 ): 从指定的文件而不是网络端口读取数据包 它经常用 在数据已经被记录到文件中的情况, 需要和 -w 的选项共同使用 -t 在输出每一行的时间不打印时间戳 -v 提供更详细的输出 V 可以增加, 象 -VV 甚至 -VVV -w filename( 文件名 ) 将数据包写到指定的文件中 Example 1 sudo tcpdump -ANntKlus0q 2 sudo tcpdump -ANntKlus0q -ieth0 8 / 29
引言 ftp 工作原理 FTP 客户端思考练习数据分析 TCPdump 过程分析 wireshark 过程分析 过程分析 1 16:35:47957917 IP 19216803851449 > 2181941069121: Flags [S], seq 3187462765, win 5840, op 2 tions [mss 1460,sackOK,TS val 4085830 ecr 0, nop,wscale 6], length 0 3 E<+@@&j[myG 4 >XF 8 16:35:48007860 IP 2181941069121 > 19216803851449: Flags [P], seq 290:323, ack 53, win 65483, options [nop, nop,ts val 14993194 ecr 4085842], length 33 9 EU @j[& 10 *>XR200 MLST OPTS Type;Size;Modify; 9 / 29
引言 ftp 工作原理 FTP 客户端思考练习数据分析 TCPdump 过程分析 wireshark 过程分析 过程分析 1 16:35:47957917 IP 19216803851449 > 2181941069121: Flags [S], seq 3187462765, win 5840, op 2 tions [mss 1460,sackOK,TS val 4085830 ecr 0,nop,wscale 6], length 0 3 E<+@@&j[myG 4 >XF 6 16:35:48007860 IP 2181941069121 > 19216803851449: Flags [P], seq 290:323, ack 53, win 65483, options [nop,nop,ts val 14993194 ecr 4085842], length 33 7 EU @j[& 8 *>XR200 MLST OPTS Type;Size;Modify; 10 16:35:48008142 IP 19216803851449 > 2181941069121: Flags [P], seq 53:67, ack 323, win 108, options [nop,nop,ts val 4085843 ecr 14993194], length 14 11 EB3@@&j[l! 12 >XS*USER jkxjxxz 14 16:35:48009464 IP 2181941069121 > 19216803851449: Flags [P], seq 323:359, ack 67, win 65469, options [nop,nop,ts val 14993195 ecr 4085843], length 36 15 EX @j[&b 16 +>XS331 User name okay, need password 18 16:35:48009811 IP 19216803851449 > 2181941069121: Flags [P], seq 67:80, ack 359, win 108, options [nop,nop,ts val 4085843 ecr 14993195], length 13 19 EA4@@&j[<l 20 >XS+PASS swfcxs 10 / 29
引言 ftp 工作原理 FTP 客户端思考练习数据分析 TCPdump 过程分析 wireshark 过程分析 wireshark 11 / 29
引言 ftp 工作原理 FTP 客户端思考练习数据分析 TCPdump 过程分析 wireshark 过程分析 12 / 29
引言 ftp 工作原理 FTP 客户端思考练习数据分析 TCPdump 过程分析 wireshark 过程分析 13 / 29
引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 过程总结 14 / 29
引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 FTP 过程 15 / 29
引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 FTP 代码 I 1 #include <stdioh> 2 #include <stdlibh> 3 #include <errnoh> 4 #include <sys/socketh> 5 #include <sys/ioctlh> 6 #include <netinet/inh> 7 #include <netdbh> 8 #include <stringh> 9 #include <signalh> 10 #include <sys/timeh> 11 #include <pollh> 12 #define SERVER_PORT 21 /* 服务器端口号 */ 13 #define MAXBUFSIZE 1024 /* 发送和接收缓存的最大长度 */ 15 char buff[maxbufsize]; /* 发送和接收缓存 */ 16 int main(int argc, char *argv[]) 17 { 18 int sockfd=0; /* 插口描述符 */ 19 struct sockaddr_in serveraddr; /* 服务器地址 */ 20 int mode=0; /* 阻塞模式 */ 22 if (argc <2) 23 { 24 printf( 使用方法 :tcp_client <server_ip_address>\n ); 25 exit(0); 26 } 27 for(;;) /* 循环等待连接成功 */ 28 { 29 /* 产生 TCP 插口 */ 16 / 29
引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 FTP 代码 II 30 if ((sockfd = socket(af_inet, SOCK_STREAM, 0)) < 0) 31 { 32 printf( 产生插口失败, 退出 \n ); 33 exit(1); 34 } 35 /* 填写服务器地址结构 */ 36 bzero((char *) &serveraddr, sizeof(struct sockaddr_in)); 37 serveraddrsin_family = AF_INET; 38 serveraddrsin_port = htons(server_port); 39 inet_aton(argv[1], &serveraddrsin_addr); 40 /* 发起连接请求 */ 41 if (connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) 42 { 43 printf( 连接请求失败 : errno=%d\n,errno); 44 close(sockfd); /* 重新建连, 必须重新产生新插口, 关闭原插口 */ 45 } 46 else{ 47 printf( 连接成功 \n ); 48 break; 49 } 50 } 52 while(1) 53 { 54 bzero(buff, sizeof(buff)); 56 if(recv(sockfd, buff, MAXBUFSIZE, 0)<=0) 57 { 58 printf( 接收失败, 程序退出, errno=%d\n,errno); 59 close(sockfd); 17 / 29
引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 FTP 代码 III 60 exit(2); 61 }else{ 62 printf( [%s]:%s\n,argv[1],buff); 64 } 65 printf( please input:\n ); 66 //bzero(buff, sizeof(buff)); 67 fgets(buff,sizeof(buff),stdin); 68 if (send(sockfd, buff, strlen(buff), 0) <= 0) 69 { 70 printf( 发送失败, 程序退出, errno=%d\n,errno); 71 close(sockfd); 72 exit(1); 73 } 74 } 75 close(sockfd); 76 return 1; 77 } $ /ftpclient 202203132241 连接成功 [202203132241]:220 Serv-U FTP Server v64 for WinSock ready Please input: USER syk // 程序在此卡住, 出现错误 18 / 29
引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 问题分析 正常的数据包 出错的数据包 解析 1 使用网络服务必须遵守协议规范 2 协议规范查看 RFC 文档 3 不公开的协议可以使用协议分析工具进行分析 19 / 29
引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 改进代码 printf( Please intpu:\n ); fgets(buff,sizeof(buff),stdin); strcat(buff, \r\n ); if (send(sockfd, buff, strlen(buff), 0) <= 0) 20 / 29
引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 密码找回 I 在知道用户名的情况下, 可以通过穷举的方法找回遗忘的密码, 即把有可能的密码都测试一遍 1 #include <stdioh> 2 #include <stdlibh> 3 #include <errnoh> 4 #include <sys/socketh> 5 #include <sys/ioctlh> 6 #include <netinet/inh> 7 #include <netdbh> 8 #include <stringh> 9 #include <signalh> 10 #include <sys/timeh> 11 #include <pollh> 12 /* 服务器端口号 */ 13 #define SERVER_PORT 21 21 / 29
引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 密码找回 II 14 /* 发送和接收缓存的最大长度 */ 15 #define MAXBUFSIZE 1024 17 char buff[maxbufsize]; /* 发送和接收缓存 */ 18 int main(int argc, char *argv[]){ 19 int sockfd=0; // 插口描述符 20 // 服务器地址 21 struct sockaddr_in serveraddr; 22 char PWD[50]; 24 if (argc <3){ 25 printf( 使用方法 :tcp_client < server_ip_address> <username>\n ); 26 exit(0); 27 } 28 for(;;){ /* 循环等待连接成功 */ 22 / 29
引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 密码找回 III 30 /* 产生 TCP 插口 */ 31 if ((sockfd = socket(af_inet, SOCK_STREAM, 0)) < 0){ 32 printf( 产生插口失败, 退出 \n ); 33 exit(1); 34 } 35 /* 填写服务器地址结构 */ 36 bzero((char *) &serveraddr, sizeof(struct sockaddr_in)); 37 serveraddrsin_family = AF_INET; 38 serveraddrsin_port = htons( SERVER_PORT); 39 inet_aton(argv[1], &serveraddrsin_addr); 40 /* 发起连接请求 */ 23 / 29
引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 密码找回 IV 41 if (connect(sockfd, (struct sockaddr *)& serveraddr, sizeof(serveraddr)) < 0){ 42 printf( 连接请求失败 : errno=%d\n,errno); 43 /* 重新建连, 必须重新产生新插口, 关闭原插口 */ 44 close(sockfd); 45 } 46 else{ 47 printf( 连接成功 \n ); 48 break; 49 } 50 } 52 while(1){ 53 bzero(buff, sizeof(buff)); 54 if(recv(sockfd, buff, MAXBUFSIZE, 0)<=0){ 24 / 29
引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 密码找回 V 55 printf( 接收失败, 程序退 出, errno=%d\n,errno); 56 close(sockfd); 57 exit(2); 58 } 59 printf( [%s]:%s\n,argv[1],buff); 61 if((strstr(buff, 220 ) buff)==0){ 62 // 登录成功, 输入用户名 63 sprintf(buff, USER %s\r\n,argv[2]); 64 } 65 else if((strstr(buff, 331 ) buff)==0){ 66 // 用户名验证通过, 输入密码 67 printf( please input the password: ); 68 fgets(pwd,sizeof(pwd),stdin); 69 sprintf(buff, PASS %s\r\n,pwd); 25 / 29
引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 密码找回 VI 70 } 71 else if((strstr(buff, 230 ) buff)==0){ 72 // 密码验证通过打印用户密码, 73 printf( the password is %s\n,pwd); 74 close(sockfd); 75 exit(0); 77 } 78 else if((strstr(buff, 530 ) buff)==0){ 79 // 验证失败, 重新开始验证 80 sprintf(buff, USER %s\r\n,argv[2]); 81 } 83 if (send(sockfd, buff, strlen(buff), 0) <= 0){ 26 / 29
引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 密码找回 VII 84 printf( 发送失败, 程序退 出, errno=%d\n,errno); 85 close(sockfd); 86 exit(1); 87 } 88 } 89 close(sockfd); 90 return 1; 91 } 27 / 29
讨论 引言 ftp 工作原理 FTP 客户端思考练习主要过程 FTP 代码改进代码密码安全 1 如何加快测试的速度 2 错误次数的限制问题 3 连接次数的限制问题 28 / 29
引言 ftp 工作原理 FTP 客户端思考练习 思考练习 1 连接 FTP 需要进行那些操作 2 active 与 passive 的区别 3 wireshark 如何捕获邮件的用户名 4 wireshark 捕获特定的数据 29 / 29