Linux下检测漏洞软件包
前言
随着开源软件热潮的进一步发展和在互联网上的广泛应用,目前因开源软件存在漏洞而造成的影响变得巨大。如Bash漏洞、Openssl心脏出血漏洞、ImageMagick命令执行漏洞、ffmpeg文件读取漏洞等等。此类软件漏洞往往没能及时修复,主要有以下原因:
1.因为此类漏洞已影响线上业务运行,而往往容易被系统运维管理者忽视;
2.不太清楚线上业务的依赖环境,所以也不敢随意更新软件包版本;
3.软件维护者已经发布更新了软件包,但是系统运维管理者没能及时获悉。
那么,作为一个企业线上业务的运维管理或者安全管理者,应该如何有效地更新系统软件包版本呢?笔者作为一名乙方网络安全产品的开发者,以HIDS中的软件包版本模块为例,简单讲讲,主机安全检测系统是如何检测存在漏洞的软件包版本的。
一、包版本比对的方法
常见的Linux环境下的软件包版本管理有apt(Debian系)和yum(Redhat系)等,其中apt在Debian系Linux系统上管理的.deb包,yum管理的是.rpm软件包。以笔者的centos系统为例,通过如下命令可以获取到目前系统中存在的软件包版本:
rpm -qa --qf '%{NAME}|%{VERSION}|%{RELEASE}|%{INSTALLTIME}|%{SIGPGP:pgpsig}\n'
获取到的部分软件列表如下:
可以很容易找到当前系统中软件对于到版本号。那么,该如何利用这些版本号找出可能存在漏洞到软件包呢?以Redhat为例,Redhat官方提供了基于软件包检测漏洞的一整套检测体系:OVAL标准。简单来说,其检测方法就是基于OVAL定义的标准进行软件版版本匹配,低于最新版本的包则可能存在漏洞。
关于什么是OVAL可以其官方网站:http://oval.mitre.org/ 关于OVAL的语法标准定义可以参考:OVAL_Language_Specification 。国内某安全研究者在Github上做了个简单概括总结,可以参考:OVAL学习。基于此标准,Redhat和Ubuntu官方都维护了一份存在漏洞的软件包版本规则列表。
Redhat系参考:https://www.redhat.com/security/data/oval/
Ubuntu系参考:https://people.canonical.com/~ubuntu-security/oval
通过将本地软件包和官方提供的最新规则库对比,就可以找出存在漏洞的软件包。那么,基于这种检测方法,笔者在基于Python语言开发HIDS相应模块中,找到了其相关的Python第三方库。
检测rpm包的Python第三方库为:version_utils
检测deb包的Python库为:apt_pkg
apt_pkg库在Debian系Linux系统中默认已经自带了,不需要额外安装。但是笔者的HIDS相应模块运行环境是在Centos下,而centos下的python包中并没有提供apt_pkg库。在查找pypi.org以及各种查找后也并没有找个相应的Python包。无奈,笔者只能根据apt包管理器的项目源码,自行编译出相关的Python第三方包。
查阅apt项目资料有:
apt project source code: https://github.com/chaos/apt
python-apt project source code: https://github.com/Jolicloud/python-apt
ibapt-pkg-dev:http://charette.no-ip.com:81/programming/doxygen/libapt-pkg/classdebVersion ingSystem.html
至此,apt项目中核心部分的版本比对的代码(详见源码中的DoCmpVersion()函数)算是有了,但是笔者仔细看了其源码两遍都没有看懂!!其比对的算法还有略有复杂,采用Python重写这个算法怕是有点儿难。鉴于此,加上笔者之前有了解可以将c语言编译为Python库,所以笔者决定直接将其源码块提取出来,将其编程成.so库共python直接调用。
二、移植apt_pkg Python类库
对于如何将c语言编译为Python库,本文在此不做详细赘述。只是将当时编译c语言扩展的Python库的相关资料列出,有兴趣的同学可以自行了解、学习:
浅谈 Python 程序和 C 程序的整合:https://www.ibm.com/developerworks/cn/linux/l-cn-pythonandc/index.html
简单的C扩展模块:https://python3-cookbook.readthedocs.io/zh_CN/latest/c15/p02_write_simple_c_extension_module.html
在此,笔者给出自己编译好的Python版apt_pkg库:apt_pkg.tar 。这里忽略详细的制作细节,编好的setup.py代码如下:
# -*- coding: UTF-8 -*-
# author: s0nnet
# time: 2018-07-24
# desc: python extend of `apt_pkg`
# Note:
# This python extend ware compiled on centos 7.2 with python2.7
# It is self-contained on Debian's Linux platform but doesn't on RedHat.
# So, you need self compile it. here are some useful infermation:
# 1. apt project source code: https://github.com/chaos/apt
# 2. python-apt project source code: https://github.com/Jolicloud/python-apt
# 3. ibapt-pkg-dev: http://charette.no-ip.com:81/programming/doxygen/libapt-pkg/classdebVersioningSystem.html
from distutils.core import setup, Extension
_module = Extension('apt_pkg', sources=['debversion.c'])
setup(name="apt_pkg", version="1.0", ext_modules=[_module])
通过上述的setup.py文件,可以很容易打包成Python第三方扩展类库,其常用打包命令如下:
#python setup.py build # 编译
#python setup.py install # 安装
#python setup.py sdist # 生成压缩包(zip/tar.gz)
#python setup.py bdist_rpm # 生成rpm包
至此,对于apt_pkg库的移植总算是完成了。其使用方法也和Debian下的apt_pkg包一致:
# -*- coding: UTF-8 -*-
# author: s0nnet
# time: 2018-07-24
# desc: test
import apt_pkg
ver_a = "0.6.35-0ubuntu7"
ver_b = "0.6.35-0ubuntu7.2"
result = apt_pkg.version_compare(ver_a, ver_b)
print "version_compare result:", result
三、Go语言版apt_pkg库
随着笔者所开发HIDS系统的进一步版本迭代,对整个系统的稳定性和性能提出了更高的要求。整个项目也从Python转为了使用Go语言重构。参考Github上相关开发者提供的Go语言版软件包版本比对,其项目如下:
go-rpm-version:https://github.com/knqyf263/go-rpm-version
这里笔者给出自己项目中用到的包含了Debian系和Redhat系两大类Linux系统的软件包版本比对算法的Go语言包:pkgVersion.tar (后期这块代码重构工作非笔者自己所做)。其使用方法比较简单,可以测试case:
package vpkg
import (
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestCompareVersion(t *testing.T) {
Convey("test apt version", t, func() {
So(CompareVersion("4.3-11+deb8u1", "4.3-11"), ShouldEqual, 1)
So(CompareVersion("4.3-11+deb8u1", "4.3-12"), ShouldEqual, -1)
So(CompareVersion("2.11.e1", "2.12"), ShouldEqual, -1)
So(CompareVersion("0A.3", "000B"), ShouldEqual, -1)
So(CompareVersion("2.11", "3"), ShouldEqual, -1)
So(CompareVersion("1.8.4-5ubuntu1.2", "1.8.4-5ubuntu1.3"), ShouldEqual, -1)
})
}
至此,这篇文章算是已经结束了。这里也只是简单提到HIDS开发过程中关于系统软件包版本漏洞检测方法的一点点核心要点。关于HIDS中关于系统软件包版本漏洞检测的工程化技术实现及其检测原理,可以继续关注笔者关于HIDS开发方面的文章。