首页> 中国专利> 一种基于LSM来实现动态的系统调用劫持的方法

一种基于LSM来实现动态的系统调用劫持的方法

摘要

本发明公开了一种基于LSM来实现动态的系统调用劫持的方法,该方法包括如下步骤:用户进程调用系统调用函数,系统调用函数运行LSM框架插入的钩子函数,钩子函数调用动态加载的LSM检测函数,检查操作上下文和主客体安全域的相关信息,符合定制的安全策略允许系统调用继续执行,不符合定制的安全策略则错误返回。本发明科学合理,使用安全方便,不需要事先编译进内核中就能够动态加载LSM安全模块,使用定制的检测函数,完成一种基于LSM的动态的系统调用劫持。

著录项

  • 公开/公告号CN112668008A

    专利类型发明专利

  • 公开/公告日2021-04-16

    原文格式PDF

  • 申请/专利权人 上海湖顶大数据科技有限公司;

    申请/专利号CN202110012280.8

  • 发明设计人 邓莹;郑翔;孙禹;

    申请日2021-01-06

  • 分类号G06F21/56(20130101);

  • 代理机构31382 上海剑秋知识产权代理有限公司;

  • 代理人徐浩俊

  • 地址 200436 上海市静安区江场三路238号1601室(集中登记地)

  • 入库时间 2023-06-19 10:38:35

说明书

技术领域

本发明涉及互联网安全技术领域,具体为一种基于LSM来实现动态的系统调用劫持的方法。

背景技术

Linux系统中运行的模式有两个:用户态和内核态。系统调用就是进程由用户态进入到内核态的入口,在Linux系统中,可以使用系统调用劫持技术来检测和防范恶意行为,其原理是当用户进程调用系统调用函数时,首先执行该函数中原有的功能错误性检查、传统的DAC访问控制检查,在系统实际访问内核内部对象之前,通过对相关LSM钩子函数的调用,根据具体的安全模块中的访问控制策略,判断该请求是否合法,若与安全策略相符,则继续进行常规访问操作,否则中断该系统的调用,并返回适当的错误信息。其中安全模块引擎部分由具体的安全模块实现。

目前有五种系统调用劫持的方法:1、用户态动态库劫持,通过修改LD_PRELOAD环境变量来改变动态库的加载顺序,优先加载包含系统调用劫持函数的动态库;2、内核态系统调用劫持,替换内核系统调用表里的系统调用函数;3、堆栈式文件系统拦截,劫持文件操作相关的系统调用;4、Linux内核提供的kprobe等内置钩子机制;5、Linux安全模块LSM(Linux Secrity Module)。现有技术中不需要重新编译内核就可以生效的方法有内核态系统调用劫持方法,内核态系统调用劫持方法替换了系统调用表中的系统调用处理函数,这样应用程序执行系统调用时,通过系统调用号,在系统调用表中查找到的就是替换后的新系统调用处理函数,新系统调用处理函数可以做很多特殊的处理,比如:对某些进程调用原来的系统调用处理函数,走原来的流程,对某些不调用原来的系统调用处理函数,走新的流程,但是,内核态系统调用劫持方法有两个缺点:一是Linux内核版本升级过程中,系统调用实现方法在变化,特别是execve这个执行命令的系统调用,变化很大,劫持方法越来越复杂,并且最新版的内核目前还劫持不了,二是execve劫持涉及到汇编语言,不同的CPU型号实现方法不同,普适性差,特别是对于非X86的CPU,实现难度很高。

LSM允许开发者定制自己的安全模块,但限制是定制的安全模块不能以动态加载的方式使用,必须预先编译才能进入Linux内核。因此,人们急需一种基于LSM来实现动态的系统调用劫持的方法。

发明内容

本发明的目的在于提供一种基于LSM来实现动态的系统调用劫持的方法,以解决上述背景技术中提出的问题。

为了解决上述技术问题,本发明提供如下技术方案:

一种基于LSM来实现动态的系统调用劫持的方法,所述方法包括如下步骤:

步骤S1:加载定制的内核模块,转步骤S2;

步骤S2:将一个指针地址作为第一命名模块加载到定制的内核模块,并在第一命名模块中实现一个定制的检测函数,转步骤S3;

步骤S3:用户进程调用系统调用函数,转步骤S4;

步骤S4:系统调用函数运行LSM框架插入的钩子函数,钩子函数调用动态加载的LSM检测函数,根据指针地址将当前安全操作集中第一命名的检测函数的地址保存起来,并且以旧检测函数命名存储,将当前安全操作集中第一命名的检测函数指针指向定制的检测函数,转步骤S5;

步骤S5:系统调用execve在执行时,先调用定制的检测函数,如果通过了定制的检测,再调用第一命名的检测函数,当LSM框架中安全模块的钩子函数被调用时,该安全模块从主客体结构中获取该安全模块的安全上下文信息并将其发送给安全模块策略引擎,安全模块策略引擎根据主客体安全上下文信息以及安全策略库,作出该安全模块对于此次调用的决策,实现系统的调用劫持。

本发明使用LSM来实现动态的系统调用劫持,LSM是Linux内核的一个轻量级通用访问控制框架,它使得各种不同的安全访问控制模型能够以Linux可加载内核模块的形式实现出来,用户可以根据其需求选择适合的安全模块加载到Linux内核中,从而大大提高了Linux安全访问控制机制的灵活性和易用性;LSM采用了通过在内核源代码中放置钩子函数的方法来仲裁对内核内部对象进行的访问;首先用户访问系统调用时,先通过原有的内存接口进行功能性的错误检查,然后再进行Linux自主访问控制权限检查。在访问内核的内部对象之前,通过安全模块的钩子函数调用LSM,LSM查看操作上下文和主客体安全域的相关信息决定是否允许请求,觉得访问的合法性,返回信息。在内核即将进行实际操作之前调用安全模块中的钩子函数,并通过钩子函数访问安全策略来决定是否允许该操作的执行。通过将当前LSM模块安全操作集合中第一命名的检测函数替换为定制的检测函数,突破了LSM机制本身不允许动态加载的限制。

进一步的,所述步骤S2中在定制的内核模块中实现一个定制的检测函数,所述定制的内核模块中添加一个指针地址作为第一命名模块加载参数,所述检测函数用于检查将被执行的程序是否处于临时目录下,如果程序处于临时目录下,则认为是一个危险程序,禁止该程序执行,如果程序不处于临时目录下,则认为是一个安全程序,允许该程序执行。

本发明可以根据用户的需求在定制的内核模块中实现一个定制的检测函数,并利用指针地址将当前安全操作集里的第一命名检测函数地址以旧检测函数地址保存起来,将当前安全操作集里的第一命名检测函数指针指向定制的检测函数,从而实现定制的检测函数被内核执行,突破了LSM机制本身不允许动态加载的限制。

进一步的,所述步骤S2中定制的检测函数插入链表头部,可将定制的检测函数以链表的形式串联起来。

本发明LSM2.0框架中将定制的检测函数插入链表头部,并且,将定制的检测函数以链表的形式串联起来,在允许多种LSM模块同时生效的情况下,使定制的检测函数优先生效,实现系统调用劫持。

进一步的,所述步骤S2中将定制函数以链表形式串联的步骤如下:

在LSM框架中的钩子函数指针结构中添加一个链表,将定制的检测函数插入链表头部;

在LSM框架中创建一个字段数组,该字段数组中的每一个指针对应一个安全模块的安全域;

在LSM框架初始化阶段,LSM框架根据配置获得多个安全模块的启动参数,并初始化链表结构;

当安全模块加载进入Linux内核时,安全模块获得一个钩子函数指针结构体,然后将该安全模块中的钩子函数与该钩子函数指针结构体中的指针相连接并给该安全模块分配一个定位值,之后通过钩子函数指针结构体的链表结构将安全模块与其他已加载进入Linux内核的安全模块的钩子函数指针结构体链接,其中,定位值代表安全模块的启动顺序。

本发明能够让LSM框架支持多个安全模块同时运行,并采用并列链接的方式使得各安全模块之间相互独立,地位平等。

进一步的,所述步骤S2中若将定制的检测函数插入链表头部,在步骤S4中定制的检测函数以链表的形式存在,运行LSM框架插入的钩子函数,定制的检测函数优先生效,实现系统调用劫持。

本发明将定制的检测函数插入在系统调用函数钩子函数头部,只需要少量修改Linux内核代码,不影响系统性能。

进一步的,所述步骤S2中若将定制的检测函数插入链表头部,所述步骤S4中按链表顺序依次运行定制的检测函数。

本发明按链表顺序依次运行定制的检测模块,支持多个安全模块同时运行,并采用并列链接的方式使得各安全模块之间相互独立,地位平等。

与现有技术相比,本发明所达到的有益效果是:本发明使用LSM来实现动态的系统调用劫持,LSM是Linux内核的一个轻量级通用访问控制框架,它使得各种不同的安全访问控制模型能够以Linux可加载内核模块的形式实现出来,用户可以根据其需求选择适合的安全模块加载到Linux内核中,从而大大提高了Linux安全访问控制机制的灵活性和易用性;LSM采用了通过在内核源代码中放置钩子函数的方法来仲裁对内核内部对象进行的访问;首先用户访问系统调用时,先通过原有的内存接口进行功能性的错误检查,然后再进行Linux自主访问控制权限检查。在访问内核的内部对象之前,通过安全模块的钩子函数调用LSM,LSM查看操作上下文和主客体安全域的相关信息决定是否允许请求,觉得访问的合法性,返回信息。在内核即将进行实际操作之前调用安全模块中的钩子函数,并通过钩子函数访问安全策略来决定是否允许该操作的执行;本发明可以根据用户的需求在定制的内核模块中实现一个定制的检测函数,并利用指针地址将当前安全操作集里的第一命名检测函数地址以旧检测函数地址保存起来,将当前安全操作集里的第一命名检测函数指针指向定制的检测函数,从而实现定制的检测函数被内核执行;本发明LSM2.0框架中将定制的检测函数插入链表头部,并且,将定制的检测函数以链表的形式串联起来,在允许多种LSM模块同时生效的情况下,使定制的检测函数优先生效,实现系统调用劫持;本发明能够让LSM框架支持多个安全模块同时运行,并采用并列链接的方式使得各安全模块之间相互独立,地位平等;本发明将定制的检测函数插入在系统调用函数钩子函数头部,只需要少量修改Linux内核代码,不影响系统性能;本发明配置简单,管理方便,安全管理员只需要简单的配置定制的检测函数,不需事先编译进内核当中,就能够动态地加载安全模块;本发明通过将当前LSM模块安全操作集合中第一命名的检测函数替换为定制的检测函数,突破了LSM机制本身不允许动态加载的限制。

附图说明

图1是本发明一种基于LSM来实现动态的系统调用劫持的方法流程示意图;

图2是本发明一种基于LSM来实现动态的系统调用劫持的方法LSM1.0框架流程示意图;

图3是本发明针对单LSM模块劫持execve系统调用实施例的流程示意图;

图4是本发明一种基于LSM来实现动态的系统调用劫持的方法LSM2.0框架流程示意图;

图5是本发明针对多LSM模块劫持execve系统调用实施例的流程示意图;

图6是本发明使用execve系统调用劫持函数进行检测实施例的流程示意图。

具体实施方式

下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。

请参阅图1-5,本发明提供技术方案:

如图1-3所示,一种基于LSM来实现动态的系统调用劫持的方法,所述方法包括如下步骤:

步骤S1:加载定制的内核模块,转步骤S2;

步骤S2:将一个指针地址作为第一命名模块加载到定制的内核模块,并在第一命名模块中实现一个定制的检测函数,转步骤S3;

步骤S3:用户进程调用系统调用函数,转步骤S4;

步骤S4:系统调用函数运行LSM框架插入的钩子函数,钩子函数调用动态加载的LSM检测函数,根据指针地址将当前安全操作集中第一命名的检测函数的地址保存起来,并且以旧检测函数命名存储,将当前安全操作集中第一命名的检测函数指针指向定制的检测函数,转步骤S5;

步骤S5:系统调用execve在执行时,先调用定制的检测函数,如果通过了定制的检测,再调用第一命名的检测函数,当LSM框架中安全模块的钩子函数被调用时,该安全模块从主客体结构中获取该安全模块的安全上下文信息并将其发送给安全模块策略引擎,安全模块策略引擎根据主客体安全上下文信息以及安全策略库,作出该安全模块对于此次调用的决策,实现系统的调用劫持。

所述步骤S2中在定制的内核模块中实现一个定制的检测函数,所述定制的内核模块中添加一个指针地址作为第一命名模块加载参数,所述检测函数用于检查将被执行的程序是否处于临时目录下,如果程序处于临时目录下,则认为是一个危险程序,禁止该程序执行,如果程序不处于临时目录下,则认为是一个安全程序,允许该程序执行。

所述步骤S2中定制的检测函数插入链表头部,可将定制的检测函数以链表的形式串联起来。

所述步骤S2中将定制函数以链表形式串联的步骤如下:

在LSM框架中的钩子函数指针结构中添加一个链表,将定制的检测函数插入链表头部;

在LSM框架中创建一个字段数组,该字段数组中的每一个指针对应一个安全模块的安全域;

在LSM框架初始化阶段,LSM框架根据配置获得多个安全模块的启动参数,并初始化链表结构;

当安全模块加载进入Linux内核时,安全模块获得一个钩子函数指针结构体,然后将该安全模块中的钩子函数与该钩子函数指针结构体中的指针相连接并给该安全模块分配一个定位值,之后通过钩子函数指针结构体的链表结构将安全模块与其他已加载进入Linux内核的安全模块的钩子函数指针结构体链接,其中,定位值代表安全模块的启动顺序。

所述步骤S2中若将定制的检测函数插入链表头部,在步骤S4中定制的检测函数以链表的形式存在,运行LSM框架插入的钩子函数,定制的检测函数优先生效,实现系统调用劫持。

所述步骤S2中若将定制的检测函数插入链表头部,所述步骤S4中按链表顺序依次运行定制的检测函数。

如图4-6所示,所述步骤S2中定制的检测函数插入链表头部,可将定制的检测函数以链表的形式串联起来。

所述步骤S2中将定制函数以链表形式串联的步骤如下:

在LSM框架中的钩子函数指针结构中添加一个链表,将定制的检测函数插入链表头部;

在LSM框架中创建一个字段数组,该字段数组中的每一个指针对应一个安全模块的安全域;

在LSM框架初始化阶段,LSM框架根据配置获得多个安全模块的启动参数,并初始化链表结构;

当安全模块加载进入Linux内核时,安全模块获得一个钩子函数指针结构体,然后将该安全模块中的钩子函数与该钩子函数指针结构体中的指针相连接并给该安全模块分配一个定位值,之后通过钩子函数指针结构体的链表结构将安全模块与其他已加载进入Linux内核的安全模块的钩子函数指针结构体链接,其中,定位值代表安全模块的启动顺序。

所述步骤S2中若将定制的检测函数插入链表头部,在步骤S4中定制的检测函数以链表的形式存在,运行LSM框架插入的钩子函数,定制的检测函数优先生效,实现系统调用劫持。

所述步骤S2中若将定制的检测函数插入链表头部,所述步骤S4中按链表顺序依次运行定制的检测函数。

实施例一:

步骤101:加载定制的内核模块,将security_ops指针地址作为模块加载参数。编写一个定制的内核安全模块,在模块中实现了一个定制的new_bprm_check_security函数,这个函数检查将被执行的程序是否处于/tmp临时目录下,如果程序处于/tmp临时目录下,则认为该程序是一个危险程序,禁止其执行,转步骤102;

步骤102:模块加载到内核中后,根据security_ops指针地址,将当前安全操作集security_operations里的bprm_check_security函数地址保存起来,如存为old_bprm_check_security,转步骤103;

步骤103:将当前安全操作集security_operations里的bprm_check_security函数指针,指向定制的new_bprm_check_security检测函数。

系统调用execve在执行过程中,原本会调用bprm_check_security检测函数,现在改为调用new_bprm_check_security检测函数,这样就实现了对execve系统调用的劫持。

实施例二:

步骤201:加载定制的内核模块,在该模块中已经实现了一个定制的new_bprm_check_security检测函数,转步骤202;

步骤202:模块加载到内核后,初始化一个exec_hook_list数据结构,并将其中的bprm_check_security函数指针指向new_bprm_check_security,转步骤203;

步骤203:将exec_hook_list插入到security_hook_heads链表的头部,使得new_bprm_check_security也处于bprm_check_security函数链表的头部。

系统调用execve在执行过程中,会依次调用检测函数链表上各个LSM模块的bprm_check_security检测函数,现在将new_bprm_check_security检测函数插在头部,使其总是最先生效,最先进行检测,这样就实现了对execve系统调用的劫持。

实施例三:

步骤301:正常用户或入侵者执行命令,发起execve系统调用,转步骤302;

步骤302:因execve系统调用已被劫持,故execve系统调用进入内核态后,调用new_bprm_check_security检测函数,进行检测,转步骤303;

步骤303:根据定制的安全规则,检测本次命令执行是否是一次异常攻击行为,转步骤304;

步骤304:如果判断是异常行为,则终止异常命令的执行。如果不是异常行为,转步骤305;

步骤305:继续执行原来的old_bprm_check_security函数,继续完成原来要做的安全检测。

对于多LSM模块的场景,如果经new_bprm_check_security检测不是异常行为,则步骤305继续执行检测函数链表上原本该执行的各bprm_check_security函数。

对于本领域技术人员而言,显然本发明不限于上述示范性实施例的细节,而且在不背离本发明的精神或基本特征的情况下,能够以其他的具体形式实现本发明。因此,无论从哪一点来看,均应将实施例看作是示范性的,而且是非限制性的,本发明的范围由所附权利要求而不是上述说明限定,因此旨在将落在权利要求的等同要件的含义和范围内的所有变化囊括在本发明内。不应将权利要求中的任何附图标记视为限制所涉及的权利要求。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号