教你编程实现TFTP协议Word格式文档下载.docx
- 文档编号:17783201
- 上传时间:2022-12-10
- 格式:DOCX
- 页数:13
- 大小:99.91KB
教你编程实现TFTP协议Word格式文档下载.docx
《教你编程实现TFTP协议Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《教你编程实现TFTP协议Word格式文档下载.docx(13页珍藏版)》请在冰豆网上搜索。
最后一种TFTP报文类型是差错报文,它的操作码为5。
它用于服务器不能处理读请求或写请求的情况。
在文件传输过程中的读和写差错也会导致传送这种报文,接着停止传输。
差错编号字段给出一个数字的差错码,跟着是一个ASCII表示的差错报文字段,可能包含额外的操作系统说明的信息。
根据图一及上面的分析,我们可以得到以下定义:
#defineTFTP_RRQ01//读请求
#defineTFTP_WRQ02//写请求
#defineTFTP_DATA03//数据包
#defineTFTP_ACK04//确认包
#defineTFTP_ERROR05//错误代码
头文件结构也能很容易得到:
typedefstructtftphdr{
USHORTtu_opcode;
//操作码
union
{
USHORTtu_block;
//块号
USHORTtu_code;
//错误码
chartu_stuff[1];
//请求包填充物
}th_u;
charth_data[1];
//数据或错误字符串
}TFTP_HDR,*PTFTP_HDR;
二、TFTP服务器的实现
不知道大家对两年前的冲击波病毒Msblast.exe是否还有印象,该病毒通过RPC远程溢出漏洞溢出目标主机后,会绑定目标主机的4444端口,然后利用windows系统自带的tftp客户端程序发送下载消息,目标主机通过tftp下载病毒再运行病毒,反复循环导致更多的计算机受到感染。
因为windows系统并没有默认的TFTP服务端程序,所以此时的关键就在于Msblast.exe病毒本身就是个tfpt服务器。
至于TFTP服务器的实现,以前ww0830在《黑防》介绍过,为了满足大多数读者的要求,及关系到本文的完整性,我这里也给出具体实现,注意,本TFTP服务端只实现了供客户端程序下载的功能,更多的功能读者可以自己完善。
下面给出TFTP实现核心代码及详细注释
(注:
以下所有代码均在winxpsp1+vc6.0环境下编译通过,因为主要理解思路,省略了错误处理等步骤,完整源代码见附件内容):
初始化winsock库,注意在要加上ws2_32.lib库文件:
WSADATAWSAData;
WSAStartup(MAKEWORD(2,2),&
WSAData);
创建套接字
SOCKETsock=INVALID_SOCKET;
sock=socket(AF_INET,SOCK_DGRAM,0);
//这里用的是UDP协议,所以协议类型为//SOCK_DGRAM
初始化本地主机地址信息:
structsockaddr_inServerAddr;
ServerAddr.sin_family=AF_INET;
ServerAddr.sin_addr.s_addr=inet_addr(MyIp);
//MyIp为本主机IP
ServerAddr.sin_port=htons(69);
//TFTP服务器默认端口号
绑定套接字
bind(sock,(structsockaddr*)&
ServerAddr,sizeof(structsockaddr_in))
初始化远程地址信息
structsockaddr_inClient;
Client.sin_family=AF_INET;
Client.sin_port=htons(INADDR_ANY);
Client.sin_addr.s_addr=inet_addr(RemoteIp);
//远程IP地址
定义TFTP首部缓冲区
TFTP_HDRRecvBuff;
//接收的数据缓冲区
TFTP_HDRLocalBuff;
//本地数据缓冲区
接收数据,定义数据块大小为512字节:
intalen=sizeof(Client);
recvfrom(sock,(char*)&
RecvBuff,512,0,(structsockaddr*)&
Client,&
alen);
获得客户端的请求操作码
LocalBuff.tu_opcode=ntohs(RecvBuff.tu_opcode);
打开本地文件
fp=fopen("
abc.txt"
"
rb"
);
//假设abc.txt为服务器文件
读本地文件
fread(FileBuff,sizeof(char),512,fp);
填充TFTP首部
SendBuff.tu_opcode=htons(3);
//操作码3=data
SendBuff.th_u.tu_block=htons(time);
memcpy(&
(SendBuff.th_data),FileBuff,i);
//数据
发送文件给客户机(接收文件或数据类似)
sendto(sock,(char*)&
SendBuff,i+4,MSG_DONTROUTE,(structsockaddr*)&
Client,sizeof(Client));
整个简单的TFTP服务器这样就完成了,是不是很简单呐。
带外说一说,这里如果要模拟冲击波病毒的传播方式,程序最开始有个随机扫描的代码:
WSAStartup(MAKEWORD(2,2),&
SOCKADDR_INaddr;
sock=socket(AF_INET,SOCK_STREAM,0);
addr.sin_family=AF_INET;
addr.sin_port=htons(80);
//通过80端口是否开放判断对方主机是否存活
addr.sin_addr.s_addr=inet_addr(RemoteIp);
//这里的RemoteIp应该通过一
//个随机生成网段内IP地址的函数得到
if(connect(sock,(structsockaddr*)&
addr,sizeof(addr))<
0)
{
closesocket(sock);
WSACleanup();
return;
//连接失败,停止扫描
}
//通过gethostsocket()获取连出去的ip
structsockaddr_inhostname;
intnamelen=sizeof(hostname);
char*source;
getsockname(sock,(structsockaddr*)&
hostname,&
namelen);
source=inet_ntoa(hostname.sin_addr);
这一段代码的作用是循环连接网段内存活主机的80端口,如果发现某台主机存活,则蠕虫自身生成的TFTP服务器则接受被冲击波病毒溢出的客户端下载请求,复制自身到对方主机,如此恶性循环,导致蠕虫成级数性的扩散。
三、TFTP客户端的实现
通常情况下,windows2K以上操作系统都可以使用系统自带的TFTP客户端程序,但自从Msblast.exe蠕虫爆发后,很多用户都关掉了TFTP的默认使用。
对于很多学习入侵和渗透的人来说,这真是个噩耗^_^。
所以,通常很多木马或后门的设计者都在他们的作品里加入了FTP,Http下载,Email或TFTP客户端的功能,以加强对肉鸡的控制。
下面,我们就来分析一下TFTP的客户端实现。
TFTP客户端的实现主要体现在对TFTP各种数据包首部字段的分析及填充上。
下面给出了部分核心功能的伪代码,(具体代码可以参看附件里的源代码:
该代码作者为helloworld1,在此对他所提供的源代码表示万分感谢)
填充(读/写)请求字段,根据图一,可以得到下面的读/些请求数据包格式:
图二:
RRQ/WRQ包格式
于是,定义一个makereq()函数来填充请求字段:
intmakereq(chartype,intmode,char*filename,char*buffer,intsize)
{
intpos=0;
//位置
inti=0;
chars[32]="
"
;
if(mode==TFTP_NETASCII)//传输模式
strcpy(s,"
netascii"
);
else
octet"
buffer[pos]=0;
pos++;
buffer[pos]=type;
//Opcode=01(RRQ)or02(WRQ)
for(i=0;
i<
strlen(filename);
i++)//&
buffer[3]=Filename
buffer[pos]=filename[i];
}
//0
strlen(s);
i++)//Mode
buffer[pos]=s[i];
returnpos;
//返回请求包头长度
}
下面为ACK包格式及填充地段函数makeack():
图三:
ACK包格式
intmakeack(unsignedshortnum,char*buffer,intsize)
buffer[pos]=TFTP_ACK;
//Opcode=04
buffer[pos]=(char)(num>
>
8);
//块号2个字节
buffer[pos]=(char)num;
同理,DATA包格式及填充函数makedata()如下:
图四:
DATA包格式
intmakedata(intnum,char*data,intdatasize,char*buffer,intbufsize)
buffer[pos]=TFTP_DATA;
//Opcode=03
//Block#块号
memcpy(&
buffer[pos],data,datasize);
//Data数据
pos=pos+datasize;
实现下载文件,cmd[][256]为自定义的参数数据结构,pcount为参数个数:
voidgetfile(charcmd[][256],intpcount)
charsendbuf[1024]={0};
//发送的请求包
charrecvbuf[1024]={0};
sockaddr_inaddr;
//本机网络地址信息
sockaddr_infrom;
//服务器网络地址信息
intfromlen=0;
intret=0;
intlen=0;
fd_setfdr;
//套接字的“读”集
intretry=0;
//重试次数
structtimevaltimeout={5,0};
//超时设置5秒
intstat=0;
intlastdata=0;
FILE*file;
intflen=0;
//总的数据或文件大小
intc;
if(pcount!
=1)
printf("
usage:
getfilename\n"
return;
if((file=fopen(cmd[1],"
r"
))!
=NULL)//判断所下载的文件是否已存在
printf("
File%salreadyexits,overwrite?
y/n"
cmd[1]);
while(true)
c=getch();
if('
Y'
==toupper(c))//覆盖
\n"
fclose(file);
break;
elseif('
N'
==toupper(c))//不覆盖,返回
w+b"
))==NULL)
Can'
tcreatefile\n"
return;
//填充读(下载)请求字段
len=makereq(TFTP_RRQ,fMode,cmd[1],sendbuf,sizeof(sendbuf));
addr.sin_family=AF_INET;
from.sin_family=AF_INET;
addr.sin_port=htons(69);
addr.sin_addr.s_addr=inet_addr(desthost);
ret=sendto(sock,sendbuf,len,0,(sockaddr*)&
addr,sizeof(addr));
FD_ZERO(&
fdr);
FD_SET(sock,&
ret=select(sock,&
fdr,NULL,NULL,&
timeout);
if(SOCKET_ERROR==ret)
Socketerror\n"
elseif(0==ret)//超时
if(MAX_RETRY==retry)//达到了尝试次数MAX_RETRY=3
TimeOut\n"
sendto(sock,sendbuf,len,0,(sockaddr*)&
retry++;
if(FD_ISSET(sock,&
fdr))
retry=0;
fromlen=sizeof(sockaddr);
//接收数据或文件
ret=recvfrom(sock,recvbuf,sizeof(recvbuf),0,(sockaddr*)&
from,&
fromlen);
if(TFTP_ERROR==recvbuf[1])
fclose(file);
Error%d:
%s\n"
recvbuf[3],&
recvbuf[4]);
return;
if(0==stat)
addr.sin_port=from.sin_port;
stat=1;
if(TFTP_DATA==recvbuf[1])
lastdata=recvbuf[2]*256+recvbuf[3];
//填充确认字段
len=makeack(lastdata,sendbuf,sizeof(sendbuf));
//#defineTFTP_NOTEND_DATALEN512+2+2
//后面的2+2是确认数据包头的操作码(2个字节)+块号(2个字节)
if(ret<
TFTP_NOTEND_DATALEN)
{
//已经是最后的包块
fwrite(&
recvbuf[4],1,ret-4,file);
flen=flen+ret-4;
printf("
total%dbytereceived\n"
flen);
}
//不是最后的包块
fwrite(&
recvbuf[4],1,512,file);
flen=flen+512;
%dbytereceived\r"
}
}(致编者:
后门6个括号…呵呵)
代码的注释很清楚,其实结合文章开始的理论及图,再实现就很简单了。
至于上传(put)文件和下载类似,由于篇幅的原因,大家可以参看源代码。
实现效果:
首先,tftpServer.exe为我们第2部分介绍实现的TFTP服务端程序,在该程序的同级目录下放一个名为“abc.txt”的文件,运行tftpd.exe。
然后,运行第3部分介绍的TFTP客户端程序tftpClient.exe,并输入命令
#getabc.txt
实验截图如下:
图五:
tftpServer.exe
图六:
tftpClient.exe
总结:
对于学习网络知识也好,学习黑客技术也罢,对于TCP/IP协议的掌握是重中之重,本文讨论虽然只是简单讨论TFTP协议的相关理论及实现,但稍微复杂一点的FTP协议,POP3协议,SNMP协议也都可以通过类似的分析来实现的。
本人水平有限,本文给出都是思路,实现都简单的不能再简单。
如有不对之处,请大家给予批评指正。
招商银行一卡通号码:
002821026284
本人地址:
成都市四川大学望江校区东区三教五楼信息安全研究所
本人姓名:
古开元。
邮编:
610064
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编程 实现 TFTP 协议