### 前言

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. 为什么选择Netty作为基础通信框架?

    在开始之前,我先讲一个亲身经历的故事:曾经有两个项目组同时用到了NIO编程技术,一个项目组选择自己开发NIO服务端,直接使用JDK原生的API,结果两个多月过去了,他们的NIO服务端始终无法稳定,问题 ...

  2. 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 ...

  3. Ajax前后台交互函数

    function AJAX(obj){ //做网络请求的时候参数以对象的形式传递进来 //我们规定obj里面包含属性:url, //请求方式type, //date前端给后端传递的参数 //回调函数s ...

  4. Educational Codeforces Round 36 (Rated for Div. 2) E. Physical Education Lessons

    提供两种思路 一种线段树区间更新 另一种用map维护连续的区间,也是题解的思路 第二种很难写(我太渣,看了别人的代码,发现自己写的太烦了) #include<iostream> #incl ...

  5. Octave 命令积累

    Octave Learning : puts all elements into a single vector :put B at A's right :put B at A's Bottom :将 ...

  6. box-sizing -- 盒模型

    项目开发中,在浏览同事的代码,发现他经常用一个属性--box-sizing,很好奇是什么,于是乎,上网查阅资料学了起来. 首先我们先复习一下盒模型的组成:一个div通常由 content(内容)+ma ...

  7. Keras官方中文文档:keras后端Backend

    所属分类:Keras Keras后端 什么是"后端" Keras是一个模型级的库,提供了快速构建深度学习网络的模块.Keras并不处理如张量乘法.卷积等底层操作.这些操作依赖于某种 ...

  8. 第二篇:操纵MySQL数据库(2) - 基于ORM思想的SQLAlchemy库

    前言 本文讲解在Python语言中使用SQLAlchemy库操纵MySQL数据库的方法. 由于具体内容涉及较多,本文仅以插入及展示数据为例,更多内容请查阅有关文档. ORM ORM也即对象 - 关系映 ...

  9. 又把JDK改回JDK1.8的过程

    我已经在崩溃的边缘. 先在控制面板卸载9.0.4,非常好,卸的干干净净的. 然后继续卸载9.0.1,也很好,卸的很干净. 命令行: 安装JDK1.8 装完了,去配环境变量: 4个环境变量都配齐了. J ...

  10. luogu2402 奶牛隐藏

    题目描述 在一个农场里有n块田地.某天下午,有一群牛在田地里吃草,他们分散在农场的诸多田地上,农场由m条无向的路连接,每条路有不同的长度. 突然,天降大雨,奶牛们非常混乱,想要快点去躲雨.已知每个田地 ...