### 前言

Linux系统中存在用户态与内核态,当用户态的进程需要申请某些系统资源时便会发起系统调用。而内核态如何将系统的相关信息实时反馈给用户态呢,便是通过proc文件系统。如此便营造了一个相对隔离的环境。
那么proc文件系统是如何呈现我们平时最关心的进程/网络连接信息的呢?在/proc目录下存在着一些以数字命名的目录,这些数字便对应了系统中正在运行的进程的pid。自然,对应进程的一些相关信息便保存在/proc/{pid}目录下。比如/proc/{pid}/fd目录中就保存了进程打开的文件描述符。
系统会将tcp协议的连接信息保存在/proc/net/tcp文件中。其他网络协议的连接信息也均保存在/proc/net对应协议的文件中。需要特别指出的是,上图中socket文件名中括号里的数字与下图中inode列是存在对应关系的。
综上所述,像ps和netstat这类命令便是读取了proc文件系统中提供的数据,然后将数据格式化输出给用户的。出于隐藏指定进程/网络连接的目的,大部分Rootkit对写proc文件的回调函数做了些手脚,造成黑客指定的一些进程/网络连接的信息不会出现在proc文件系统中。于是,也就实现了进程/网络连接的隐藏。
### 探索
那么,如何发现那些被隐藏的进程/网络连接呢?首先是进程,这个其实并不复杂。系统给我们提供了一个方便的全局变量current。current永远指向当前正在运行的进程的task_struct数据结构,而进程的主要信息都包含在这个名为task_struct的巨大结构体中。当我们遍历到系统中所有进程task_struct结构体中的pid值,然后再去/proc目录下去寻找是否有对应的值。一但我们得到的pid未出现在ps的返回结果中,那么说明该进程被隐藏了。
如何发现被隐藏的网络连接呢?其实还是基于上一步进一步挖掘,因为网络IO请求都是由进程发起的,那么理论上来说我们肯定可以从进程一步步“捋”到socket。Linux一切皆文件的准则告诉我们,所谓网络IO其实就是读写socket文件,而每个socket结构体中都会有一个对应的inet_sock结构体,来记录IP协议下网络连接的四元组信息。那么我们把这些四元组再和netstat命令的返回结果比对一下便可知是否存在隐藏的网络信道了。
总结出来在Kernel2.6.32中,进程-文件-网络三者之间大致的关系如下图所示。
fdtable结构体的成员fd字符数组中存储的是file结构体,每当进程开启了一个文件描述符之后会自动在fd数组中新增一个对应的file结构体。通过获取file结构体中的f_path成员,我们可以获得对应的path结构体。系统内置的d_path函数可以返回path结构体对应文件的绝对路径信息。当d_path返回了一个“socket:[xxx]”的信息时,就说明这是个socket文件,该进程在试图进行网络IO。我们引用这个file结构体的private_data成员就可以获得这个socket文件对应的socket结构体了。最后通过内置的inet_sk()函数我们就可以找到对应socket文件的inet_sock结构体,我们需要的四元组便存在这个结构体中。
### 代码
[C] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/file.h>
#include <linux/dcache.h>
#include <linux/fdtable.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/limits.h>
#include <linux/string.h>
#include <linux/net.h>
#include <net/inet_sock.h>
  
static int __init mychk_init(void);
static void __exit mychk_exit(void);
  
module_init(mychk_init);
module_exit(mychk_exit);
  
MODULE_LICENSE("GPL");
  
void get_socket(struct file *f,char* sock_name){
        struct socket *st = NULL;
        struct inet_sock *is = NULL;
        st = f->private_data;
        is = inet_sk(st->sk);
        printk(KERN_ALERT"%s: LA: %d.%d.%d.%d:%u  FA: %d.%d.%d.%d:%u\n",sock_name,NIPQUAD(is->saddr),ntohs(is->sport),NIPQUAD(is->daddr),ntohs(is->dport));
}
  
char* get_path(struct path p) {
        char *buff = NULL;
        char *path = NULL;
        buff = kmalloc(PATH_MAX,GFP_KERNEL);
        if (!buff)
                return NULL;
        path = d_path(&p,buff,PATH_MAX);
        return path;
}
  
static int __init mychk_init(void) {
        struct task_struct *t = NULL;
        struct files_struct *f = NULL;
        struct file *file = NULL;
        struct fdtable *fdt = NULL;
        struct path p;
        char *msg = NULL;
        int i;
        list_for_each_entry(t,¤t->tasks,tasks) {
                printk(KERN_ALERT"Process:%s [%d]\n", t->comm, t->pid);
                task_lock(t);
                f = t->files;
                if(NULL != f){
                        fdt = f->fdt;
                        for (i = 0;i<NR_OPEN_DEFAULT;i++) {
                                if (fdt != NULL) {
                                        file = fdt->fd;
                                        if(file != NULL && file->f_path.dentry != NULL) {
                                                p = file->f_path;
                                                msg = get_path(p);
                                                if (msg != NULL && msg != strstr(msg,"socket"))
                                                        printk(KERN_ALERT"-- %s\n",msg);
                                                else
                                                        get_socket(file,msg);
                                        }
                                }
                        }
                }
                task_unlock(t);
        }
        return 0;
}
  
static void __exit mychk_exit(void) {
        printk(KERN_ALERT"Remove Module!\n");
}
###运行结果
Process:sshd [1840]
-- /dev/null
-- /dev/null
-- /dev/null
socket:[16185]: LA:192.168.11.144:22  FA: 192.168.11.1:61493
-- pipe:[16256]
-- pipe:[16256]
-- /dev/ptmx
-- /dev/ptmx
-- /dev/ptmx
Process:bash [1844]
-- /dev/pts/1
-- /dev/pts/1
-- /dev/pts/1
Process:mysqld_safe [3668]
-- /dev/null
-- /dev/null
-- /dev/null
Process:mysqld [3770]
-- /dev/null
-- /var/log/mysqld.log
-- /var/log/mysqld.log
-- /var/lib/mysql/ibdata1
-- /tmp/ibABwsCH (deleted)
-- /tmp/ibLWJRBw (deleted)
-- /tmp/ibVCthBl (deleted)
-- /tmp/ibogYHLa (deleted)
-- /var/lib/mysql/ib_logfile0
-- /var/lib/mysql/ib_logfile1
socket:[18993]: LA:0.0.0.0:3306  FA: 0.0.0.0:0
-- /tmp/ibgDa0v2 (deleted)
-- /var/lib/mysql/mysql/host.MYI
-- /var/lib/mysql/mysql/host.MYD
-- /var/lib/mysql/mysql/user.MYI
-- /var/lib/mysql/mysql/user.MYD
-- /var/lib/mysql/mysql/db.MYI
-- /var/lib/mysql/mysql/db.MYD
-- /var/lib/mysql/mysql/tables_priv.MYI
-- /var/lib/mysql/mysql/tables_priv.MYD
-- /var/lib/mysql/mysql/columns_priv.MYI
-- /var/lib/mysql/mysql/columns_priv.MYD
-- /var/lib/mysql/mysql/procs_priv.MYI
-- /var/lib/mysql/mysql/procs_priv.MYD
-- /var/lib/mysql/mysql/servers.MYI
-- /var/lib/mysql/mysql/servers.MYD
-- /var/lib/mysql/mysql/event.MYI
-- /var/lib/mysql/mysql/event.MYD
 
###后记
一篇简析进程-文件-网络三者在内核中的关系的文章,偏内核方向,如有感兴趣的小伙伴欢迎留言探讨。

NSRC技术分享——自制Linux Rootkit检测工具的更多相关文章

  1. Linux入侵检测工具 - RKHunter

    RKHunter是Linux系统平台下的一款开源入侵检测工具 特点 (1)安装便捷,运行快速 (2)扫描范围全,能够检测各种已知的rootkit特征码.端口扫描.常用程序文件的变动情况检查 主要功能 ...

  2. Linux入侵检测工具

    原文:https://www.cnblogs.com/lvcisco/p/4045203.html 一.rootkit简介 rootkit是Linux平台下最常见的一种木马后门工具,它主要通过替换系统 ...

  3. 技术分享 | 自制GreatSQL Docker镜像

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 近期打算制作一个GreatSQL的docker镜像,方便社区用户使用GreatSQL. 制作docker镜像的环境基于Ce ...

  4. 网易视频云技术分享:linux软raid的bitmap分析

    网易视频云是网易倾力打造的一款基于云计算的分布式多媒体处理集群和专业音视频技术,提供稳定流畅.低时延.高并发的视频直播.录制.存储.转码及点播等音视频的PAAS服务,在线教育.远程医疗.娱乐秀场.在线 ...

  5. 【技术分享】linux各种一句话反弹shell总结——攻击者指定服务端,受害者主机(无公网IP)主动连接攻击者的服务端程序(CC server),开启一个shell交互,就叫反弹shell。

    反弹shell背景: 想要搞清楚这个问题,首先要搞清楚什么是反弹,为什么要反弹.假设我们攻击了一台机器,打开了该机器的一个端口,攻击者在自己的机器去连接目标机器(目标ip:目标机器端口),这是比较常规 ...

  6. [Linux 性能检测工具]PIDSTAT

    PIDSTAT NAME pidstat对linux任务的统计 语法 pidstat [ -C comm ] [ -d ] [ -h ] [ -I ] [ -l ] [ -p { pid [,...] ...

  7. [Linux 性能检测工具]TOP

    TOP NAME 显示linux任务 语法 top -hv | -abcHimMsS -d delay -n iterations -p pid [, pid ...] 描述 top程序提供了系统实时 ...

  8. [Linux 性能检测工具]FREE

    FREE NAME free显示系统可用内存和已使用内存 语法 free [-b | -k | -m] [-o] [-s delay ] [-t] [-l] [-V] 描述 free显示了总可用和被用 ...

  9. [Linux 性能检测工具]SAR

    SAR NAME: SAR报告,收集,保存系统活动信息 语法: sar  [ -A ] [ -b ] [ -B ] [ -C ] [ -d ] [ -h ] [ -i interval ] [ -m ...

随机推荐

  1. Caused by: java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0

    1.错误描述 [ERROR:]2015-05-05 16:35:50,664 [异常拦截] org.hibernate.exception.GenericJDBCException: error ex ...

  2. Java中的空值判断

    Java中的空值判断 /** * 答案选项: * A YouHaidong * B 空 * C 编译错误 * D 以上都不对 */ package com.you.model; /** * @auth ...

  3. WDF驱动的编译、调试、安装

    编译和调试使用WDK编译,源代码应包括wdf.h,ntddk.h以及KMDF_VERSION=1,编译使用/GS.KMDF包括以下库:1). WdfDriverEntry.lib(编译时绑定):驱动入 ...

  4. html标签自带样式总结

    一.html标签自带样式 head { display:none; } body { margin:8px; line-height:1.12; } button, textarea, input, ...

  5. 芝麻HTTP:Python爬虫入门之正则表达式

    1.了解正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个"规则字符串",这个"规则字符串"用来 ...

  6. TOJ 4120 Zombies VS Plants

    链接:http://acm.tju.edu.cn/toj/showp4120.html 4120.   Zombies VS Plants Time Limit: 1.0 Seconds   Memo ...

  7. 百度定位一直出现4.9E -324的问题解决方法

    问题:华为mate10一直在申请百度定位的时候出现此问题并且定位权限和定位服务都打开的情况也是返回这个参数 明显没有定位成功,其他手机暂时没有出现(只要打开定位权限就会立即定位成功) 解决:在定位之前 ...

  8. TC命令流量控制测试(针对具体IP和具体进程)

    TC命令流量控制测试 这里测试系统为Linux操作系统,通过简单的TC命令来实现对带宽的控制. 1对具体IP地址的流量控制 这里采用iperf来进行带宽的测试,首先在服务器和客户端都安装上iperf软 ...

  9. LTS和其他解决方案的比较(官方)

    主要根据LTS支持的几种任务(实时任务.定时任务.Cron任务,Repeat任务)和其他一些 开源框架在应用场景上做比较. 实时任务,实时执行 这种场景下,当任务量比较小的时候,单机都可以完成的时候. ...

  10. Scala编程快速入门系列(一)

    目    录 一.Scala概述 二.Scala数据类型 三.Scala函数 四.Scala集合 五.Scala伴生对象 六.Scala trait 七.Actor 八.隐式转换与隐式参数 九.Sca ...