内存中的Linux内核代码检查sha256 sum
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存中的Linux内核代码检查sha256 sum相关的知识,希望对你有一定的参考价值。
有没有办法在内存中找到加载的内核代码?我的意思是引导加载程序加载内核并执行它。内核提取自己并开始初始化硬件并运行init。据我所知,内核是从(b)zImage从磁盘保存和加载的。这个未更改的代码我想在系统内存中查找并检查它。
我有以下增强功能:
创建加载的内核代码的sha256哈希值,并将其与定义的值进行比较,以审计系统的安全性。因此,我加载了一个模块,它试图在内存中找到内核代码并计算出sha256的总和。
我试着在内存中找到内核代码:
static struct resource *adhoc_next_resource(struct resource *p, bool sibling_only)
{
if (sibling_only)
return p->sibling;
if (p->child)
return p->child;
while (!p->sibling && p->parent)
p = p->parent;
return p->sibling;
}
static struct resource *get_kernel_code (void) {
struct resource *kern_code = &iomem_resource;
while (kern_code && strcmp(kern_code->name ? kern_code->name : "","Kernel code") != 0) {
kern_code = adhoc_next_resource(kern_code, false);
}
return kern_code;
}
int init_module(void)
{
void *start,*end;
size_t length;
SHA256_CTX sha256;
u32 *hash;
struct resource *kern_code;
kern_code = get_kernel_code();
if ( IS_ERR(kern_code) )
return -EINVAL;
start = (void*)phys_to_virt(kern_code->start);
end = (void*)phys_to_virt(kern_code->end);
length = kern_code->end - kern_code->start;
printk("%s[%s]:%s address: %0*llx-%0*llx
", MODULE_NAME, __FUNCTION__, kern_code->name ? kern_code->name : "", 4, start, 4, end );
printk("%s[%s]: length: %lu
", MODULE_NAME, __FUNCTION__, length);
printk ( KERN_INFO "%s[%s]: Init sha256
", MODULE_NAME, __FUNCTION__ );
sha256_init(&sha256);
printk ( KERN_INFO "%s[%s]: Give kernel code to sha256
", MODULE_NAME, __FUNCTION__ );
sha256_update ( &sha256, start, length );
hash = kmalloc ( 4 * sizeof(u32), GFP_KERNEL );
printk ( KERN_INFO "%s[%s]: Finalize sha256
", MODULE_NAME, __FUNCTION__ );
sha256_final ( &sha256, (BYTE*)hash );
printk ( KERN_INFO "%s[%s]: Hash value of kernel code: %x - %x - %x - %x
", MODULE_NAME, __FUNCTION__, hash[0], hash[1], hash[2], hash[3] );
kfree(hash);
return 0;
}
但是,每次重启都会得到不同的sha256总和。
- 请解释一下会发生什么?内核代码内存中的某些内容发生了变化。但它有什么用呢?
- 这个概念会起作用吗?或者不是每次都在内存中加载相同的代码。
答案
我自己找到了这个问题的答案:
- 我对内核的内存位置等进行了一些研究。我发现在运行时,内核“。text”部分(提取的bzImage)没有存储在iomem_resource列表中。我已经检查了“内核代码”资源的地址范围(参见我之前发布的代码)并发现大多数位都是0.只有在开头和结尾都有一些代码。但这不是“内核代码”我没有找到答案黑客是这个“内核代码”部分。也许它必须是内核映像的“.text”部分,但不是我的系统(ARM 32bit和yocto-linux 4.10.17)。
- 从Yasushi发布的KASLR功能(info here)不是ARM 32bit arichtecture的问题。我在内核中发现,在这种类型的系统上没有启用此功能。但这是一个非常有趣的功能。
- 要获取“.text”部分的内核地址,我现在使用kallsysm功能。这是所有地址和导出变量的大列表。定义开始和结束的变量有两个。我使用以下代码: start =(void *)kallsyms_lookup_name(“_ stext”); end =(void *)kallsyms_lookup_name(“_ etext”);
注意:请注意虚拟内存与物理内存位置。 Kallsyms输出是虚拟内存位置。 (如果我错了,请纠正我)
最后:对于相同的内核代码,我为每次启动获得相同的校验和,我可以继续完成我的审计模块:-)。
以上是关于内存中的Linux内核代码检查sha256 sum的主要内容,如果未能解决你的问题,请参考以下文章