Rootkit隐藏进程和端口检测

发布者:上海IT外包来源:http://www.lanmon.net点击数:1383

一,导言
Rootkit是一种特殊的恶意软件。它的功能是隐藏自身以及安装目标上的指定文件,进程和网络链接。更常见的是,rootkit通常与其他恶意程序(如特洛伊木马和后门程序)结合使用。 。
例如:inetd或login,为攻击者提供后门;隐藏攻击者的目录和进程程序,ps,netstat和其他常用命令。
Rootkit检测也已成为主机安全的重要功能。 Rootkit中最常见的隐藏进程和端口检测主要分为两种检测思想,一种基于内核内存分析,另一种基于应用层分析。
基于内存分析的Rootkit检测可以参考rootkit检测。该方案的缺点是需要增加内核模块,具有高风险和最佳检测效果。
本文介绍第二种方案。取消隐藏在应用层发现隐藏的进程和端口。该方案风险较低,可以集成到主机安全代理中。
二,应用层隐藏进程检测
1.过程隐藏和检测方法
该过程隐藏了两种方式:
在读取/proc/pid目录时,替换ps命令以过滤掉进程信息。
加载内核模块,通过拦截proc文件系统的回调函数,过滤掉需要隐藏的进程信息。
检测核心理念:
libc系统函数盲目地测量进程pid的生存状态,然后根据ps结果比较差异以确定pid是隐藏进程。
Unhide提供了以下19种检测方法,大致可分为四类:一类通过procfs下的进程目录信息,第二类通过系统调用函数,第三类通过前两种类型组合,第四类通过爆炸力裂缝(不推荐)。
Tab_test [TST_PROC] .func=checkproc;
Tab_test [TST_CHDIR] .func=checkchdir;
Tab_test [TST_OPENDIR] .func=checkopendir;
Tab_test [TST_READDIR] .func=checkreaddir;
Tab_test [TST_GETPRIO] .func=checkgetpriority;Tab_test [TST_GETPGID] .func=checkgetpgid;
Tab_test [TST_GETSID] .func=checkgetsid;
Tab_test [TST_GETAFF] .func=checksched_getaffinity;
Tab_test [TST_GETPARM] .func=checksched_getparam;
Tab_test [TST_GETSCHED] .func=checksched_getscheduler;
Tab_test [TST_RR_INT] .func=checksched_rr_get_interval;
Tab_test [TST_KILL] .func=checkkill;
Tab_test [TST_NOPROCPS] .func=checkallnoprocps;
Tab_test [TST_BRUTE] .func=brute;
Tab_test [TST_REVERSE] .func=checkallreverse;
Tab_test [TST_QUICKONLY] .func=checkallquick;
Tab_test [TST_SYS_INFO] .func=checksysinfo;
Tab_test [TST_SYS_INFO2] .func=checksysinfo2;
Tab_test [TST_SYS_INFO3] .func=checksysinfo3;
从名称中可以看出,取消隐藏使用libc函数,如chdir,opendir,readdir,getpriority,getpgid,getsid,sched_getaffinity,kill,sysinfo。
在下文中,从三个类别中的每一个中选择一种类型的检测方法。
2. procfs检测
提取checkreaddir检测分析:
遍历/proc目录,如果子文件名是数字,则表示进程pid
读取进程状态任务目录(/proc/pid/task),获取每个子线程号使用ps命令查明该线程是否存在。
对比差异,没有判断隐藏的过程
Procdir=opendir('/proc');
Dirproc=readdir(procdir));
Taskdir=opendir(任务);
Dir=readdir(taskdir)
检查(procpids,PS_THREAD)
这种类型的方法可以检测第一个隐藏的过程模式,这对第二个模式是无效的。
3.系统调用检测
提取checksetsid检测分析:
通过读取/proc/sys/kernel/pid_max获得Max_pid:
遍历从1到max_pid的进程,通过getsid返回值和错误代码检测进程生存状态
使用ps命令查明进程是否存在。
通过getsid再次确认进程生存状态,以防止进程在执行ps期间退出。
对比差异,没有判断隐藏的过程
Ret=getsid(syspids)
Checkps(syspids,PS_PROC | PS_THREAD);
Ret=getsid(syspids)
这种方法可以检测上述两种隐藏的过程模式。
4.复合检测
提取checkallquick检测分析:
遍历从1到max_pid的过程
通过杀死返回值和错误代码来检测进程生存
通过使用getpriority返回值和错误代码来检测进程生存
通过getpgid返回值和错误代码来检测进程生存
通过getsid返回值和错误代码检测进程生存状态
通过sched_getaffinity返回值和错误代码检测进程生命周期
通过sched_getparam返回值和错误代码检测进程生存
通过sched_getscheduler返回值和错误代码检测进程生存期
通过sched_rr_get_interval返回值和错误代码检测进程生存期
通过chdir,opendir读取进程目录(/proc/pid)
使用ps命令查明进程是否存在。
终止进程以再次确认进程的生存状态,防止进程在执行ps期间退出。
对比差异,只有过程不存在(找到=0)或过程在11次测试(找到==11)后被认为是正常的,其余的被判断为隐藏过程。
Ret=kill(syspids,0);Ret=getpriority(PRIO_PROCESS,syspids);
Ret=getpgid(syspids);
Ret=getsid(syspids);
Ret=sched_getaffinity(syspids,sizeof(cpu_set_t),&mask);
Ret=sched_getparam(syspids,&param);
Ret=sched_getscheduler(syspids);
Statstatusproc=stat(目录,&缓冲区);
Statusdir=chdir(目录);
Dir_fd=opendir(目录);
Checkps(syspids,PS_PROC | PS_THREAD)
Ret=kill(syspids,0);
如果(found_killbefore==found_killafter){
如果(!((found_killbefore==0 && found==0)||
(found_killbefore==1 && found==11))){
Printbadpid(syspids);
}
三,应用层隐藏端口检测
核心思想:通过libc系统函数绑定,监听盲端口
1. tcp隐藏端口检测
遍历端口从1到65535
根据tcp协议SOCK_STREAM创建套接字
通过绑定返回值和错误代码检测端口状态
如果它被占用,则端口被侦听错误代码EADDRINUSE占用
使用ss或netstat命令过滤tcp协议并检查端口状态。
比较差异并确认端口是隐藏端口
Socketsocket_desc=socket(AF_INET,SOCK_STREAM,0);
绑定(socket_desc,(struct sockaddr *)&address,sizeof(address));
听(socket_desc,1);如果(EADDRINUSE==errno){
Checkoneport(i,tcpcommand,TCP);
}
2. udp隐藏端口检测
与tcp相比,udp使用缺少listen步骤的SOCK_DGRAM套接字。其余检测步骤类似。
Socketsocket_desc=socket(AF_INET,SOCK_DGRAM,0);
绑定(socket_desc,(struct sockaddr *)&address,sizeof(address));
如果(EADDRINUSE==errno){
Checkoneport(u,udpcommand,UDP);
}
第四,结论
本文提供了应用程序层来检测rootkit中最常见的隐藏进程和端口。风险很小,可以无缝集成到主机安全代理中。
IT外包
>
400-635-8089
立即
咨询
电话咨询
服务热线
400-635-8089
微信咨询
微信咨询
微信咨询
公众号
公众号
公众号
返回顶部