1 引言
随着 Linux 的不断发展,已有越来越多的人开始推广和使用 Linux,其安全性也受到越来越多的挑战。ELF(Executable and Linkable Format)[1]作为 Linux 下最主要的可执行二进制文件格式,自然成了病毒及各种恶意代码的攻击目标。事实证明,有不少Linux下的病毒程序就是通过直接修改ELF文件的方法来实现入侵的[10]。传统的Unix系统(包括Linux)并不会对执行的代码进行完整性和合法性检测,因而让很多病毒程序以及木马程序有机可乘。

代码签名验证是一种能够有效的防止病毒以及其他恶意代码入侵的方法。对于Linux下的代码签名验证机制,早几年就已经有人研究。文[2]提出了在安装时进行签名验证的方法,并通过修改chmod系统调用控制文件的可执行属性,但这种方法无法检测程序安装后对代码的任何修改,有一定的局限性。文[3][4][5]描述的都是在执行时进行签名验证的方法,其中[4][5]采用了缓存已验证文件的策略,使效率较[3]有很大提高。但是,它们将所有ELF文件"一视同仁",没有主次轻重之分,缺少灵活性。

本文提出了一种改进的基于ELF文件格式的代码签名验证机制,通过提供更加灵活的分级验证方式,进一步提高验证效率,并且使系统在安全性与效率方面取得平衡。

2 签名验证原理
我们采用完全符合PKCS[8] 系列标准的签名验证算法,并兼容所有符合X509格式的证书,以RSA[6][7]非对称密钥体制为基础来完成对ELF文件代码的签名验证。

2.1签名
设被签名的数据为m,其数字摘要为h。


h = Hash(m)

其中,Hash是哈希单向散列算法,如MD5、SHA-1等。

设p,q,d为签名者的私有数据,他们都包含在签名者的私钥SK中;n,e为签名者的公开数据,并且都包含在签名者的公钥PK中。这些数据满足以下要求:

n = pq 其中p ≠ q,p q均为大素数;e,d∈RZn 并且e = d-1,ed ≡ 1mod(n);这里,(n) = (p-1)(q-1)。那么,使用签名者私钥对h进行加密即可得到签名值s:


s = E(x) = hdmod n

2.2验证
设被验证数据为m′,其数字摘要为h′。

h′ = Hash(m′)

假设我们已经取得签名者的真实公钥PK,然后我们使用PK中的公开数据e对s进行解密计算,得到还原的数字摘要h′′,这里h′′就相当于是○1式中的h。


h′′ = D(s) = se mod n

现在,我们比较h′和h′′是否完全相同。如果相同则验证通过,否则验证失败。

3 设计与实现
为了便于描述,我们引入以下几个基本概念:

1. 完全摘要值--指对ELF文件的所有数据以及签名相关数据计算出来的摘要值;

2. 不完全摘要值--指对ELF文件的一部分重要数据(主要是ELF文件头)以及签名相关数据计算出来的摘要值;

3. 完全签名值--指对完全摘要值加密所得到的签名值;

4. 不完全签名值--指对不完全摘要值加密所得到的签名值;

5. 系统验证级别--指系统级的验证级别,它适用于系统中所有的ELF文件;

6. 文件验证级别--指单个ELF文件的验证级别,它只适用于指定的某个ELF文件。

签名相关数据是指原始文件大小、签名者公钥标识ID、签名算法、签名时间以及签名者基本信息等数据。

3.1 签名策略
对ELF文件的签名是通过签名工具完成的,与操作系统核心无关,同时也和平台无关。签名过程完全遵循第二节中所描述的标准和原理。

首先,我们通过○1式计算得到两种摘要值:不完全摘要值(hpart)和完全摘要值(hcomp)。然后再通过 2 式使用签名者私钥(SKsign)加密摘要值,从而得到两种签名值:不完全签名值(spart)和完全签名值(scomp)。

最后,我们将不完全签名值和完全签名值按照固定的格式组合在一起,并放在被签名文件的末尾。如图3-1所示(括号中的数字表示该字段所占字节数)。

图3-1 代码签名过程及签名值存放

3.2 验证策略
对被执行ELF文件签名值的验证是根据"系统验证级别"和该文件的"文件验证级别"二者进行的。"文件验证级别"是为单个文件设置的验证级别,共分为3个级别,分别由0~2表示。"文件验证级别"保存在每个文件的inode节点标志中,系统管理员可以根据需要设置文件的验证级别。"文件验证级别"的具体含义如表3-1所示。

表3-1:文件验证级别

级别 名称 说明
0 无保护级 不验证该文件的签名值。
1 中保护级 验证该文件的不完全签名值。
2 高保护级 验证该文件的完全签名值。

"系统验证级别"分为四级,分别由0~3表示。"系统验证级别"通过PROC文件系统来进行控制,可以由管理员根据需要进行设置。"系统验证级别"的具体含义如表3-2所示。

表3-2:系统验证级别

级别 名称 说明
0 无保护级 执行所有程序,不进行任何验证。
1 低保护级 根据"文件验证级别"验证被执行文件的签名值。
2 中保护级 "文件验证级别"为0时,根据"系统验证级别"验证被执行文件的签名值;
"文件验证级别"不为0时,根据"文件验证级别"验证被执行文件的签名值。
3 高保护级 验证所有被执行文件的完全签名值。

3.3验证算法
当用户请求执行某个ELF文件时,系统将根据图3-2所示的流程来判断如何验证该文件的签名值。为了提高系统效率,我们将分别为已验证过"不完全签名值"和"完全签名值"的ELF文件维护相应的缓存,当再次请求执行这些文件时,就可以不必重复验证其签名值了。

图3-2:系统级签名值验证机制

图3-2中,"验证不完全签名值"和"验证完全签名值"两项都是整个验证过程的重要步骤。签名值的验证与签名值的生成相对应,验证时首先要根据相应的数据通过 3 式计算出摘要值(h′part或h′comp),然后再使用签名者的公钥(PKsign)通过 ○4 式解密相应的签名值,得到的对应的摘要值(h′′part或h′′comp)。最后比较h′和h′′是否完全一致,一致则验证通过,不一致则验证失败。

3.4公钥管理
在解密签名数据时,需要用到签名者的证书公钥。由于可能存在多个签名者签发的代码,因此也就存在多个签名者的证书。为了节省系统开销,尽量减小对系统性能的影响,我们必须高效地管理这些证书公钥。为此,我们在系统核心空间中维护了一个信任公钥链表,所有被信任者的公钥都将被放在该公钥链表中。当系统验证代码的签名值时,就可以直接从公钥链表中取得相应的公钥。如果公钥链表中没有相应的公钥,则表示该代码的签名者不被信任,因而验证失败。系统中的被信任公钥是可配置的,系统在启动时将根据配置文件自动初始化核心公钥链表,系统管理员也可以随时对其刷新或者修改。

3.5软件结构
本机制的实现主要包括用户空间的签名验证工具和核心空间的签名验证机制模块两个部分。其中,用户空间的签名验证工具是本机制的辅助工具,其主要功能是对ELF文件进行签名和设置,同时也可对ELF文件的签名值进行验证,在此不再赘述;核心空间的签名验证机制模块可以分为验证策略模块以及公钥管理模块。

3.5.1验证策略模块

验证策略模块负责执行签名值的验证策略,同时负责管理已验证文件的缓存链表。当用户请求执行ELF文件时,该模块就会执行如图3-2所示的验证策略。

验证签名值时,系统将首先查询已验证文件缓存链表,如果发现被验证文件已经被验证过,那么就不必再进行重复验证,直接采用上次的验证结果。如果缓存链表中没有被执行文件,那么就向公钥管理模块请求签名者公钥,然后再验证其签名值。如果验证正确,则说明被执行文件是完整和可信的,就让其执行;否则就禁止执行。

另外,为了保证已验证文件缓存链表和实际文件的一致性,我们必须监视ELF文件的修改情况,当某一ELF文件被修改时,我们应当立即清除已验证文件缓存链表中与该文件相关的验证结果。

3.5.2公钥管理模块

公钥管理模块主要负责对信任公钥链表进行管理,如:初始化链表,获取、添加以及删除公钥节点等。

信任公钥链表由一系列的公钥节点组成,如图3-3所示。

图3-3 核心公钥链表

其中key_id是对应公钥的MD5哈希值,长度为16个字节。从理论上说,不同公钥的key_id相同的概率接近于2128分之一。在很大范围内,我都可以认为key_id和公钥是一一对应的。因此,我们将key_id作为每个公钥的唯一标识。

3.6性能测试
表3-3是一组简单的测试数据,这些数据是通过多次执行后取得的平均值。从中可以看出,通过使用分级机制和缓存机制,系统开销增加不到5%,大大减小了对系统性能的影响。

表3-3 验证签名的系统开销

被执行文件 ls / gcc test.c
不验证签名值 1489μs 567041μs
验证不完全签名值 无缓存 3264μs 569763μs
有缓存 1513μs 567054μs
验证完全签名值 无缓存 8955μs 683295μs
有缓存 1547μs 567482μs

环境:CPU PIV 1.7G,Kernel linux-2.4.18,签名密钥长度为1024位。

4 结束语
代码签名及验证的主要目的是防止执行病毒以及木马程序等恶意代码,提高操作系统的安全性;同时也是为了保护软件开发者以及使用者的利益,软件开发者可以防止他人冒名顶替,而软件使用者也可以确认软件的真实性和完整性。

目前,也有很多系统采用安装时验证代码签名的机制,如微软的windows系列操作系统。但是,仅仅在安装时验证代码签名存在很大的局限性,它无法检测程序安装后对代码的任何修改。因此,采用执行时验证代码签名的机制将大大提高系统的安全性。但安全性增强的同时却导致了系统效率的降低。为了取得安全性与效率的平衡,本文提出了分级验证的机制。对安全要求高的系统,则牺牲一定的效率来提高系统安全性;对安全性要求较低的系统,则牺牲一定的安全性来提高系统效率。

参考资料

  • Tool Interface Standard (TIS) Portable Formats Specification Version 1.1:TIS Committee,October 1993
  • Juha-Petri K?rn? and Mika Leppinen:Signing executables in Linux. April 7th,1998
  • WLF tutorial,http://libeccio.dia.unisa.it/ wlf/wlf_tutorial.html
  • W.A. Arbaugh,G.Ballintijn,L.van Doorn:Signed Executables for Linux. Tech. Report CS-TR-4259. University of Maryland,June 4,2001
  • Luigi Catuogno and Ivan Visconti:A Format-Independent Architecture for Run-Time Integrity Checking of Executable Code. Dipartimento di Informatica ed Applicazioni Università di Salerno Via S. Allende,84081 Baronissi (SA),Italy
  • OpenSSL cryptographic library man page,http://www.openssl.org/docs/crypto/crypto.html
  • OpenSSL SSL/TLS library man page,http://www.openssl.org/docs/ssl/ssl.html
  • PKCS : Public-Key Cryptography Standards. http://www.rsasecurity.com/rsalabs/ pkcs/
  • Tigran Aivazian:Linux Kernel Internals. tigran@veritas.com,22 August,2000
  • LINUX VIRUSES - ELF FILE FORMAT:Marius Van Oers AVERT-NAI Labs,Gatwickstraat 25,1043 GL Amsterdam,The Netherlands,Europe
关于作者
吴志刚,Linux 爱好者,从事过内核安全机制的研究和开发。通过 alex_wzg@yahoo.com.cn 可以和他联系。

Linux下一种 ELF 文件的代码签名验证机制相关推荐

  1. linux下几种目标文件的分析

    本文中用到的命令: gcc -c addvec.c  生成可重定位目标文件addvec.o readelf addvec.o -a 读取可重定位目标文件addvec.o gcc -O2 -c main ...

  2. linux下统计所有py文件的代码多少行

    find . -name "*.py" | xargs cat | wc -l输出:10234find . -name "*.py" | xargs wc -l ...

  3. Linux怎样创建.log文件,列数Linux下几种创建文件的方式

    vi.touch是创建文件的命令 1.现在Linux图形界面做的很好,直接使用编辑器创建的 vi hi.txt vim hi.txt gedit hi.txt 2.间接创建文件 cp .mv cp拷贝 ...

  4. Linux下几种文件传输命令 sz rz sftp scp

    vbs自动启动程序 64位系统编译的程序,在32位系统中运行会有问题 Linux下几种文件传输命令 sz rz sftp scp 2011-10-28 16:08:47|  分类: 默认分类 |  标 ...

  5. linux 快速处理文本文件,Linux 下三种高效的文件处理技巧

    在 Linux 下工作,打交道最多的就是文件了,毕竟 Linux 下工作一切皆文件嘛.Linux 也为大家提供了多种用于处理文件的命令,合理使用这些命令可以大大节省你的时间,并让我们的工作负担不再那么 ...

  6. Linux下的图标与文件关联机制:freedesktop

    Linux下的图标与文件关联机制:freedesktop 目前主流的Linux发行版中,使用的桌面基本都是基于GNOME.KDE.Xfce等环境,这几种桌面环境中,关于桌面图标,文件关联,应用程序启动 ...

  7. linux 网络io命令详解,Linux下五种网络IO模型详解

    本文我们主要来了解一下Unix/Linux下5种网络IO模型:blocking IO, nonblocking IO, IO multiplexing, signal driven IO, async ...

  8. linux误删 bin目录,记linux下rm误删bin文件的解决方式

    平常有个坏习惯,删文件为了快点,喜欢用rm xx*,删除一些关键词文件.今天为了删/bin下几个含有mix关键词的文件,使用命令rm mix*.手贱,mix和*之间多了个空格...灾难发生了!bin下 ...

  9. linux下怎么批量命名文件,linux下的文件操作——批量重命名

    概述:在日常工作中,我们经常需要对一批文件进行重命名操作,例如将所有的jpg文件改成bnp,将名字中的1改成one,等等.文本主要为你讲解如何实现这些操作 1.删除所有的 .bak 后缀: renam ...

最新文章

  1. hp laser103 属性没有配置项_冰雪传奇:起源之上还有装备吗?详解鸿蒙装备合成与属性...
  2. vue.js学习笔记(1)
  3. 数据库的UNDO和REDO
  4. Spring Boot配置文件有提示
  5. python输出jpg_利用python实现.dcm格式图像转为.jpg格式
  6. CSS3实现小黄人动画
  7. 【Java】CMD编译Java源码遇到\ufeff问题的解决方法
  8. 数字猜谜游戏python_Python Tkinter教程系列02:数字猜谜游戏
  9. angular4点击事件监听_angular 事件广播和事件监听
  10. 软件保护技术--- 常见保护技巧
  11. runtime消息转发机制
  12. python server酱_教你如何使用Python向手机发送通知(IFTTT)
  13. Mac Android studio 修改历史查看
  14. (转)区块链:为什么说finchain是下一代金融应用平台
  15. 二十五.决策树之CART决策树的原理和sklearn实现
  16. Multi-armed Bandits(多臂老虎机问题)
  17. 光学字符识别引擎 tesseract-ocr 简介
  18. 用VB.NET(Visual Basic 2010)封装EXCEL VBA为DLL_COM组件(一)
  19. apk protect下载地址
  20. 盘点买房贷款的八大注意事项

热门文章

  1. lan的以太网标准_并非所有以太网电缆都是平等的:通过升级,您可以获得更快的LAN速度...
  2. Java面试笔试考点精讲视频教程
  3. 西门子逻辑运算指令_西门子plc 算术、逻辑运算指令
  4. 微信小程序 版本更新及调试方法
  5. android开发方法数,Android方法数methods超过65536详解
  6. Kali Linux系统安装
  7. Lora1278驱动V4.4.2讲解二:驱动多个SX1278芯片
  8. 更新TKK失败,请检查网络连接的解决办法
  9. 又开始的python-day10-20200821-文件操作相关内置函数-拷贝-读取-写入
  10. 帧率、分辨率、码流的概念