Pwn专题(4)-安全机制RELRO

下面的代码通过命令行读入一个地址,然后将十六进制常量0x41414141写到地址内存里。这是缓冲区溢出的简化形式,对篡改GOT的行为进行简单的模拟。
//gcc -g -W -no-pie -z norelro relro.c -o relro_norelro 

#include <stdio.h> 

#include <stdlib.h> 

int main(int argc,char *argv[]) { 

size_t *p = (size_t *) strtol(argv[1], NULL, 16); 

p[0] = 0x41414141;

 printf("RELRO: %x\n",(unsigned int)*p);

 return 0; 

}
首先来看第一种关闭RELRO的情况。通过checksec查看程序开启的保护。

使用”-R“参数查看文件的动态重定位入口,通过下面的信息可以发现两种不容的符号都在一页里面。其中R_X86_64_GLOB_DAT是将符号写到OFFSET的位置;R_X86_64_JUMP_SLOT用于延迟绑定,OFFSET保存的是符号对应PLT位置。当这两个符号位于同一页的时候说明他们的权限有可能是相同的。

使用“-S”参数查看ELF文件的section信息。

readelf -S relro_norelro

使用“-l”参数查看ELF文件头(segment)信息。.got、.got.plt都是有读写权限。

测试写.got段看程序是否运行成功。

测试写.got.plt段看程序是否运行成功。

第二种开启Partial RELRO

使用”gcc -g -W -no-pie -z lazy relro.c -o relro_lazy”来对代码进行编译。

再来查看文件的动态重定位入口发现两种符号已经不在同一页上,说明他们的权限可能不同。

使用“-S”参数查看ELF文件的section信息。

readelf -S relro_lazy

使用“-l”参数查看ELF文件头(segment)信息。程序头中多了一个GUN_RELRO,.dynamic、.got拥有只读权限。

测试写.got段看程序是否运行成功。

测试写.got.plt段看程序是否运行成功。

第三种开启Full RELRO。

使用“gcc -g -W -no-pie -z now relro.c -o relro_now”对代码进行编译。

查看文件的动态重定位入口,发现这两个符号又位于同一页。

查看ELF文件头信息。发现所有的符号都放在.got段上了,并且只剩下了读取的权限。

测试写.got段看程序是否运行成功。