利用netfilter機制,實現核心防火牆把http請求和迴應的資料包截獲後,解釋出其中的http層資料
阿新 • • 發佈:2019-01-29
#include<linux/init.h>
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/netfilter_ipv4.h>
#include<linux/skbuff.h>
#include<linux/ip.h>
#include<linux/tcp.h>
#include<linux/if_ether.h>
#include<linux/if_packet.h>
unsigned int change(int aChar,int hex)
{
int ch;
ch = aChar - hex;
return ch;
}
unsigned char HexToAsc(int aChar)
{
/*if(aChar>=0x20&&aChar<=0x7E)
{
return ' '+(aChar-0x20);
}*/
/*if((aChar>=0x0)&&(aChar<=0x9))
return 0+change(aChar,0x0);
if((aChar>=0xA)&&(aChar<=0xF))
return 0+change(aChar,0xA);
if((aChar>=0x10)&&(aChar<=0x19))
return 16+change(aChar,0x10);
if((aChar>=0x1A)&&(aChar<=0x1F))
return 26+change(aChar,0x1A);*/
if(aChar == 0x20)
return 32;
/*if(aChar == 0x7F)
return 127;*/
if(aChar == 0xA)
return 10;
if(aChar == 0xD)
return 13;
if((aChar>=0x21)&&(aChar<=0x2F))
{
int ch = change(aChar,0x21);
return '!'+ch;
}
if((aChar>=0x30)&&(aChar<=0x39))
{
int ch = change(aChar,0x30);
return '0'+ch;
}
if((aChar>=0x3A)&&(aChar<=0x40))
{
int ch = change(aChar,0x3A);
return ':'+ch;
}
if((aChar>=0x41)&&(aChar<=0x5A))
{
int ch = change(aChar,0x41);
return 'A'+ch;
}
if((aChar>=0x5B)&&(aChar<=0x60))
{
int ch = change(aChar,0x5B);
return '['+change;
}
if((aChar>=0x61)&&(aChar<=0x7A))
{
int ch = change(aChar,0x61);
return 'a'+ch;
}
if((aChar>=0x7B)&&(aChar<=0x7E))
{
int ch = change(aChar,0x7B);
return '{'+ch;
}
return NULL;
}
//nf_in鉤子執行函式hf_hook_in
static unsigned int nf_hook_in(unsigned int hooknum,struct sk_buff **skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff*))
{
int i;
struct sk_buff *sk = NULL;
sk = skb_copy(skb,GFP_ATOMIC);
struct iphdr *iph = ip_hdr(sk);//獲取ip頭指標
struct tcphdr *tcph;//tcp頭指標
tcph = (void*)iph + iph->ihl*4;//獲取tcp開始位置
//int char_int1,char_int2;
//char c1 = NULL;
//char c2 = NULL;
if(iph->protocol == IPPROTO_TCP)//截獲的是TCP型別的包
{
if((tcph->source == htons(8080)||tcph->source == htons(80))&&(sk->len > 40))//接收的包源地址埠是8080或80埠的並且包長度大於40個位元組
{
if(tcph->source == htons(8080))//源地址埠號是8080,接收的8080埠的包
{
printk("receive package starting:this is a http 8080 package!\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%x ",*(sk->data+i));
}
printk("\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%c",HexToAsc(*(sk->data+i)));
}
printk("\nreceive ended!\n");
}
else//源地址埠號是80,接收的是80埠的包
{
printk("receive package starting:this is a http 80 package!\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%x ",*(sk->data+i));
}
printk("\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%c",HexToAsc(*(sk->data+i)));
}
printk("\nreceive ended!\n");
}
}
}
return NF_ACCEPT;
}
//nf_out鉤子執行函式hf_hook_out
static unsigned int nf_hook_out(unsigned int hooknum,struct sk_buff **skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff*))
{
int i;
struct sk_buff *sk = NULL;
sk = skb_copy(skb,GFP_ATOMIC);
struct iphdr *iph = ip_hdr(sk);//獲取ip頭指標
struct tcphdr *tcph;//tcp頭指標
tcph = (void*)iph + iph->ihl*4;//獲取tcp開始位置
//int char_int1,char_int2;
//char c1 = NULL;
//char c2 = NULL;
if(iph->protocol == IPPROTO_TCP)//傳送的是TCP型別的包
{
if((tcph->dest == htons(8080)||tcph->dest == htons(80))&&(sk->len > 40))//傳送的包目的地址埠是8080或80埠的並且包長度大於40個位元組
{
if(tcph->dest == htons(8080))//目的地址埠號是8080,傳送的是前往8080埠的包
{
printk("send package starting:this is a http 8080 package!\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%x ",*(sk->data+i));
}
printk("\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%c",HexToAsc(*(sk->data+i)));
}
printk("\nsend ended!\n");
}
else//目的地址埠號是80,傳送的是前往80埠的包
{
printk("send package starting:this is a http 80 package!\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%x ",*(sk->data+i));
}
printk("\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%c",HexToAsc(*(sk->data+i)));
}
printk("\nsend ended!\n");
}
}
}
return NF_ACCEPT;
}
//初始化nf_in鉤子,在鉤子LOCAL_IN上
static struct nf_hook_ops nf_in =
{
.hook = nf_hook_in,//繫結執行函式nf_hook_in()
.hooknum = NF_INET_LOCAL_IN,//鉤子型別
.pf = PF_INET,//指定IPv4協議族
.priority = 0//指定在執行的順序中,這個hook函式應當在被放在什麼地方
};
//初始化nf_out鉤子,在鉤子LOCAL_OUT上
static struct nf_hook_ops nf_out =
{
.hook = nf_hook_out,//繫結執行函式nf_hook_out()
.hooknum = NF_INET_LOCAL_OUT,//鉤子型別
.pf = PF_INET,//指定IPv4協議族
.priority = 0//指定在執行的順序中,這個hook函式應當在被放在什麼地方
};
static int __init nf_init(void){//模組入口
nf_register_hook(&nf_in);//註冊nf_in鉤子函式
nf_register_hook(&nf_out);//註冊nf_out鉤子函式
return 0;
}
static void __exit//模組退出
nf_exit(void){
nf_unregister_hook(&nf_in);//登出nf_in鉤子函式
nf_unregister_hook(&nf_out);//登出nf_out鉤子函式
}
module_init(nf_init);
module_exit(nf_exit);
MODULE_LICENSE("GPL");
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/netfilter_ipv4.h>
#include<linux/skbuff.h>
#include<linux/ip.h>
#include<linux/tcp.h>
#include<linux/if_ether.h>
#include<linux/if_packet.h>
unsigned int change(int aChar,int hex)
{
int ch;
ch = aChar - hex;
return ch;
}
unsigned char HexToAsc(int aChar)
{
/*if(aChar>=0x20&&aChar<=0x7E)
{
return ' '+(aChar-0x20);
}*/
/*if((aChar>=0x0)&&(aChar<=0x9))
return 0+change(aChar,0x0);
if((aChar>=0xA)&&(aChar<=0xF))
return 0+change(aChar,0xA);
if((aChar>=0x10)&&(aChar<=0x19))
return 16+change(aChar,0x10);
if((aChar>=0x1A)&&(aChar<=0x1F))
return 26+change(aChar,0x1A);*/
if(aChar == 0x20)
return 32;
/*if(aChar == 0x7F)
return 127;*/
if(aChar == 0xA)
return 10;
if(aChar == 0xD)
return 13;
if((aChar>=0x21)&&(aChar<=0x2F))
{
int ch = change(aChar,0x21);
return '!'+ch;
}
if((aChar>=0x30)&&(aChar<=0x39))
{
int ch = change(aChar,0x30);
return '0'+ch;
}
if((aChar>=0x3A)&&(aChar<=0x40))
{
int ch = change(aChar,0x3A);
return ':'+ch;
}
if((aChar>=0x41)&&(aChar<=0x5A))
{
int ch = change(aChar,0x41);
return 'A'+ch;
}
if((aChar>=0x5B)&&(aChar<=0x60))
{
int ch = change(aChar,0x5B);
return '['+change;
}
if((aChar>=0x61)&&(aChar<=0x7A))
{
int ch = change(aChar,0x61);
return 'a'+ch;
}
if((aChar>=0x7B)&&(aChar<=0x7E))
{
int ch = change(aChar,0x7B);
return '{'+ch;
}
return NULL;
}
//nf_in鉤子執行函式hf_hook_in
static unsigned int nf_hook_in(unsigned int hooknum,struct sk_buff **skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff*))
{
int i;
struct sk_buff *sk = NULL;
sk = skb_copy(skb,GFP_ATOMIC);
struct iphdr *iph = ip_hdr(sk);//獲取ip頭指標
struct tcphdr *tcph;//tcp頭指標
tcph = (void*)iph + iph->ihl*4;//獲取tcp開始位置
//int char_int1,char_int2;
//char c1 = NULL;
//char c2 = NULL;
if(iph->protocol == IPPROTO_TCP)//截獲的是TCP型別的包
{
if((tcph->source == htons(8080)||tcph->source == htons(80))&&(sk->len > 40))//接收的包源地址埠是8080或80埠的並且包長度大於40個位元組
{
if(tcph->source == htons(8080))//源地址埠號是8080,接收的8080埠的包
{
printk("receive package starting:this is a http 8080 package!\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%x ",*(sk->data+i));
}
printk("\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%c",HexToAsc(*(sk->data+i)));
}
printk("\nreceive ended!\n");
}
else//源地址埠號是80,接收的是80埠的包
{
printk("receive package starting:this is a http 80 package!\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%x ",*(sk->data+i));
}
printk("\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%c",HexToAsc(*(sk->data+i)));
}
printk("\nreceive ended!\n");
}
}
}
return NF_ACCEPT;
}
//nf_out鉤子執行函式hf_hook_out
static unsigned int nf_hook_out(unsigned int hooknum,struct sk_buff **skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff*))
{
int i;
struct sk_buff *sk = NULL;
sk = skb_copy(skb,GFP_ATOMIC);
struct iphdr *iph = ip_hdr(sk);//獲取ip頭指標
struct tcphdr *tcph;//tcp頭指標
tcph = (void*)iph + iph->ihl*4;//獲取tcp開始位置
//int char_int1,char_int2;
//char c1 = NULL;
//char c2 = NULL;
if(iph->protocol == IPPROTO_TCP)//傳送的是TCP型別的包
{
if((tcph->dest == htons(8080)||tcph->dest == htons(80))&&(sk->len > 40))//傳送的包目的地址埠是8080或80埠的並且包長度大於40個位元組
{
if(tcph->dest == htons(8080))//目的地址埠號是8080,傳送的是前往8080埠的包
{
printk("send package starting:this is a http 8080 package!\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%x ",*(sk->data+i));
}
printk("\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%c",HexToAsc(*(sk->data+i)));
}
printk("\nsend ended!\n");
}
else//目的地址埠號是80,傳送的是前往80埠的包
{
printk("send package starting:this is a http 80 package!\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%x ",*(sk->data+i));
}
printk("\n");
for(i=40;i<sk->len;i++)//從第40個位元組以後開始獲取資料data部分
{
printk("%c",HexToAsc(*(sk->data+i)));
}
printk("\nsend ended!\n");
}
}
}
return NF_ACCEPT;
}
//初始化nf_in鉤子,在鉤子LOCAL_IN上
static struct nf_hook_ops nf_in =
{
.hook = nf_hook_in,//繫結執行函式nf_hook_in()
.hooknum = NF_INET_LOCAL_IN,//鉤子型別
.pf = PF_INET,//指定IPv4協議族
.priority = 0//指定在執行的順序中,這個hook函式應當在被放在什麼地方
};
//初始化nf_out鉤子,在鉤子LOCAL_OUT上
static struct nf_hook_ops nf_out =
{
.hook = nf_hook_out,//繫結執行函式nf_hook_out()
.hooknum = NF_INET_LOCAL_OUT,//鉤子型別
.pf = PF_INET,//指定IPv4協議族
.priority = 0//指定在執行的順序中,這個hook函式應當在被放在什麼地方
};
static int __init nf_init(void){//模組入口
nf_register_hook(&nf_in);//註冊nf_in鉤子函式
nf_register_hook(&nf_out);//註冊nf_out鉤子函式
return 0;
}
static void __exit//模組退出
nf_exit(void){
nf_unregister_hook(&nf_in);//登出nf_in鉤子函式
nf_unregister_hook(&nf_out);//登出nf_out鉤子函式
}
module_init(nf_init);
module_exit(nf_exit);
MODULE_LICENSE("GPL");