使用sha256 sum在内存中检查Linux内核代码 [英] Linux Kernel code in memory check with sha256 sum

查看:121
本文介绍了使用sha256 sum在内存中检查Linux内核代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以找到内存中已加载的内核代码?我的意思是引导程序会加载内核并执行它.内核提取自身并开始初始化硬件并运行init.据我了解,内核是从磁盘的(b)zImage中保存和加载的.我想在系统内存中找到并检查此不变的代码.

Is there a way of finding the loaded kernel code inside the memory? I mean the bootloader loads the kernel and executes it. The kernel extracts itself and start to initialize the hardware and runs init. As I understand the kernel is saved and loaded from the (b)zImage from disk. This unchanged code I want to find inside the memory of the system and check it.

我具有以下增强功能:

I have the following enhancement:

创建已加载内核代码的sha256哈希并将其与定义的值进行比较,以审核系统的安全性.因此,我加载了一个模块,该模块尝试在内存中查找内核代码并从中计算出sha256和.

Create a sha256 hash of the loaded kernel code and compare it to a defined value to audit the security of the system. Therefore I load a module which tries to find the kernel code inside the memory and compute the sha256 sum out of that.

我试图像这样在内存中找到内核代码:

I tried to find the kernel code in memory like that:

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 \n", MODULE_NAME, __FUNCTION__, kern_code->name ? kern_code->name : "", 4, start, 4, end );

    printk("%s[%s]: length: %lu \n", MODULE_NAME, __FUNCTION__, length);


    printk ( KERN_INFO "%s[%s]: Init sha256\n", MODULE_NAME, __FUNCTION__ );
    sha256_init(&sha256);

    printk ( KERN_INFO "%s[%s]: Give kernel code to sha256\n", MODULE_NAME, __FUNCTION__ );
    sha256_update ( &sha256, start, length );

    hash = kmalloc ( 4 * sizeof(u32), GFP_KERNEL );

    printk ( KERN_INFO "%s[%s]: Finalize sha256\n", MODULE_NAME, __FUNCTION__ );
    sha256_final ( &sha256, (BYTE*)hash );

    printk ( KERN_INFO "%s[%s]: Hash value of kernel code: %x - %x - %x - %x \n", MODULE_NAME, __FUNCTION__, hash[0], hash[1], hash[2], hash[3] );

    kfree(hash);

    return 0;
}

但是,每次重新启动时,我都会得到不同的sha256总和.

But, I get every time a reboot was done a different sha256 sum.

  1. 请解释会发生什么?内核代码内存中的某些内容已更改.但是那会是什么呢?
  2. 这个概念行得通吗?还是不是每次都在内存中加载了相同的代码.

推荐答案

我自己找到了此问题的答案:

I have found by myself an answer for this problem:

  1. 我已经对内核的内存位置等进行了更多研究.我发现在运行时,内核".text"部分(提取的bzImage)未存储在iomem_resource列表中.我检查了内核代码"资源中的地址范围(请参阅我以前发布的代码),发现大多数位都是0.仅在开头和结尾处都有一些代码.但这不是内核代码",我没有找到答案是此内核代码"部分的内容.也许它必须是内核映像的".text"部分,而不是在我的系统上(ARM 32bit& yocto-linux 4.10.17).

  1. I have made some more research about memory location of the kernel and so on. I found that during runtime the kernel ".text" section (extracted bzImage) is not stored in the iomem_resource list. I have inspected the address range from the "kernel code" resource (see my previous posted code) and found that most of the bits are 0. Only very at the beginning and at the end there is some code. But this is not "kernel code" I didn't find an answer what the hack is this "kernel code" section. Maybe it has to be the ".text" section of the Kernel Image, but not on my system (ARM 32bit & yocto-linux 4.10.17 ).

从Yasushi发布的KASLR功能(此处的信息)不是问题所在ARM 32位丰富技术.我在内核内部发现,该类型的系统未启用此功能.但这是一个非常有趣的功能.

The KASLR feature (info here) posted from Yasushi is not the problem for ARM 32bit arichtecture. I found inside the kernel defines that this feature is not enabled on this type of system. But it is a very interesting feature.

要获取".text"部分的内核地址,我现在使用kallsysm功能.这是所有地址和导出变量的一个大列表.有两个变量定义开始和结束.我使用以下代码:

To get the kernel address of the ".text" section I use now the kallsysm functionality. This is a big list of all addresses and exported variables. There are two variables who define the start and end. I use the following code:


    start = (void*)kallsyms_lookup_name("_stext");
    end = (void*)kallsyms_lookup_name("_etext");

注意:请谨慎使用虚拟内存和物理内存位置. Kallsysm输出是虚拟内存位置. (如果我错了,请纠正我)

Note: Be carefull with virtual memory vs. physical memory location. Kallsysm output is virtual memory location. (Please correct me if I am wrong)

最后::对于相同的内核代码,每次引导我都会得到相同的校验和,然后我就可以继续完成我的审核模块了:-).

Finally: I get the same checksum for each boot for the same kernel code and I can go on finishing my audit module :-).

这篇关于使用sha256 sum在内存中检查Linux内核代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆