Fedora等、モジュールを署名しているディストリビューションの場合、カーネルモジュールのELFバイナリの最後に署名がついています。これがとんな感じなの?いうところはkernelのDocumentation/module-signing.txtに書かれています。/proc/keysで鍵の確認とかはrootじゃないとできません。 テストした環境はFedora 22(x86_64)です。
/proc/keysをrootで開くとこんなふうになってます。
root@saga:/proc# cat /proc/keys 02c9848e I------ 1 perm 1f030000 0 0 keyring .persistent_register: 1 039b4a4a I--Q--- 3 perm 1f3f0000 0 65534 keyring _uid.0: empty 096cc3a2 I------ 1 perm 1f030000 0 0 keyring .system_blacklist_keyring: empty 13630bc6 I------ 1 perm 1f030000 0 0 asymmetri Fedora kernel signing key: 5df3cf03be233f1af50438d0fce94781004fd41d: X509.RSA 004fd41d [] 22310e67 I------ 1 perm 1f0b0000 0 0 keyring .system_keyring: 1 37ff8e04 I--Q--- 6 perm 3f030000 0 0 keyring _ses: 1 3cbed499 I--Q--- 1 perm 1f3f0000 0 65534 keyring _uid_ses.0: 1
これらファイルのうち.system_keyringがカーネルに埋め込まれている公開鍵とのことです。
そして、.system_keyringの行の一番左側のカラムにある数値(ここでは22310e67)を使って情報を見れます。
root@saga:/proc# keyctl list 0x22310e67 1 key in keyring: 325258182: ---lswrv 0 0 asymmetric: Fedora kernel signing key: 5df3cf03be233f1af50438d0fce94781004fd41d
そしたら、カーネルモジュールを見てます。署名はELFのセクションではなくて、単にELFバイナリの最後にくっついています。hexdumpで見てみると最後のほうはこうなっています。
0000d4b0 39 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |9...............| 0000d4c0 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 0000d4d0 46 65 64 6f 72 61 20 6b 65 72 6e 65 6c 20 73 69 |Fedora kernel si| 0000d4e0 67 6e 69 6e 67 20 6b 65 79 5d f3 cf 03 be 23 3f |gning key]....#?| 0000d4f0 1a f5 04 38 d0 fc e9 47 81 00 4f d4 1d 02 00 7f |...8...G..O.....| 0000d500 3b 03 3a 63 a8 cb bc f5 fd 02 02 5a 43 fd 48 69 |;.:c.......ZC.Hi| 0000d510 fe 1e 58 a0 9b 88 1d 24 f6 91 d1 14 f7 83 69 a7 |..X....$......i.| 0000d520 36 3c ac d0 90 6e e0 ed c7 9d 7a e4 ff 2e c0 14 |6<...n....z.....| 0000d530 da 62 cc f8 d4 37 cf e5 f0 c5 ec 8b bf 8c a9 f3 |.b...7..........| 0000d540 38 bf 12 35 2b e8 30 8e 87 34 f3 f1 52 f8 55 0b |8..5+.0..4..R.U.| 0000d550 46 74 37 1c da 4b 7d 79 47 a0 25 08 85 53 6d e6 |Ft7..K}yG.%..Sm.| 0000d560 de 4e 46 8d f8 5e 79 b5 64 fa 10 33 7f 87 29 34 |.NF..^y.d..3..)4| 0000d570 f5 92 4a 99 76 12 aa be 76 d0 09 85 72 91 37 4f |..J.v...v...r.7O| 0000d580 0a ba 2a 56 cc 63 df a8 cb ff 8a 82 e7 f4 8a 8e |..*V.c..........| 0000d590 b2 de e6 50 49 22 13 da 12 b0 42 ef 6a a6 12 b5 |...PI"....B.j...| 0000d5a0 8a 9b 7f e4 92 6e 3b 52 db 49 e5 30 e9 cf ed e9 |.....n;R.I.0....| 0000d5b0 c8 3a 84 6d a8 cb 53 fd 8e 11 8f 31 2b 15 18 3e |.:.m..S....1+..>| 0000d5c0 14 53 a1 45 5f ce af ab 1d 7f e8 9d 93 66 5b ed |.S.E_........f[.| 0000d5d0 df f5 42 da f3 e0 03 ec 8d 40 c4 f6 9a 3d 90 32 |..B......@...=.2| 0000d5e0 c1 02 06 f6 8d 54 c7 9c 27 e4 86 29 e5 37 72 01 |.....T..'..).7r.| 0000d5f0 9a 3b a6 3c df b8 15 47 13 a9 bd 9c f0 a5 ac 09 |.;.<...G........| 0000d600 bd 35 b0 43 a7 c7 64 76 e5 06 27 ea 96 c5 0d 1d |.5.C..dv..'.....| 0000d610 2c ae 7a e0 27 3a 3e 24 b9 b9 ec eb 6f a1 05 ce |,.z.':>$....o...| 0000d620 51 d4 af 45 7e 37 07 69 3c 1f 81 6f bf 06 aa 58 |Q..E~7.i<..o...X| 0000d630 24 92 24 cb c2 1d a6 88 be 0f bc 79 02 63 9d 9f |$.$........y.c..| 0000d640 15 b7 65 fc f6 d3 93 d0 cd 68 4a 71 67 eb 9d 35 |..e......hJqg..5| 0000d650 ca b0 83 85 19 7b 95 b5 27 e1 16 57 d7 1b 93 d7 |.....{..'..W....| 0000d660 3f 34 04 0b d8 47 5b 6e 6a a9 a1 4c 9f 35 f4 e3 |?4...G[nj..L.5..| 0000d670 10 86 8a f4 8d 13 0d a7 41 0e 3e c4 ba 4b c2 b1 |........A.>..K..| 0000d680 e7 82 0c 1a b8 ba 1a 06 90 de 90 02 c2 8a ea 5a |...............Z| 0000d690 63 48 6a f1 58 26 90 0a 84 5f 76 f6 e4 84 90 8e |cHj.X&..._v.....| 0000d6a0 71 af 68 c5 44 63 3f 43 f8 f4 b2 6a 51 b5 74 5b |q.h.Dc?C...jQ.t[| 0000d6b0 2f 3c c2 93 de 1a 4a d3 66 ec 25 be 51 59 35 0a |/<....J.f.%.QY5.| 0000d6c0 fc bf 10 10 af 49 c4 26 0e 7a 79 09 de 0f 14 64 |.....I.&.zy....d| 0000d6d0 07 e6 a7 ae 74 67 09 98 b2 7b a5 1e db 75 ed 85 |....tg...{...u..| 0000d6e0 f6 9f 7e b5 27 f7 70 f2 99 36 ab c6 3f af 8e a2 |..~.'.p..6..?...| 0000d6f0 62 cb 16 0c ca 67 0b 72 46 7c ae 1d dc d0 2d 01 |b....g.rF|....-.| 0000d700 04 01 19 14 00 00 00 00 00 02 02 7e 4d 6f 64 75 |...........~Modu| 0000d710 6c 65 20 73 69 67 6e 61 74 75 72 65 20 61 70 70 |le signature app| 0000d720 65 6e 64 65 64 7e 0a |ended~.| 0000d727
バイナリの最後のところに~Module signature appended~とあり、これが署名の最後を表しているマーカーです。アドレス0x0000d4d0からはFedora kernel signing keyが見えていて、ここがFedoraのカーネルビルド時につけた署名の先頭部分です。この範囲はELFのセクションでも何でもないところです。stripコマンドにかけると消えます。
ついでなので、このマーカーに挟まれた部分をシェルスクリプトで取り出してみようかなと思った結果が下です。c言語でやれば簡単なのは分かっているので、なんとなくシェルでやってみたと。 シェルスクリプトでバイナリを触るのはod(1)さえあればなんとかなるものですね。出力結果を加工するのにsedを使ってたりしますが(空白削るだけならtrでも良いけど)。。。
やってる内容としては、ファイルの最後の部分が~Module signature appended~になっているか調べて、マーカーが見つかったらその文字列が始まっているアドレスを16の倍数に切り下げて$(((${marker_start_offset} >> 4) << 4))16バイトごとに前に戻りつつFedora〜の場所を探してます。0xfffffff0でマスクしても良いんだけど、32/64bitの違いを気にするのも面倒だし、右シフトと左シフトでやったほうが楽かなーと。
#!/bin/bash if [ $# -ne 1 ]; then echo "Usage $0 [kernel module]" exit 1 fi kmodfile=$1 filesize=`stat -c %s ${kmodfile}` printf "file size is 0x%x\n" ${filesize} module_sign_marker="~Module signature appended~" module_sign_marker_len=`echo ${#module_sign_marker}` module_sign_fedora_key_marker="Fedora kernel signing key" module_sign_fedora_key_marker_stripped=`echo ${module_sign_fedora_key_marker} | sed 's/ //g'` module_sign_fedora_key_marker_len=${#module_sign_fedora_key_marker} printf "fedora len: 0x%x\n" $module_sign_fedora_key_marker_len function modsign_check_key() { strings ${kmodfile} | grep "${module_sign_marker}" 2>&1 >/dev/null if [ $? -ne 0 ]; then echo "Module not signed" return 1 fi marker_start_offset=$((${filesize} - ${module_sign_marker_len})) printf "marker_start_offset is 0x%x\n" ${marker_start_offset} check_start_offset=$(((${marker_start_offset} >> 4) << 4)) printf "check_start_offset is 0x%x\n" ${check_start_offset} fedora_key_start_addr=0 for ((fedora_key_start_addr=${check_start_offset}; fedora_key_start_addr >= 0; fedora_key_start_addr-=16)); do s=`od --width=64 -An -tc -j ${fedora_key_start_addr} -N ${module_sign_fedora_key_marker_len} ${kmodfile} | sed 's/\\n//g' | sed 's/ //g'` if [ "${s}" = "${module_sign_fedora_key_marker_stripped}" ]; then echo "found" break fi done printf "fedora_key_start_addr is 0x%x\n" ${fedora_key_start_addr} key_start_addr=$((${fedora_key_start_addr} + ${module_sign_fedora_key_marker_len})) printf "key_start_addr is 0x%x\n" ${key_start_addr} key_size=$((${marker_start_offset} - ${key_start_addr})); printf "key_size is 0x%x\n" ${key_size} od --width=1024 -An -txC -j ${key_start_addr} -N ${key_size} ${kmodfile} | sed 's/ //g' } modsign_check_key
できるPRO Red Hat Enterprise Linux 7 (できるPROシリーズ)
- 作者: 平初,できるシリーズ編集部
- 出版社/メーカー: インプレス
- 発売日: 2015/06/25
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る