免费注册 查看新帖 |

Chinaunix

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

[求助]关于使用NetFilter Hook进行FTP地址伪装的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-04-22 15:29 |只看该作者 |倒序浏览
各位:

我想利用Linux内核中的NetFilter提供的Hook函数实现FTP地址伪装。
基本想法是:
1、在数据包即将离开本机之前设置Hook,对特定的数据包(FTP)进行编辑
2、编辑内容:将源IP地址(本机地址)改成伪装地址,重新计算checksum
3、编辑完成后让该数据包继续在网路上传播
4、由于MAC地址是正确的,所以本机理论上应该能收到FTP服务器的答复
5、在数据包到达本机的时候设置Hook,对特定的数据包(FTP)进行编辑
6、编辑内容:将目标IP地址(伪装地址)改成本机地址,重新计算checksum
7、编辑完成后让将数据包继续交给下一个协议层

源代码如下:


  1. #include <linux/module.h>;
  2. #include <linux/kernel.h>;
  3. #include <linux/skbuff.h>;
  4. #include <linux/if_ether.h>;
  5. #include <linux/ip.h>;
  6. #include <linux/tcp.h>;
  7. #include <linux/in.h>;
  8. #include <linux/netfilter.h>;
  9. #include <linux/netfilter_ipv4.h>;
  10. #include <linux/netdevice.h>;
  11. #include <net/tcp.h>;
  12. #include <asm/checksum.h>;

  13. MODULE_AUTHOR("SKY <skywjf@hotmail.com>;");
  14. MODULE_DESCRIPTION("NerFilter Hook Reserch Test");
  15. #ifdef MODULE_LICENSE
  16. MODULE_LICENSE("GPL");
  17. #endif /* MODULE_LICENSE */

  18. static char local_ip[] = { 0xc0, 0xa8, 0x03, 0x78 };  /* 192.168.3.120 */
  19. static char target_ip[] = { 0xc0, 0xa8, 0x03, 0x3c }; /* 192.168.3.60 */
  20. static char foo_ip[] = { 0xc0, 0xa8, 0x03, 0x6f };  /* 192.168.3.111 */

  21. /*
  22. * ip_post_fn
  23. * out packet hook function:
  24. * catch the out ftp packet, change the source IP to foo.
  25. */
  26. unsigned int
  27. ip_post_fn(unsigned int hooknum,
  28.            struct sk_buff **skb,
  29.            const struct net_device *in,
  30.            const struct net_device *out, int (*okfn) (struct sk_buff *))
  31. {
  32.   struct sk_buff *sb = *skb;
  33.   struct iphdr *ihead = (struct iphdr *)sb->;nh.iph;
  34.   struct tcphdr *thead = (struct tcphdr *)((unsigned int *)ihead + ihead->;ihl);

  35.   /* is a ftp packet to target host? */
  36.   if (ihead->;saddr != *(unsigned int *)local_ip ||
  37.       ihead->;daddr != *(unsigned int *)target_ip ||
  38.       ihead->;protocol != IPPROTO_TCP || thead->;dest != htons(21)) {
  39.     return NF_ACCEPT;
  40.   }

  41.   /* change it */
  42.   ihead->;saddr = *(unsigned int *)foo_ip; /* fooip */
  43.   thead->;check = 0;
  44.   thead->;check =
  45.     tcp_v4_check(thead, sb->;len - ihead->;ihl * 4, ihead->;saddr, ihead->;daddr,
  46.                  csum_partial((char *)thead, sb->;len - ihead->;ihl * 4, 0));
  47.   ihead->;check = 0;
  48.   ihead->;check = ip_fast_csum((unsigned char *)ihead, ihead->;ihl);

  49.   return NF_ACCEPT;
  50. }


  51. /*
  52. * ip_pre_fn
  53. * in packet hook function:
  54. * catch the in ftp packet, change the dest IP.
  55. */
  56. unsigned int
  57. ip_pre_fn(unsigned int hooknum,
  58.           struct sk_buff **skb,
  59.           const struct net_device *in,
  60.           const struct net_device *out, int (*okfn) (struct sk_buff *))
  61. {
  62.   struct sk_buff *sb = *skb;
  63.   struct iphdr *ihead = (struct iphdr *)sb->;nh.iph;
  64.   struct tcphdr *thead = (struct tcphdr *)((unsigned int *)ihead + ihead->;ihl);

  65.   if (ihead->;saddr != *(unsigned int *)target_ip ||
  66.       ihead->;daddr != *(unsigned int *)foo_ip ||
  67.       ihead->;protocol != IPPROTO_TCP || thead->;source != htons(21)) {
  68.     return NF_ACCEPT;
  69.   }

  70.   ihead->;daddr = *(unsigned int *)local_ip; /* fooip */
  71.   thead->;check = 0;
  72.   thead->;check =
  73.     tcp_v4_check(thead, sb->;len - ihead->;ihl * 4, ihead->;saddr, ihead->;daddr,
  74.                  csum_partial((char *)thead, sb->;len - ihead->;ihl * 4, 0));
  75.   ihead->;check = 0;
  76.   ihead->;check = ip_fast_csum((unsigned char *)ihead, ihead->;ihl);

  77.   return NF_ACCEPT;
  78. }


  79. static struct nf_hook_ops ip_post_ops =
  80.   { {NULL, NULL}, ip_post_fn, PF_INET, NF_IP_POST_ROUTING, NF_IP_PRI_FIRST };
  81. static struct nf_hook_ops ip_pre_ops =
  82.   { {NULL, NULL}, ip_pre_fn, PF_INET, NF_IP_PRE_ROUTING, NF_IP_PRI_FIRST };


  83. /*
  84. * init_module
  85. * module init function
  86. */
  87. int
  88. init_module()
  89. {
  90.   int  ret = 0;

  91.   if ((ret = nf_register_hook(&ip_post_ops)) < 0) {
  92.     printk("can't register ip_post_ops hook\n");
  93.     return ret;
  94.   }

  95.   if ((ret = nf_register_hook(&ip_pre_ops)) < 0) {
  96.     printk("can't register ip_pre_ops hook\n");
  97.     nf_unregister_hook(&ip_post_ops);
  98.     return ret;
  99.   }

  100.   return 0;
  101. }


  102. /*
  103. * cleanup_module
  104. * module destroy function
  105. */
  106. void
  107. cleanup_module()
  108. {
  109.   nf_unregister_hook(&ip_post_ops);
  110.   nf_unregister_hook(&ip_pre_ops);
  111. }

  112. /*----- eof -----*/

复制代码



编译并安装模块后,执行FTP命令,访问target_ip:
ftp 192.168.3.60

结果没反应,在192.168.3.60端抓包发现,FTP包过来了,并且是伪装的IP地址,
checksum也都没有问题。奇怪的是FTP服务器收到这个包不作任何响应。抓包结果如下:

  1. Frame 1 (74 bytes on wire, 74 bytes captured)
  2.     Arrival Time: Apr 22, 2004 15:10:28.868024000
  3.     Time delta from previous packet: 0.000000000 seconds
  4.     Time since reference or first frame: 0.000000000 seconds
  5.     Frame Number: 1
  6.     Packet Length: 74 bytes
  7.     Capture Length: 74 bytes
  8. Ethernet II, Src: 00:90:27:08:90:bc, Dst: 00:00:e2:47:3b:d5
  9.     Destination: 00:00:e2:47:3b:d5 (00:00:e2:47:3b:d5)
  10.     Source: 00:90:27:08:90:bc (00:90:27:08:90:bc)
  11.     Type: IP (0x0800)
  12. Internet Protocol, Src Addr: 192.168.3.111 (192.168.3.111), Dst Addr: 192.168.3.60 (192.168.3.60)
  13.     Version: 4
  14.     Header length: 20 bytes
  15.     Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
  16.         0000 00.. = Differentiated Services Codepoint: Default (0x00)
  17.         .... ..0. = ECN-Capable Transport (ECT): 0
  18.         .... ...0 = ECN-CE: 0
  19.     Total Length: 60
  20.     Identification: 0xeca8 (60584)
  21.     Flags: 0x04
  22.         0... = Reserved bit: Not set
  23.         .1.. = Don't fragment: Set
  24.         ..0. = More fragments: Not set
  25.     Fragment offset: 0
  26.     Time to live: 64
  27.     Protocol: TCP (0x06)
  28.     Header checksum: 0xc617 (correct)
  29.     Source: 192.168.3.111 (192.168.3.111)
  30.     Destination: 192.168.3.60 (192.168.3.60)
  31. Transmission Control Protocol, Src Port: 1126 (1126), Dst Port: 21 (21), Seq: 0, Ack: 0, Len: 0
  32.     Source port: 1126 (1126)
  33.     Destination port: 21 (21)
  34.     Sequence number: 0
  35.     Header length: 40 bytes
  36.     Flags: 0x0002 (SYN)
  37.         0... .... = Congestion Window Reduced (CWR): Not set
  38.         .0.. .... = ECN-Echo: Not set
  39.         ..0. .... = Urgent: Not set
  40.         ...0 .... = Acknowledgment: Not set
  41.         .... 0... = Push: Not set
  42.         .... .0.. = Reset: Not set
  43.         .... ..1. = Syn: Set
  44.         .... ...0 = Fin: Not set
  45.     Window size: 5840
  46.     Checksum: 0x5150 (correct)
  47.     Options: (20 bytes)
  48.         Maximum segment size: 1460 bytes
  49.         SACK permitted
  50.         Time stamp: tsval 39767606, tsecr 0
  51.         NOP
  52.         Window scale: 0 (multiply by 1)

  53. 0000  00 00 e2 47 3b d5 00 90 27 08 90 bc 08 00 45 00   ...G;...'.....E.
  54. 0010  00 3c ec a8 40 00 40 06 c6 17 c0 a8 03 6f c0 a8   .<..@.@......o..
  55. 0020  03 3c 04 66 00 15 60 3d 22 9e 00 00 00 00 a0 02   .<.f..`=".......
  56. 0030  16 d0 51 50 00 00 02 04 05 b4 04 02 08 0a 02 5e   ..QP...........^
  57. 0040  ce 36 00 00 00 00 01 03 03 00                     .6........

复制代码



请教这是为什么?

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2004-04-22 15:30 |只看该作者

[求助]关于使用NetFilter Hook进行FTP地址伪装的问题

不懂编程,替你顶一下。等待高手出现。

论坛徽章:
0
3 [报告]
发表于 2004-04-22 15:34 |只看该作者

[求助]关于使用NetFilter Hook进行FTP地址伪装的问题

iptables不是已经有这个功能,是自己练手?

论坛徽章:
0
4 [报告]
发表于 2004-04-22 15:40 |只看该作者

[求助]关于使用NetFilter Hook进行FTP地址伪装的问题

自己练习,感觉很简单的样子,只是出了这样的问题很不解。

论坛徽章:
0
5 [报告]
发表于 2004-04-22 17:07 |只看该作者

[求助]关于使用NetFilter Hook进行FTP地址伪装的问题

这是一个TCP握手包,看样子数据包在到达TCP协议层之前就被丢了,很不解:为什么checksum都是对的,包还会丢呢?还是有其他的原因?

论坛徽章:
0
6 [报告]
发表于 2006-09-15 09:33 |只看该作者
学习,顶一下,支持,也想知道,各位大虾请多指教!qq:254836615  email:zhanghx1977@163.com

论坛徽章:
0
7 [报告]
发表于 2006-12-12 16:16 |只看该作者
鄙人最近在研究用netfilter实现类似NAT功能的应用。。。
也在对数据包进行修改/转发。。。

建议你先查看一下那个FTP server的ARP表格,看看它上面192.168.3.111对应的MAC地址是不是192.168.3.120的。

另外,似乎对数据包不能直接修改吧,之前要调用skb_make_writable()之类的函数吧。

我的MSN:zhubaining(at)hotmail.com,可以讨论讨论。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP