+ -
当前位置:首页 → 问答吧 → 关于内核数据包劫持、修改、转发的问题

关于内核数据包劫持、修改、转发的问题

时间:2010-06-15

来源:互联网

我们想在a(192.168.1.204)连接b(192.168.1.200)时,欺骗a,让a于c(192.168.1.202)相连。当我们把自己的模块挂上以后,源目的的ip和 mac都修改了(192.168.1.200被修改成了192.168.1.202,对应mac修改正确),但是通过wireshark观察数据包发现,ping能正常使用;用ssh连接时,第一个syn报文能够发送到c,但是c没有回应。下面是我们些的代码,能帮忙看看是什么问题吗?谢谢了。
  1. /*#define _KERNEL_*/
  2. #include <linux/module.h>
  3. #include <linux/kernel.h>
  4. #include <linux/netfilter.h>
  5. #include <linux/skbuff.h>
  6. #include <linux/ip.h>
  7. #include <linux/netdevice.h>
  8. #include <linux/if_ether.h>
  9. #include <linux/if_packet.h>
  10. #include <net/tcp.h>
  11. #include <linux/netfilter_ipv4.h>


  12. #include <linux/timer.h>
  13. #include <net/xfrm.h>
  14. #include <linux/netdevice.h>
  15. #define NF_IP_PRE_ROUTING        0
  16. #define NF_IP_FORWARD  2
  17. static struct nf_hook_ops nfho;


  18. unsigned int hook_func(unsigned int hooknum,
  19.                        struct sk_buff *skb,
  20.                        const struct net_device *in,
  21.                        const struct net_device *out,
  22.                        int (*okfn)(struct sk_buff *))
  23. {
  24.     struct sk_buff *sb = skb;
  25.     unsigned char src_ip[4],src_mac[6];
  26.     unsigned char des_ip[4],des_mac[6];
  27.     *(unsigned int *)src_ip = ip_hdr(sb)->saddr;
  28.     *(unsigned int *)des_ip= ip_hdr(sb)->daddr;
  29.         unsigned int tcphoffset;
  30.         struct tcphdr*tcph;
  31.         int ret;
  32.         tcphoffset=0;
  33.     if(des_ip[0]==192&&des_ip[1]==168&&des_ip[2]==1&&des_ip[3]==200)  //将目的地址是192.168.1.200的数据包截获下来,将目的地址改为202,同时修改目的地址的mac
  34.         {
  35.             des_ip[0]=192;
  36.                 des_ip[1]=168;
  37.                 des_ip[2]=1;
  38.                 des_ip[3]=202;
  39.                 memcpy(&ip_hdr(sb)->daddr,des_ip,4);
  40.                
  41.                 des_mac[0]=0x00;
  42.                 des_mac[1]=0x16;
  43.                 des_mac[2]=0x3e;
  44.                 des_mac[3]=0x7b;
  45.                 des_mac[4]=0x32;
  46.                 des_mac[5]=0xef;
  47.                 memcpy(eth_hdr(sb)->h_dest,des_mac,6);
  48.                 if(ip_hdr(sb)->protocol == IPPROTO_TCP){//如果接到的数据包是tcp包,重新计算tcp校验和
  49.                                 tcph = tcp_hdr(sb);
  50.                                   tcphoffset = ip_hdr(sb)->ihl * 4;

  51.                                   sb->csum = 0;
  52.                                   sb->csum = skb_checksum (sb, tcphoffset, sb->len - tcphoffset, 0);
  53.                                  
  54.                                 tcph->check=0;
  55.                                 tcph->check=tcp_v4_check(sb->len-tcphoffset,ip_hdr(sb)->saddr,ip_hdr(sb)->daddr,csum_partial(tcph,sb->len-tcphoffset,0));

  56.                 }       
  57.                 ip_hdr(sb)->check=0;//计算ip校验和
  58.                 ip_hdr(sb)->check    = ip_fast_csum((void *) ip_hdr(sb), ip_hdr(sb)->ihl);
  59.         }
  60.         if(src_ip[0]==192&&src_ip[1]==168&&src_ip[2]==1&&src_ip[3]==202)//取出源地址为192.168.1.202的数据包,将源地址改为192.168.1.200,同时修改目的mac
  61.         {
  62.             src_ip[0]=192;
  63.                 src_ip[1]=168;
  64.                 src_ip[2]=1;
  65.                 src_ip[3]=200;
  66.                 memcpy(&ip_hdr(sb)->saddr,src_ip,4);
  67.                
  68.                 src_mac[0]=0x00;
  69.                 src_mac[1]=0x16;
  70.                 src_mac[2]=0x36;
  71.                 src_mac[3]=0x6a;
  72.                 src_mac[4]=0x55;
  73.                 src_mac[5]=0x5d;
  74.                 memcpy(eth_hdr(sb)->h_source,src_mac,6);
  75.                 if(ip_hdr(sb)->protocol == IPPROTO_TCP){//如果是tcp包,计算tcp的校验和
  76.                                 tcph = tcp_hdr(sb);
  77.                                   tcphoffset = ip_hdr(sb)->ihl * 4;
  78.                                   sb->csum = 0;
  79.                                   sb->csum = skb_checksum (sb, tcphoffset, skb->len - tcphoffset, 0);
  80.                                 tcph->check=0;
  81.                                 tcph->check=tcp_v4_check(sb->len-tcphoffset,ip_hdr(sb)->saddr,ip_hdr(sb)->daddr,csum_partial(tcph,sb->len-tcphoffset,0));

  82.                                
  83.                 }
  84.                 ip_hdr(sb)->check=0;//计算ip校验和
  85.                 ip_hdr(sb)->check  = ip_fast_csum((void *) ip_hdr(sb), ip_hdr(sb)->ihl);       
  86.         }
  87.         skb_push(sb , ETH_HLEN);

  88.         /*直接调用该函数,将数据包从网卡上发送出去*/

  89.          ret = dev_queue_xmit(sb);
  90.    // nf_reset(sb);
  91.     //netif_rx(sb);
  92.     return NF_STOLEN;         
  93. }


  94. int init_module()
  95. {
  96.   
  97.     nfho.hook = hook_func;         
  98.     nfho.hooknum  = NF_IP_PRE_ROUTING;
  99.     nfho.pf       = PF_INET;
  100.     nfho.priority = NF_IP_PRI_FIRST;

  101.     nf_register_hook(&nfho);

  102.     return 0;
  103. }

  104. void cleanup_module()
  105. {
  106.     nf_unregister_hook(&nfho);
  107. }
复制代码

作者: jhl19880722   发布时间: 2010-06-15

上面的代码,我在NF_IP_LOCAL_IN上面能够正常的运行。但是在 NF_IP_PRE_ROUTING不行,我用wireshark查看接受到的数据包,同时打印出来在程序中接收到的数据包,发现接收到的数据包和wireshark捕获到的不一样,用wireshark在不同位置上捕获,确定是接收到的不对。有谁知道原因

作者: jhl19880722   发布时间: 2010-08-12

LZ 你的模块挂载到那台机子上了?

作者: Godbach   发布时间: 2010-08-12

你需要同时修改prerouting 和output,
并且你要iptable -F
清掉 Iptables规则。

作者: souldemo   发布时间: 2010-08-12

热门下载

更多