LKM Linux rootkit之Reptile分析二

admin 2023年2月27日20:02:39评论97 views字数 2424阅读8分4秒阅读模式

Reptile内核模块分析

 这篇文章分析一下内核模块部分,这部分主要功能就两个字:隐藏。通过前边的文章,知道了是通过cmd文件控制是否隐藏文件、模块、进程、网络连接等等。

cmd模块是运行在用户层,rep_mod运行在内核层。下边先来看一下他们之间怎么交互

用户层和内核层交互

用户层发送

cmd文件开始看,这个文件也简单,前边初始化一些变量,后边是几个if循环,有:root权限提升、隐藏或查看当前模块、文件篡改、隐藏或查看tcp连接、隐藏或查看udp连接。

这几个if都差不多,最终都是把需要的变量传递给ioctl()函数。

             LKM Linux rootkit之Reptile分析二

             

ioctl(input/output control)是一个在Unix/Linux系统中广泛使用的系统调用,用于控制设备的输入输出操作。通过ioctl调用,程序可以读取或修改设备的特定属性。例如,程序可以通过ioctl获取一个硬件设备的状态,或者设置设备的参数,如波特率、数据位等。

安装的时候,可以知道利用的PulseAudio硬件。PulseAudio 中的 ioctl 函数可以用来配置音频设备,例如更改音量、设置麦克风、扬声器等。

这样,就把用户层的数据传递给了内核层,那么,内核层怎么接收这些数据?

内核层接收

这里打开的是一个socket套接字,肯定会调用inet_ioctl()函数处理。所以在内核模块hook这个函数。确实简单粗暴。

LKM Linux rootkit之Reptile分析二

             

             

模块隐藏和显示

内核链表

Linux 内核模块链表是一种数据结构,在内核中用于管理模块(即动态加载到内核中的程序段)。内核模块链表是一个双向链表,每个模块都是链表中的一个节点,用于表示模块的信息,例如模块的名称、加载和卸载的函数等。内核模块链表有助于管理和组织内核中的多个模块,从而使得内核更加灵活。

THIS_MODULE 宏是一个内核定义的全局变量,表示当前模块,并且其中包含了当前模块的详细信息,例如名称,版本号,以及链表中的指针。

THIS_MODULE->list表示当前模块的链表元素。是一个指向struct list_head结构体的指针,指向当前模块在链表中的位置。

可以通过nextprev获取当前模块的下一个和上一个元素。

隐藏

隐藏模块功能其实就几行函数,入下,出现的函数都是内核函数和结构体:

LKM Linux rootkit之Reptile分析二

             

THIS_MODULE->list.prev : 当前模块的前一个元素的指针

list_del():是Linux内核链表操作中的一个函数,它可以将一个节点从链表中删除

mutex_trylock():是一个C语言的内核函数,它的作用是尝试获取锁定的互斥锁。具体地,如果指定的互斥锁当前没有被其他进程锁定,则该函数将锁定该互斥锁,并返回0。否则,该函数返回一个非零值,表示该互斥锁已经被其他进程锁定,因此无法获取。

&module_mutex :是一个互斥锁变量的引用,用于标识要获取锁定的互斥锁。

保存前一个元素地址,是为了查看时,复原用到。

显示

只需需要把当前模块添加到链表即可。

LKM Linux rootkit之Reptile分析二

             

网络连接隐藏和显示原理类似模块的隐藏和显示,不展开分析。

进程隐藏和显示

进程标志位

task_struct是内核中代表一个进程的数据结构,它是描述一个进程的详细信息的数据结构。它涵盖了该进程的内存使用情况、状态信息、信号处理信息、调度信息、文件描述符信息等。

task_struct->flags是 Linux 内核中的进程状态标志位。它的数据类型为 unsigned long,是一个二进制的位操作,用于标识进程的状态。不同的内核版本,定义不同。Linux内核版本3.10.0的定义如下:

LKM Linux rootkit之Reptile分析二

             

当标志位正常时,是一个非零的长整型数。

当标志位清零时,ps等命令中将不会显示该进程。

             

判断是否已隐藏

判断一个进程是否已隐藏,首先看能不能通过进程ID找到内核中进程结构体。其次,判断标志位。进行位于运算,非零说明进程为正常状态,如果为零,则为隐藏状态。

LKM Linux rootkit之Reptile分析二

             

             

通过操作标志位进行隐藏和显示

Linux C中,按位与取反常用来清零,可以直接用来清零标志位,从而隐藏该进程。|= 运算符常用来合并二进制数,这样可以给标志位已被清零的进程添加标志位,从而显示该进程。

LKM Linux rootkit之Reptile分析二

             

             

文件内容隐藏和显示

在Linux系统中,要读取文件内容,会调用vfs_read内核函数。需要隐藏文件中指定内容时,hook这个函数,然后对其进程处理。

LKM Linux rootkit之Reptile分析二

             

待隐藏的这块文件内容,已经定义了隐藏开始标志和隐藏结束标志。如果是在文本编辑器中,要隐藏这块内容,直接从隐藏标志开始位置删到隐藏标志结束位置即可。在内存中,就需要操作对应指针,进行相应操作。

过程大致如下

计算出隐藏结束标志到文件末尾的长度,定义为i

i这块内容往前移动到隐藏开始标志处

现在文件内容的开始到i这块内容的结束,就是去掉待隐藏的文件内容后的全部内容了。

             

i的长度

LKM Linux rootkit之Reptile分析二

             

i移动到隐藏开始标志处。此时p1指针指向带隐藏内容的开始,P2指针指向i这块内容的开始。

memmove((void *)p1, (void *)p2, i);

计算出去掉带隐藏内容后的文件内容长度

newret = size - (p2 - p1);

从分配的内存里截取newret这么长的数据,也就是隐藏掉要隐藏的文件内容之后的数据,返回给用户

copy_to_user((void *)arg, (void *)buf, newret)

文件隐藏和显示

Linux系统内核处理文件的几个函数如下:

fillonedir、filldir、filldir64、compat_fillonedir、compat_filldir64

hook这些函数,然后遍历读取的文件列表,匹配要隐藏的文件名,如果匹配到,直接返回0即可。

LKM Linux rootkit之Reptile分析二

             

原文始发于微信公众号(云智信安云窟实验室):LKM Linux rootkit之Reptile分析二

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年2月27日20:02:39
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   LKM Linux rootkit之Reptile分析二http://cn-sec.com/archives/1578047.html

发表评论

匿名网友 填写信息