提交ctfshow{【.got表与.got.plt是否可写(可写为1,不可写为0)】,【.got的地址】,【.got.plt的地址】
前置基础知识:
.got 和 .got.plt 是 ELF(Executable and Linkable Format,可执行和可链接格式)二进制文件中的两个重要部分,用于实现动态链接和延迟绑定(lazy binding)。
.got 表(Global Offset Table,全局偏移表):
.got 表是一个在程序加载时由动态链接器填充的表,包含了程序中所有需要在运行时动态解析的全局变量和函数的地址。这些地址最初是未知的,直到程序在内存中加载并开始执行时才会被解析和填充。当程序第一次执行到一个全局变量或者函数时,动态链接器会通过查找该符号的地址并将其写入 .got 表中,这样下次再次访问这个符号时就不需要再次查找。
.got.plt 表(Procedure Linkage Table,过程链接表):
.got.plt 表是在程序中用于实现延迟绑定的一种数据结构,用于处理程序中对动态链接库函数的调用。当程序第一次调用一个动态链接库中的函数时,其对应的入口地址会被写入到 .got.plt 表中。然后,动态链接器会跳转到 PLT 中的相应入口,执行一系列指令,最终将函数的实际地址写入 .got.plt 表中,并跳转到该地址执行函数。下次再调用这个函数时,程序会直接跳转到 .got.plt 表中存储的函数地址,而不需要再次执行 PLT 中的指令序列。
加上可执行权限后直接执行程序:
提示:What is RELRO protection ?
我们需要先知道什么是 RELRO 保护:
RELRO(RELocation Read-Only)保护是一种针对二进制可执行文件的安全性措施,用于防止针对程序中全局偏移表(GOT)和程序加载时动态链接器(LD)的攻击,确保全局偏移表(GOT)和过程链接表(PLT)在程序加载后被设为只读,从而使得攻击者无法修改这些表以执行恶意代码注入或覆盖函数指针等攻击。
RELRO 的几种常见类型:
1、NO RELRO:这种状态下 GOT 和 PLT 都是可写的。
.got 与 .got.plt 都可写。
2、Partial RELRO:将全局偏移表(GOT)的非空项设为只读,而对于空项则保持可写。
.got 不可写而 .got.plt 可写。
3、Full RELRO:在程序加载后将全局偏移表(GOT)和过程链接表(PLT)的所有项都设置为只读,即使这些项为空。任何对这些表的修改都会导致程序异常终止。
.got 与 .got.plt 都不可写。
下载题目附件检查:
64 位程序,开了 NX 保护,RELRO 保护未开,则 .got 表与 .got.plt 表都可写。
因此 ctfshow{1_1_
readelf -S pwn
readelf 是一个用于显示 ELF 格式文件信息的工具,而 -S 选项用于显示 ELF (Executable and Linkable Format,可执行和可链接格式)文件中的节表(section headers)信息,节表包含了关于 ELF 文件中每个节的详细信息,例如节的名称、偏移、大小、对齐方式等。
找到这两个表的地址:0x600f18 和 0x600f28
因此 flag:ctfshow{1_1_0x600f18_0x600f28}
在 ida 里面也可以看到这两个表的:
可以看出 .got 和 .got.plt 这两个段在内存中的地址分别为 0x600F18 和 0x600F28。这两个段的内存地址是由汇编语言中的 org 指令指定的,分别为 0x600F18 和 0x600F28。
测试 .got 和 .got.plt 是否都可写:
验证成功,都是可写的