AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 493170
Accepted
Mikhail Morfikov
Mikhail Morfikov
Asked: 2019-01-09 00:13:22 +0800 CST2019-01-09 00:13:22 +0800 CST 2019-01-09 00:13:22 +0800 CST

如何验证内核模块签名?

  • 772

编译内核源代码时,可以选择使用CONFIG_MODULE_SIG*选项对内核模块进行签名。该modinfo工具应该处理验证模块签名的任务,但多年来一直存在一些错误,该工具根本无法再完成这项工作。我得到的只是以下内容:

sig_id:         PKCS#7
signer:
sig_key:
sig_hashalgo:   md4
signature:      30:82:02:F4:06:09:2A:86:48:86:F7:0D:01:07:02:A0:82:02:E5:30:
                ...

所以没有密钥,哈希算法是 md4,甚至没有在内核中编译。

那么如何手动检查和验证模块签名呢?这甚至可能吗?

kernel kernel-modules
  • 1 1 个回答
  • 10576 Views

1 个回答

  • Voted
  1. Best Answer
    mosvy
    2019-01-26T19:14:40+08:002019-01-26T19:14:40+08:00

    是的,这是可能的,但它非常复杂。

    首先,您必须提取模块签名——您可以使用extract-module.sig.pl内核源代码中的脚本:

    $ scripts/extract-module-sig.pl -s MODULE.ko >/tmp/modsig.
    Read 789006 bytes from module file
    Found magic number at 789006
    Found PKCS#7/CMS encapsulation
    Found 670 bytes of signature [3082029a06092a864886f70d010702a0]
    

    其次,您必须从内核中提取证书和公钥;您可以extract-sys-certs.pl为此使用脚本:

    $ scripts/extract-sys-certs.pl /PATH/TO/vmlinux /tmp/cert.x509
    Have 32 sections
    Have 28167 symbols
    Have 1346 bytes of certs at VMA 0xffffffff81be6db8
    Certificate list in section .init.data
    Certificate list at file offset 0xde6db8
    $ openssl x509 -pubkey -noout -inform der -in /tmp/cert.x509 -out /tmp/pubkey
    

    您还可以从 linux 内核构建目录中的certs/signing_key.x509或文件中提取公钥。certs/signing_key.pem

    完成此操作后,您就拥有了所需的所有数据/tmp/modsig,/tmp/cert.x509并且可以继续执行十几个必要的步骤来验证 PKCS#7 签名。

    您可以查看此博客文章以了解整个食谱。


    我试图将整个过程(除了extract-certs.pl步骤)放在一个 perl 脚本中。

    你可以像这样使用它:

    perl checkmodsig.pl /path/to/cert.x509 mod1.ko mod2.ko ...
    

    YMMV。我只尝试过使用 sha512 签名的自定义构建内核。这当然应该通过直接使用 openssl 库来更好地完成,而不是将 slow 和脆弱openssl x509的asn1parse和rsautl调用混在一起。

    checkmodsig.pl

    use strict;
    
    sub through {
        my ($cmd, $data, $cb) = @_;
        use IPC::Open2;
        my $pid = open2 my $from, my $to, ref $cmd ? @$cmd : $cmd;
        print $to $data; close $to; my $out;
        if($cb){ while(<$from>){ last if $out = $cb->($_) } }
        else { local $/; $out = <$from>; }
        waitpid ($pid, 0);
        die "status $?" if $? != 0;
        $out;
    }
    sub gethash {
        my ($d) = @_; my ($alg, $hash);
        through [qw(openssl asn1parse -inform der)], $d, sub {
            if(/(\d+):d=\d+ +hl= *(\d+) +l= *(\d+) +prim: +OCTET STRING/){
                $hash = substr $d, $1 + $2, $3
            }elsif(/prim: +OBJECT +:(sha\w+)/){
                $alg = $1;
            }
            undef
        };
        $alg, $hash
    }
    
    use File::Temp;
    my $tf = new File::Temp;
    my $pub_key;
    my @type = qw(PGP X509 PKCS7);
    my $r = 0;
    if((my $cert = shift) =~ /(\.x509)$|\.pem$/i){
        $pub_key = $tf->filename;
        system qw(openssl x509 -pubkey -noout),
            '-inform', $1 ? 'der' : 'pem',
            '-in', $cert, '-out', $pub_key;
        die "status $?" if $? != 0;
    }
    die "no certificate/key file" unless $pub_key;
    for my $kof (@ARGV){
        open my $ko, '<', $kof or die "open $kof: $!\n";
        seek $ko, -4096, 2 or die "seek: $!";
        read $ko, my $d, 4096 or die "read: $!";
        my ($algo, $hash, $type, $signer_len, $key_id_len, $sig_len, $magic) =
            unpack 'C5x3Na*', substr $d, -40;
        die "no signature in $kof"
            unless $magic eq "~Module signature appended~\n";
        die "this script only knows about PKCS#7 signatures"
            unless $type[$type] eq 'PKCS7';
    
        my $hash = gethash substr $d, - 40 - $sig_len, $sig_len;
        die "hash not found" unless $hash;
    
        my ($alg, $vhash) = gethash
            through [qw(openssl rsautl -verify -pubin -inkey), $pub_key],
                $hash;
    
        seek $ko, 0, 0 or die "seek: $!";
        read $ko, my $d, (-s $ko) - $sig_len - 40 or die "read: $!";
        use Digest::SHA;
        my $fhash = new Digest::SHA($alg)->add($d)->digest;
    
        if($fhash eq $vhash){
            print "OK $kof\n";
        }else{
            print "**FAIL** $kof\n";
            $r = 1;
            warn 'orig=', unpack('H*', $vhash), "\n";
            warn 'file=', unpack('H*', $fhash), "\n";
        }
    }
    exit $r;
    
    • 11

相关问题

  • /proc/net/wireless 如何是 /proc/net/dev 的“克隆”?

  • Linux Mint 内核损坏

  • Linux 内核开发人员如何处理数百万行代码的工作?他们是一种方法吗?[关闭]

  • 通过标签将根文件系统传递给linux内核

  • 以 root 用户身份访问文件系统

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve