windows下使用winpcap修改数据包,重定向tcp连接

lzwml 2010-10-29 09:03:53
局域网里有3台计算机A、B、C其中A上运行抓包程序监控其余机台计算机通讯情况,A、B、C上运行我以前写的C/S程序,B、C运行的是Server,A运行的是Client。
我的工作是检测到当A向B发起3次握手连接请求的第一个数据包时,把这个数据包的目的地址修改成C的地址,然后发送出去,实现A与C的连接。判断是否是三次握手的第一个数据包我的依据是,tcp头里的ack为0。在C上运行wireshark的确看到我修改的数据包,但是没见到C上的Server有什么反映。
A:192.168.123.36
B:192.168.123.101
C:192.168.123.102
部分代码如下:
//winpcap回调函数
void protocol_packet_callback(
u_char *argument,
const struct pcap_pkthdr *packet_header,
const u_char *packet_content)
{
static long olddstip = inet_addr("192.168.123.101");//旧的目的地址,B的
static long dstip = inet_addr("192.168.123.102"); //新的目的地址,C的
static long srcip = inet_addr("192.168.123.36"); //原来的源地址,A的
static u_char dstmac[] = {0x00,0x88,0x99,0x80,0xbd,0xc3};//B的物理地址地址

if(ptcp->tcp_acknowledgement == 0 && //3次握手第一次连接
pip->ip_souce_address.S_un.S_addr == srcip && //且原来源地址是A
pip->ip_destination_address.S_un.S_addr == olddstip) {//且原目的地址是B
//定位各个协议头指针位置
u_char *ppacket;
ether_header *pether;
ip_header *pip;
tcp_header *ptcp;

ppacket = (u_char*)packet_content;
pether = (ether_header*)(ppacket);
pip = (ip_header*)(ppacket+sizeof(ether_header));
ptcp = (tcp_header*)(ppacket+sizeof(ether_header)+sizeof(ip_header));

memmove(pether->ether_dhost,dstmac,6);//B的物理地址写成C的物理地址
pip->ip_destination_address.S_un.S_addr = dstip;//B的IP地址写成C的IP地址
pip->ip_checksum = 0;//计算校验和,下面的函数我保证没有错误
pip->ip_checksum = ( checksum((unsigned short*)(packet_content+14),
sizeof(ip_header)/sizeof(unsigned short)) );

//发送出去
pcap_sendpacket(mydev,(u_char*)packet_content,packet_header->len);

}
//*******无关内容*****比如伪造A向B发送关闭连接操作数据包
}
实际上我怕原来的B在我之前应答了A,所以我在B上没有运行Server程序,B仅仅开机而已。
我不知道问题出在哪里,是我还有什么地方需要修改的,还是跟A上运行的Client有关,三次握手是由connect函数实现的,
int connect(
SOCKET s,
const struct sockaddr* name,
int namelen
);
莫非函数里对第二次握手的源地址(C的)与sockaddr里的地址(B的)是否一致做了判断?我成了非法连接?
...全文
2044 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
vincent_1011 2010-10-31
  • 打赏
  • 举报
回复
本来winpcap就是肯定能发包和监听接收到的包的
lzwml 2010-10-31
  • 打赏
  • 举报
回复
问题解决
printf("before \t%x %x \n",pip->ip_checksum,ptcp->tcp_checksum);

u_short tcpSize;//tcp数据包长度,
tcpSize = htons(pip->ip_length)- sizeof(tcp_header);//tcp其中最后8个字节的选项是可选的
sdheader.tcpl = htons(tcpSize);

//计算tcp校验和
ptcp->tcp_checksum = 0;
memcpy(SendBuf,&sdheader,sizeof(psd_header));
memcpy(SendBuf + sizeof(psd_header),(ppacket+TCP_STAR),tcpSize);
ptcp->tcp_checksum = ComputeChecksum((USHORT *)SendBuf,sizeof(psd_header)+tcpSize);

printf("end \t%x %x \n",pip->ip_checksum,ptcp->tcp_checksum);
结贴给分
lzwml 2010-10-31
  • 打赏
  • 举报
回复
我发现问题所在了,是tcp在计算校验和时候有个伪首部。
校验内容:伪首部+tcp头+tcp数据。因为SYN数据包tcp数据区域是空,所以tcp数据长度是0。

现在我计算的结果和原来的仍然不同。
//sdheader是伪首部
unsigned short SendBuf[100];
sdheader.saddr = htonl(pip->ip_souce_address.S_un.S_addr);
sdheader.daddr = htonl(pip->ip_destination_address.S_un.S_addr);
sdheader.mbz = 0;
sdheader.ptcl = 0x06;
sdheader.tcpl = sizeof(tcp_header);

ptcp->tcp_checksum = 0;
memcpy(SendBuf,&sdheader,sizeof(psd_header)); //伪头
memcpy(SendBuf + sizeof(psd_header),(ppacket+TCP_STAR),sizeof(tcp_header));//tcp头
ptcp->tcp_checksum = ComputeChecksum((USHORT *)SendBuf,sizeof(psd_header)+sizeof(tcp_header)); //计算
lzwml 2010-10-30
  • 打赏
  • 举报
回复
刚刚再次证明winpcap发送数据包没有任何问题,我用A与C连接成功后,然后记录下A发送的第一个数据包内容。
再写一个发送数据包的程序,把刚才的内容发送出去,结果发送成功,C方也有反映。

其实我需要一些【简单的理论】就可以成功了。
肯定是我有什么地方需要修改的而没有修改,可能ip头的identification部分也需要修改。
谁给我点理论。。。。。
lzwml 2010-10-29
  • 打赏
  • 举报
回复
至于你说的什么层次驱动我不是怎么清楚,以前在论坛上曾经看到过说windows对自己构造的tcp数据包有限制,好像是为了安全把,我不懂是怎么回事。
至于winpcap能不能发送数据包这个我原来测试过,不过发送的不是tcp而是arp,成功修改了另一台计算机的arp表。
vincent_1011 2010-10-29
  • 打赏
  • 举报
回复
我意思就是监听

照理说windows上你一般通信是用tcp/ip协议驱动发来送数据的,而你自己的协议驱动(winpcap)是和tcp/ip协议驱动是同一个级别的。这时你发送的数据通过tcp/ip协议驱动发送的,所以你自己的协议驱动是应该感应不到的/
lzwml 2010-10-29
  • 打赏
  • 举报
回复
我没有拦截原来的数据(A->B),B这时没有运行Server所以不会应答A,我获取到这个数据包后做小小的修改再发到网络上,同时在C上我看到了自己修改的数据包,但是C上的Server没有反映,连接不成功。
在windows下winpcap是可以完成抓取数据包(不是拦截)和发送功能
vincent_1011 2010-10-29
  • 打赏
  • 举报
回复
奇怪了,winpcap是协议驱动啊,不能拦截数据的,照你这么说,如果你不发送出去难道原本的数据就不能发送出去了?
lzwml 2010-10-29
  • 打赏
  • 举报
回复
static u_char dstmac[] = {0x00,0x88,0x99,0x80,0xbd,0xc3};//B的物理地址地址
写错了
应写成
static u_char dstmac[] = {0x00,0x88,0x99,0x80,0xbd,0xc3};//C的物理地址地址

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧