一、前言
Rootkit是一种特有的恶意程序,它的作用是在安裝总体目标上掩藏本身及特定的文档、进程和网络等信息,比较多看到的是Rootkit一般都和木马病毒、侧门等别的木马程序融合应用。
rootkit检测也变成服务器安全性一项关键作用,对于rootkit中最普遍隐藏进程、端口号检测,关键分成二种检测构思,一种根据核心运行内存剖析,一种根据应用层剖析。
根据运行内存剖析Rootkit检测可参照Rootkit检测,该计划方案缺陷是必须提升内核模块,风险性高,检测实际效果相比不错。
文中详细介绍第二种计划方案,unhide在应用层发觉隐藏进程、端口号,该计划方案风险性小,可集成化到服务器安全性agent中。
二、应用层隐藏进程检测
1. 进程掩藏和检测方式
进程隐藏二种方式:
- 更换ps命令,在载入/proc/pid文件目录时,过虑掉需隐藏进程信息
- 载入内核模块,根据阻拦proc系统文件的调用函数,过虑掉需隐藏进程信息
检测核心内容:
根据libc系统软件函数公式盲测进程pid的生存情况,再依据ps結果比照差别,分辨该pid是隐藏进程。
unhide给予如下所示19种检测方式,大概可分成四类:一类根据procfs下的进程文件目录信息,第二类根据系统软件函数调用, 第三类根据前两大类组成方式,第四类根据爆力破译(不强烈推荐)。
从名称上可以看得出,unhide应用chdir,opendir,readdir,getpriority,getpgid,getsid,sched_getaffinity,kill,sysinfo等libc函数公式。
下边各自从三类中各挑选一种检测方式剖析。
2. procfs检测
提取checkreaddir检测剖析:
- 解析xml/proc文件目录, 子文件夹名称如果是数据,意味着是一个进程pid
- 载入进程情况task文件目录(/proc/pid/task), 获得各子进程号
- 根据ps命令搜索是不是存有该进程
- 比照差别,不会有分辨为隐藏进程
- procdir=opendir("/proc");
- dirproc=readdir(procdir));
- taskdir=opendir(task);
- dir=readdir(taskdir)
- checkps(procpids,PS_THREAD)
此类方式能检验出兑第二种失效。
3. syscall检验
提取checkgetsid检测分析:
max_pid根据载入 /proc/sys/kernel/pid_max获得:
- 从1到max_pid解析xml进程, 根据getsid返回值和错误码探测进程存活状态
- 通过ps命令搜索是不是存有该进程
- 再度根据getsid确定进程存活状态,避免在实行ps这時间内,进程撤出了
- 比照差别,不会有分辨为掩藏进程
- ret=getsid(syspids)
- checkps(syspids,PS_PROC|PS_THREAD);
- ret=getsid(syspids)
此类方式都能检验以上二种掩藏进程方法。
4. compund检验
提取checkallquick检测分析:
- 从1到max_pid解析xml进程
- 根据kill返回值和错误码探测进程存活状态
- 通过getpriority返回值和错误码探测进程存活状态
- 根据getpgid返回值和错误码探测进程存活状态
- 通过getsid返回值和错误码探测进程存活状态
- 根据sched_getaffinity返回值和错误码探测进程存活状态
- 通过sched_getparam返回值和错误码探测进程存活状态
- 根据sched_getscheduler返回值和错误码探测进程存活状态
- 通过sched_rr_get_interval返回值和错误码探测进程存活状态
- 根据chdir,opendir载入进程文件目录(/proc/pid)
- 根据ps命令搜索是不是存有该进程
- 再度根据kill确定进程存活状态,避免在实行ps这時间内,进程撤出
- 比照差别,仅有进程不会有(found=0)或是进程通过11项检验(found == 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,¶m);
- ret=sched_getscheduler(syspids);
- statstatusproc=stat(directory,&buffer);
- statusdir=chdir(directory);
- dir_fd=opendir(directory);
- checkps(syspids,PS_PROC|PS_THREAD)
- ret=kill(syspids,0);
- if(found_killbefore==found_killafter){
- if(!((found_killbefore==0&&found==0)||
- (found_killbefore==1&&found==11))){
- printbadpid(syspids);
- }
三、网络层掩藏端口检测
核心内容:根据libc系统软件函数公式bind,listen盲测端口号
1. tcp掩藏端口检测
- 从1到65535解析xml端口号
- 建立一个根据tcp协议SOCK_STREAM的socket
- 通过bind返回值和错误码探测端口号状态
- 假如被占有,根据listen 错误码是EADDRINUSE明确端口占用
- 根据ss或netstat指令过虑tcp协议,查看端口状况
- 比照差别,确定该端口号为掩藏端口号
- socketsocket_desc=socket(AF_INET,SOCK_STREAM,0);
- bind(socket_desc,(structsockaddr*)&address,sizeof(address));
- listen(socket_desc,1);
- if(EADDRINUSE==errno){
- checkoneport(i,tcpcommand,TCP);
- }
2. udp掩藏端口检测
对比tcp, udp应用SOCK_DGRAM的socket, 缺乏listen这步,其他检验流程相近
四、结果
文中给予的根据网络层方法检验rootkit中最多见的隐藏进程和端口号,风险小,可无缝拼接集成化到服务器安全性agent中。