pwn20-pwn22是关于.got节跟.got.plt节的。这3道题的问题描述全是一样的,全都是问.got跟.got.plt是否可写以及他们的地址是什么,然后根据这些信息来拼成flag。那么关于.got和.got.plt的内容非常复杂,这里呢我也不解释了,推荐一个牛逼的博主的文章,大家可以自行去了解一下这两个节。
聊聊Linux动态链接中的PLT和GOT(1)——何谓PLT与GOT
聊聊Linux动态链接中的PLT和GOT(2)——延迟重定位
聊聊Linux动态链接中的PLT和GOT(3)——公共GOT表项
Ok,本篇文章我们只针对如何获得flag啊,具体涉及到got表即plt表的知识大家看以上的那三篇文章就行了。
解题思路
首先呢,题目问.got与.got.plt节是否可写,那么如何知道他们是否可写呢?
其实呢?Linux的可执行文件都有各种保护机制,包括Stack canaries、No-eXecute、ASLR和PIE、FORTIFY_SOURCE以及RELRO。其中RELRO保护机制就是与.got、.got.plt节是否可写有关!
我们使用python的pwntools工具中的checksec命令就可以查看这些保护机制的信息。例如:
这里可以看到上面的各种保护机制信息,其中RELRO是我们本篇文章重点关注的。
RELRO(ReLocation Read-Only)机制的提出就是为了解决延迟绑定的安全问题,它最初于2004年由Redhat的工程师Jakub Jelinek实现,它将符号重定向表设置为只读,或者在程序启动时就解析并绑定所有动态符号,从而避免GOT上的地址被篡改。如今,RELOR有两种形式:
Partial RELRO:一些段(包括.dynamic、.got等)在初始化后将会被标记为只读。在Ubuntu16.04(GCC-5.4.0)上默认开启Partial RELRO。
Full RELRO:除了Partial RELRO,延迟绑定将被禁止,所有的导入符号将在开始时被解析,.gotPlt段会被完全初始化为目标函数的最终地址,并被mprotect标记为只读但其实.got.plt会直接被合并到.got,也就看不到这段了。另外link_map和_dl_runtime_resolve的地址也不会被装入。开启Full RELRO会对程序启动时的性能造成一定的影响,但也只有这样才能防止攻击者篡改GOT。
其实还应该多加一种形式,那就是No RELRO。
所以:
当RELRO为Partial RELRO时,表示.got不可写而.got.plt可写。
当RELRO为FullRELRO时,表示.got不可写.got.plt也不可写。
当RELRO为No RELRO时,表示.got与.got.plt都可写。
而使用readelf -S 命令可以查看节头表以查看各个节的信息,这里其中就包含了节的所在地址。
所以我们可以使用checksec命令来看.got与.got.plt是否可写,使用readelf -S 命令来查看.got与.got.plt的地址。
下面我们就开始肝题目吧!
pwn20
首先我们将pwn文件托到虚拟机然后加上可执行的权限。
接下俩我们就可以使用checksec命令来看RELRO的情况了。
chmod +x pwn
checksec pwn
RELRO为No RELRO代表.got与.got.plt都可写,那么flag前一部分就为:ctfshow{1_1_。
下面我们再来查看地址:
readelf -S pwn
这样我们就可以拼出flag的后一部分了:0x600f18_0x600f28}。
所以的总的flag就为:ctfshow{1_1_0x600f18_0x600f28}
pwn21
首先我们将pwn文件托到虚拟机然后加上可执行的权限。
接下俩我们就可以使用checksec命令来看RELRO的情况了。
chmod +x pwn
checksec pwn
RELRO为Partial RELRO代表.got不可写而.got.plt都可写,那么flag前一部分就为:ctfshow{0_1_。
下面我们再来查看地址:
readelf -S pwn
这样我们就可以拼出flag的后一部分了:0x600ff0_0x601000}。
所以的总的flag就为:ctfshow{0_1_0x600ff0_0x601000}
pwn22
首先我们将pwn文件托到虚拟机然后加上可执行的权限。
接下俩我们就可以使用checksec命令来看RELRO的情况了。
chmod +x pwn
checksec pwn
RELRO为Full RELRO代表.got和.got.plt都不可写,那么flag前一部分就为:ctfshow{0_0_。
下面我们再来查看地址:
readelf -S pwn
这样我们就可以拼出flag的后一部分了:0x600fc0}。
所以的总的flag就为:ctfshow{0_0_0x600fc0}