- 论坛徽章:
- 0
|
昨天在和dreamice大哥聊应用层防火墙的时候,问了些比较白痴的问题....比如内核态获取URL...呵呵 今天实现了下发现也不是很难...参考了ipp2p那么多协议的分析...好了不废话了....
http.c
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/netfilter.h>
- #include <linux/skbuff.h>
- #include <linux/ip.h>
- #include <linux/netdevice.h>
- #include <linux/if_ether.h>
- #include <linux/if_packet.h>
- #include <net/tcp.h>
- #include <net/udp.h>
- #include <net/icmp.h>
- #include <linux/netfilter_ipv4.h>
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("kenthy@163.com");
- static struct nf_hook_ops os_attack_ops;
- void check_http(const unsigned char* haystack, unsigned int len)
- {
- char url[100];
- char* host_tmp;
- char* url_tmp = url;
- if(len>3)
- {
- #if 0
- printk("len is %d\n", len);
- printk("%s\n", haystack);
- #endif
- if(memcmp(haystack, "GET", 3)==0)
- {
- host_tmp = strstr(haystack,"Host:");
- while(*host_tmp!='\r')
- *url_tmp++ = *host_tmp++;
- *url_tmp='\0';
- printk("http connect----%s\n",url);
- }
- }
- }
- unsigned int
- os_attack_detect(unsigned int hooknum,
- struct sk_buff** skb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff*))
- {
- struct iphdr *iph = NULL;
- struct tcphdr *tcph = NULL;
- struct tcphdr _otcph;
- unsigned char* haystack;
- int hlen;
- iph = ip_hdr(*skb);
- haystack =(char*)iph+(iph->ihl*4);
- hlen = ntohs(iph->tot_len)-(iph->ihl*4);
- if (iph->protocol == IPPROTO_TCP) {
- tcph = skb_header_pointer(*skb, ip_hdrlen(*skb), sizeof(_otcph), &_otcph);
-
- haystack += tcph->doff*4;
- hlen -= tcph->doff*4;
-
- check_http(haystack, hlen);
- }
- return NF_ACCEPT;
- }
- static int __init init(void)
- {
- int ret;
- os_attack_ops.hook = os_attack_detect;
- os_attack_ops.hooknum = NF_IP_LOCAL_OUT;
- os_attack_ops.pf = PF_INET;
- os_attack_ops.priority = NF_IP_PRI_FIRST;
- ret = nf_register_hook(&os_attack_ops);
- if (ret < 0) {
- printk("http detect:can't register http detect hook!\n");
- return ret;
- }
- printk("insmod http detect module\n");
- return 0;
- }
- static void __exit fini(void)
- {
- nf_unregister_hook(&os_attack_ops);
- printk("remove http detect module.\n");
- }
- module_init(init);
- module_exit(fini);
复制代码
Makefile
- obj-m := http.o
- KDIR := /lib/modules/$(shell uname -r)/build/
- PWD := $(shell pwd)
- all:module
- module:
- $(MAKE) -C $(KDIR) M=$(PWD) modules
- clean:
- rm -rf *.ko *.mod.c *.o Module.* modules.* .*.cmd .tmp_versions
复制代码
脱掉外套ip头,在脱掉内衣tcp头,ok现在就是好色的你想要的了...也就是haystack了
- haystack += tcph->doff*4;
- hlen -= tcph->doff*4;
- check_http(haystack, hlen);
复制代码
这里的haystack就是上层的一些数据...
用wireshark抓包看到http请求如下:
- "GET /u2/76292/ HTTP/1.1\r\n"
- "Accept: */*\r\n"
- "Accept-Language: zh-cn\r\n"
- "Accept-Encoding: gzip, deflate\r\n"
- "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; CIBA; TheWorld)\r\n"
- "Host:blog.chinaunix.net\r\n"
- "Connection: Keep-Alive\r\n\r\n";
复制代码
我这里只是提取了Host你可以根据自己需要提取别的...
if(memcmp(haystack, "GET", 3)==0) //这里并没有使用端口判断...直接看头三个char是不是GET,这里也可以||memcmp(haystack, "POST", 4)
{
/*就是找到Host,所以Accept Accept-Language Host的顺序不是固定的,所以别根据第几行,也就是多少个'\n'来找
至于strstr函数这个不是这里考虑的,我也没看strstr的源码,你们自己也可以写kmp来找到Host*/
host_tmp = strstr(haystack,"Host:");
/*这里就是将Host:blog.chinaunix.net赋给url_tmp了*/
while(*host_tmp!='\r')
*url_tmp++ = *host_tmp++;
*url_tmp='\0';
printk("http connect----%s\n",url);
}
ok其实也蛮简单的,弄清楚了的话... 有个帖子是url过滤的.. 今天先休息下,明天基于这个url提取再做个URL过滤的....
代码在CentOS5.3 2.6.18上测试通过了
图片是测试结果
[ 本帖最后由 ubuntuer 于 2009-12-17 16:19 编辑 ] |
-
评分
-
查看全部评分
|