阅读linux的源码时,看到在task_struct
中使用了randomized_struct_fields_start
这个宏,也就是使用了结构混淆这一特性。原文可见邮件列表。
大意就是,一个struct的内部数据存储是按照声明顺序的,因此黑客程序可以很容易得计算出一个关键值,比如跳转函数地址在内核一些结构体中的偏移。修改该偏移的值以后,就可以轻松控制内核执行自己的代码(内核态)。
所以我们可以使用gcc的一个plugin所提供的特性(插件来自于Grsecurity),进行结构体的混淆。在编译的时候,结构体的数据存放不会按照声明顺序,而是根据函数名以及随机种子,打乱存储顺序。
假设:
struct critical_struct {
int id;
void (* fn) (void *data);
void *data;
...
};
有这么一段内核源码,如果骇客程序获得了对应数据段的写权限,那么他可以($STRUCT_OFFSET + 0x04),也就是fn
的函数地址修改为自己的代码地址,进而获得内核态的执行权限。如果混淆以后,就为这种侵入过程制造了难度。