Created
September 25, 2020 12:59
-
-
Save jandryuk/62f18d802eb705f5ecf4ecd866318f3a to your computer and use it in GitHub Desktop.
mod-sig-chk.sh is a script to check the kernel modules signatures against a cert. mod-sig-chk.py is a helper, called by mod-sig-chk.sh, to extract the actual signature data for verification. mod-sig-chk.py should be in the user's home (~/) directory.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import struct | |
import sys | |
magic = "~Module signature appended~\n" | |
magic_len = len(magic) | |
PKEY_ID_PKCS7 = 2 | |
mod_name = sys.argv[1] | |
f = open(mod_name, 'rb') | |
mod = f.read() | |
f.close() | |
mod_len = len(mod) | |
magic_idx = mod.find(magic) | |
if magic_idx == -1: | |
print "Module is not signed?" | |
sys.exit(1) | |
if mod[-magic_len:] != magic: | |
print "Module magic not at end of file?" | |
sys.exit(1) | |
mod_sig_len = 12 | |
mod_sig_idx = magic_idx - mod_sig_len | |
module_signature = struct.unpack(">BBBBB3BL", mod[mod_sig_idx:magic_idx]) | |
for i in [0,1,3,4,5,6,7]: | |
if module_signature[i] != 0: | |
print "module_signature[i] doesn't match %d != 0" % module_signature[i] | |
if module_signature[2] != PKEY_ID_PKCS7: | |
print "module_signature[2] doesn't match %d != PKEY_ID_PKCS7(2)" % module_signature[2] | |
sig_len = module_signature[8] | |
sig_idx = mod_sig_idx - sig_len | |
#print "%06x %06x %06x %06x %s" % ( sig_idx, mod_sig_idx, magic_idx, mod_len, mod_name) | |
#sig = mod[sig_idx:sig_idx+sig_len] | |
f = open(mod_name+".sigdata", "wb") | |
f.write(mod[sig_idx:sig_idx+sig_len]) | |
f.close() | |
#data = mod[:sig_idx] | |
f = open(mod_name+".data", "wb") | |
f.write(mod[:sig_idx]) | |
f.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -ue | |
# To check all kernel modules in a directory: | |
# find .../rootfs -name "*.ko" | xargs -n1 $0 .../$cert | |
verbose= | |
if [ "${1:-}" = "-v" ]; then | |
verbose=1 | |
shift | |
fi | |
cert=${1:-} | |
mod=${2:-} | |
if [ ! -r "$cert" ] || [ ! -r "$mod" ] ; then | |
echo "Usage: $0 signing_key module.ko" | |
echo " maybe \`find .../rootfs/lib/modules -name '*.ko' | xargs -n1 $0 .../\$cert\`" | |
echo " to check all kernel modules in an image." | |
exit 1 | |
fi | |
~/mod-sig-chk.py "${mod}" | |
data="${mod}.data" | |
sigdata="${mod}.sigdata" | |
keyform=DER | |
grep -q -- "-----BEGIN CERTIFICATE-----" $cert && keyform=PEM | |
#openssl asn1parse -inform der -in ${sigdata} | |
hash=$( openssl asn1parse -inform der -in ${sigdata} | tail -n 1 ) | |
hash=$( echo ${hash} | awk -F prim: '{ print $1 }' ) | |
offset=$( echo ${hash} | cut -d: -f1 ) | |
hdr_len=$( echo ${hash} | sed -e 's/.*hl=//' -e 's/ .*//' ) | |
sig_size=$( echo ${hash} | sed -e 's/.*l=//' -e 's/ //g' ) | |
sig_hash=$( dd if=${sigdata} bs=1 skip=$(( offset + hdr_len )) count=${sig_size} status=none | | |
openssl rsautl -verify -certin -keyform $keyform -inkey ${cert} | | |
openssl asn1parse -inform der | | |
tail -n 1 | | |
sed -e 's/.*HEX DUMP.://' | | |
tr 'A-F' 'a-f' ) | |
data_hash=$( sha384sum ${data} | awk '{ print $1 }' ) | |
if [ "${sig_hash}" != "${data_hash}" ] ; then | |
echo "hash mismatch - $( basename $mod )" | |
echo "${sig_hash} signature value" | |
echo "${data_hash} data value" | |
else | |
[ -n "$verbose" ] && echo "${sig_hash} hashes match" | |
fi | |
rm ${data} | |
rm ${sigdata} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment