0%

Linux系统加固 - (内核)模块签名

目的

防止未授权的或恶意的驱动模块加载

测试模块准备

参考https://paper.seebug.org/779/

先准备个测试module

功能很简单: 内核加载时打印Hello World, 卸载时打印Goodbye World

driver_example.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Hcamal");

int hello_init(void)
{
printk(KERN_INFO "Hello World\n");
return 0;
}

void hello_exit(void)
{
printk(KERN_INFO "Goodbye World\n");
}

module_init(hello_init);
module_exit(hello_exit);

Makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ifneq ($(KERNELRELEASE),)

obj-m := driver_example.o

else

KERN_DIR ?= /usr/src/linux-$(shell uname -r)/
PWD := $(shell pwd)

default:
$(MAKE) -C $(KERN_DIR) M=$(PWD) modules

endif

clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

最后通过make生成driver_example.ko

通过insmod driver_example.kormmod driver_example.ko来进行内核模块的加载、删除

dmesg -T可以看到打印的信息

1
2
[Tue Sep 14 17:25:16 2021] Hello World
[Tue Sep 14 17:25:20 2021] Goodbye World

签名配置

内核模块签名 https://www.kernel.org/doc/html/latest/admin-guide/module-signing.html?highlight=signing

1
2
3
4
5
6
7
8
9
Enable loalable module support --->

[*] Module signature verification

[*] Require modules to be validly signed

[*] Automatically sign all modules

Which hash algorithm should modules be signed with?(Sign modules with SHA-512)

最终生成的关键配置项

1
2
3
4
5
6
7
CONFIG_MODULE_SIG=y                           # 开启模块签名
CONFIG_MODULE_SIG_FORCE=y # 未通过签名核验的模块拒绝加载
CONFIG_MODULE_SIG_ALL=y # modules_install时自动给模块签名
CONFIG_MODULE_SIG_SHA512=y
CONFIG_MODULE_SIG_HASH="sha512" # 算法sha512

CONFIG_MODULE_SIG_KEY="certs/signing_key.pem" # 证书文件, 不存在的话自动生成, 存在的话直接使用

重新编译内核和安装、重启系统

1
2
3
make -j`nproc`
make modules_install
make install

确认已启用内核签名

dmesg -T | grep -i 'x.*509'

1
2
3
4
5
[Tue Sep 14 18:54:43 2021] Asymmetric key parser 'x509' registered
[Tue Sep 14 18:54:43 2021] Loading compiled-in X.509 certificates
[Tue Sep 14 18:54:43 2021] Loaded X.509 cert 'Build time autogenerated kernel key: 61e75ddf5386c7378280fbed3f5d3b5f39dc5b9a'
[Tue Sep 14 18:54:43 2021] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[Tue Sep 14 18:54:43 2021] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'

cat /proc/keys

1
2
3
4
5
6
7
8
9
075b6d49 I------     1 perm 1f0b0000     0     0 keyring   .builtin_trusted_keys: 1
07b9d7e9 I------ 1 perm 1f030000 0 0 asymmetri sforshee: 00b28ddf47aef9cea7: X509.rsa []
0b22aa86 I--Q--- 2 perm 1f3f0000 0 65534 keyring _uid.0: empty
2515517c I------ 1 perm 1f0b0000 0 0 keyring .builtin_regdb_keys: 1
2a5884f8 I--Q--- 1 perm 1f3f0000 0 65534 keyring _uid_ses.0: 1
2cad08c9 I------ 1 perm 1f030000 0 0 keyring .id_resolver: empty
301e3a1b I------ 1 perm 1f030000 0 0 asymmetri `Build time autogenerated kernel key`: 61e75ddf5386c7378280fbed3f5d3b5f39dc5b9a: X509.rsa 39dc5b9a []
31476e28 I------ 1 perm 1f030000 0 0 keyring .dns_resolver: empty
357f2eb8 I--Q--- 1 perm 0c030000 0 65534 keyring .user_reg: 2

验证 - 只允许加载签名后的模块

加载测试模块insmod driver_example.ko - 失败

1
insmod: ERROR: could not insert module driver_example.ko: Key was rejected by service

用系统生成的key、证书对模块进行签名

1
scripts/sign-file sha512 certs/signing_key.pem certs/signing_key.pem /home/test/driver_example.ko

加载签名后的测试模块insmod driver_example.ko - 成功

dmesg -T | tail看到Hello World的输出

1
[Wed Sep 15 10:15:18 2021] Hello World

签名信息会被追加到模块尾部 hexdump -C driver_example.ko | tail

1
2
3
4
5
6
7
8
9
10
00001250  d3 5b d7 6e 42 b8 3d 6b  ad 1d 17 7c dc cf 5f 9d  |.[.nB.=k...|.._.|
00001260 07 02 93 45 d5 ea e4 cd 2c 3d ae 92 bd 33 81 4f |...E....,=...3.O|
00001270 67 39 a7 c2 a9 96 42 d0 87 1c 19 d9 e4 79 a3 c5 |g9....B......y..|
00001280 5e 83 a6 3c 1e 13 70 93 c3 4a ad 51 32 d8 ab e5 |^..<..p..J.Q2...|
00001290 26 b4 ed 27 ca 98 37 78 70 d7 79 69 cf 9f 5b 67 |&..'..7xp.yi..[g|
000012a0 98 f6 17 84 8d 4c 32 0a b0 00 00 02 00 00 00 00 |.....L2.........|
000012b0 00 00 00 02 a9 7e 4d 6f 64 75 6c 65 20 73 69 67 |.....~Module sig|
000012c0 6e 61 74 75 72 65 20 61 70 70 65 6e 64 65 64 7e |nature appended~|
000012d0 0a |.|
000012d1

删除签名信息

1
strip --strip-debug driver_example.ko

证书文件生成方式

参照certs/Makefile, 更多自签名证书相关自行搜索

1
2
3
4
$(Q)openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \
-batch -x509 -config $(obj)/x509.genkey \
-outform PEM -out $(obj)/signing_key.pem \
-keyout $(obj)/signing_key.pem \

注意事项

  • 公司如果有统一的签名管理体系的话, 生产环境不建议自动生成签名证书
  • 私钥保护好, 避免被恶意人员利用