免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 8097 | 回复: 10
打印 上一主题 下一主题

[网络子系统] 自己构造tcp报文,三次握手已经通过,但是发送数据报文时,客户端重传 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-07-31 00:22 |只看该作者 |倒序浏览
应该是客户端认为发过来的数据报文(http 重定性)是无效的,所以重传了报文,
我看了下 报文里面的SEQ和ACK_SEQ都是没有问题的,请高手帮我看看是哪个字段出了问题?
抓包见附件,是第28个报文

error.tar

10 KB, 下载次数: 47

论坛徽章:
0
2 [报告]
发表于 2012-07-31 09:05 |只看该作者
回复 1# u2001


    不是源码?把代码贴出来分析一下吧,

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
3 [报告]
发表于 2012-07-31 09:40 |只看该作者
回复 1# u2001
你构造了什么样的报文


   

论坛徽章:
0
4 [报告]
发表于 2012-07-31 22:30 |只看该作者
回复 3# Godbach


   构造了两个报文
1.收到SYN后,构造tcp SYN+ACK报文,这个没问题,客户端收到后已经回应ACK了;
2.收到push+ack数据报文后,回应tcp报文FIN+PUSH+ACK数据报文(其实就是http重性),

有问题的报文见抓包的第28个(就是第1个FIN+PUSH+ACK报文,后来客户端就重传了),可以先用tcp过滤一下.

论坛徽章:
0
5 [报告]
发表于 2012-07-31 22:34 |只看该作者
static int skb_clone_xmit( struct sk_buff *pskb, const struct net_device *in )
{
        int retval = 0;
        struct sk_buff *nskb;
        struct iphdr *oiph;
        struct tcphdr *tcph;
        unsigned char eth_addr[ETH_ALEN];
        struct ethhdr *oeth;
        __be32 addr;
        __be16 port;
        u32 tcplen;


        oiph = ip_hdr( pskb );
        tcph = (struct tcphdr *)((u_int32_t *)oiph + oiph->ihl);



       if(ntohs(tcph->dest) != 80)
       {

          return -1;
       }
        nskb = skb_clone(pskb, GFP_ATOMIC);

        if ( !nskb ) {
                printk( "skb_clone occur error!\n" );
                return -1;
        }

        nskb->pkt_type = PACKET_OUTGOING; //OUTGOING;

        nskb->dev = (struct net_device *)in;
        print_block(pskb->data - ETH_HLEN,ETH_HLEN);
        nskb->data = skb_mac_header(nskb);
        nskb->len += ETH_HLEN;
        ALERT("nskb->len is %d \r\n", nskb->len);
         //mac
        if (pskb->mac_header != NULL) {

            oeth = (struct ethhdr *)nskb->mac_header;
            memcpy( eth_addr, oeth->h_source, ETH_ALEN );
            memcpy( oeth->h_source, oeth->h_dest, ETH_ALEN );
            memcpy( oeth->h_dest, eth_addr, ETH_ALEN );
        }
        oeth = skb_mac_header(pskb);

        oiph = ip_hdr(nskb );
        tcph = (struct tcphdr *)((u_int32_t *)oiph + oiph->ihl);

        addr = oiph->daddr;
        oiph->daddr = oiph->saddr;
        oiph->saddr = addr;

        ALERT("IP packet with packet from %d.%d.%d.%d to %d.%d.%d.%d\r\n",NIPQUAD(oiph->saddr),NIPQUAD(oiph->daddr));
        // tcp

        port = tcph->source;
        tcph->source = tcph->dest;
        tcph->dest = port;
        //memset(nskb->data,0xff,6);
    if(tcph->ack && !(tcph->psh))
    {
       return 0;

    }
    else if(tcph->syn){
        tcph->ack_seq = htonl( ntohl(tcph->seq) + 1 );
        tcph->seq = 0;
      
        tcph->ack = 1;
     }
  else if(tcph->psh)
   {
        unsigned int recv_len =  nskb->len - ETH_HLEN - sizeof(struct iphdr) - 32;
        unsigned int ack_seq = ntohl(tcph->ack_seq);
        tcph->ack_seq = htonl( ntohl(tcph->seq) + recv_len);
        tcph->seq = htonl(ack_seq);
        ALERT("recevie http request rec_len = %d ~~~~~~~~~~~~~~~~~~~~",recv_len);
        tcph->fin = 1;
         tcph->window = htons(930);
        char *buf = nskb->data + ETH_HLEN+sizeof(struct tcphdr)+sizeof(struct iphdr);
        memcpy(buf,content,strlen(content));
        nskb->len = ETH_HLEN+sizeof(struct iphdr)+sizeof(struct tcphdr) + strlen(content);
        nskb->len =ETH_HLEN+sizeof(struct iphdr)+sizeof(struct tcphdr);
        oiph->tot_len = htons(nskb->len - ETH_HLEN);
        oiph->id = htons(273;
        oiph->ttl = 255 ;
   }        

        ALERT("IP packet with packet from %d to %d\r\n",ntohs(tcph->source),ntohs(tcph->dest));
        if(tcph->syn)
            tcplen = ntohs( oiph->tot_len ) - oiph->ihl * 4;
        else
        {
            tcplen = sizeof(struct tcphdr)+strlen(content);
            tcph->doff = sizeof(struct tcphdr)>>2;
        }
        ALERT("tcplen %d nskblen %d\r\n",tcplen,nskb->len);
        tcph->check = 0;
        tcph->check = tcp_v4_check( tcplen,
                              oiph->saddr, oiph->daddr,
                              csum_partial(tcph,
                                          tcplen, 0));
        ip_send_check( oiph );

        retval = dev_queue_xmit(nskb);
        printk( "dev_queue_xmit return %d\n", retval );
        return retval;
}

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
6 [报告]
发表于 2012-08-01 14:18 |只看该作者
回复 4# u2001
你说的是 HTTP 的重定向吗?

   

论坛徽章:
0
7 [报告]
发表于 2012-08-01 19:06 |只看该作者
回复 6# Godbach


    是啊,这个重定性报文,客户端不认,所以重发了tcp报文,看不出哪个字段填的有问题.

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
8 [报告]
发表于 2012-08-02 09:41 |只看该作者
回复 7# u2001

如果只是 http 重定向的话,你没有必要修改三次握手,直接修改 GET 请求应该就可以吧。

修改 TCP 报文,要检查 seq 和 ack_seq 是否都正确的调整好了,还有校验和的修改。

   

论坛徽章:
0
9 [报告]
发表于 2012-08-02 16:05 |只看该作者
回复 8# Godbach


    如果主机中没有http端口的话,是无法完成握手的;
   我的SYN+ACK报文没问题 ,就是发重定性的报文客户端不认,重定性也是按照你的方法封装的,抓包和代码见上面,wireshark分析校验和是没有问题的 ,
  请帮忙看一下这两个序列号或者窗口之类的值是否有问题.

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
10 [报告]
发表于 2012-08-02 17:12 |只看该作者
本帖最后由 Godbach 于 2012-08-02 17:12 编辑

回复 9# u2001

如果目标 IP 是你的机器的话,你是应该开启 80 端口的。比如作为代理的设备。

否则,如果是转发设备,你只想干涉一下 GET 请求,让他进行重定向,那你没有必要修改三次握手。只需要修改 GET 请求即可。

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP