Hack Zone Tunisia 2018 参戦

この大会は2018/4/15 5:00(JST)~2018/4/15 17:00(JST)に開催されました。
今回もチームで参戦。結果は1708点で63チーム中11位でした。
今回は自分が得点した問題は1問もありませんでした。
パッと見た感じ、簡単には解ける問題もなかったので、他の大会を優先。
Writeupで復習したいと思います。

HITB-XCTF GSEC CTF 2018 Quals Writeup

この大会は2018/4/11 23:00(JST)~2018/4/13 23:00(JST)に開催されました。
今回もチームで参戦。結果は692点で344チーム中81位でした。
自分で解けた問題は参加表明問題だけでしたが、Writeupとして書いておきます。

IRC checkin (Misc)

freenodeで #hitbxctf2018 チャネルに入る。

22:58 *topic : HITB-XCTF 2018 GSEC Online Qualifications | https://conference.hitb.org/hitbsecconf2018ams/hitb-xctf-gsec-qualifications/. Flag for IRC checkin: HITBXCTF{W3lcome_To_HITBXCTF_2018_Online_Qualifications}
HITBXCTF{W3lcome_To_HITBXCTF_2018_Online_Qualifications}

UIUCTF 2018 Writeup

この大会は2018/4/7 9:00(JST)~2018/4/9 9:00(JST)に開催されました。
今回もチームで参戦。結果は602点で431チーム中19位でした。
自分で解けた問題をWriteupとして書いておきます。

We Read the Rules (other 0)

ルール記述の下にフラグが書いてある。

flag{0kay_s0unds_g00d_2_m3}

irc (other 1)

freenodeで#uiuctfチャネルに入る。

10:13 *topic :  Welcome to UIUCTF | CTF live at https://uiuc.tf/ flag{sorry_for_not_posting_link_to_irc_sooner}
flag{sorry_for_not_posting_link_to_irc_sooner}

ROT180 (Misc 1)

上下反対(180度回転)にするとフラグになっている。

flag{at_least_its_not_recon}

Hastad (Crypto 200)

Hastad's broadcast attackで攻撃できそう。
eは3なので、対応するnとcのペアが3つ必要。
ペアが分からず、cが15個もあるので、総当たりで攻撃する。

import functools
import itertools

def chinese_remainder(n, a):
    sum = 0
    prod = functools.reduce(lambda a, b: a*b, n)
    for n_i, a_i in zip(n, a):
        p = prod // n_i
        sum += a_i * mul_inv(p, n_i) * p
    return sum % prod
 
def mul_inv(a, b):
    b0 = b
    x0, x1 = 0, 1
    if b == 1: return 1
    while a > 1:
        q = a // b
        a, b = b, a%b
        x0, x1 = x1 - q * x0, x0
    if x1 < 0: x1 += b0
    return x1

def inv_pow(c, e):
    low = -1
    high = c+1
    while low + 1 < high:
        m = (low + high) // 2
        p = pow(m, e)
        if p < c:
            low = m
        else:
            high = m
    m = high
    if pow(m, e) != c:
        return 0
    return m

N1 = 0xbc4ec2b74d85fb57ec07f538b59987c1150042ef76178b7af6dc09ca139dc8570226fe0317f3b73e8f98de38eb03a986496431d8526be4e65d47d86130a4370348b8a8dbba80d922f4dbac31b95f1028baac1ba8f8cab00d6e362c761da0dece81a700b92a5c1d79ec50451b3147805123e92f424d422d688ab020280d35384f
N2 = 0xd83a59170679b7d8b2199e98656717c515e06e44e65b5f7b687e4fec6d21a7e6e75ecbcf208202f210ef8e29a7ad44ab72914b1f35d502f6d7f657e5512d4b989773515cbc046ca3ffef37f3090548ac1086d96c96fe7edb9bdeb58ba635fa1582da4a85357105293139c8152d70c2ec5ec667bb91197c353cd6aafac73476df
N3 = 0xc39ab84fbf6709048427c05dbd303f0ba2f90ecdd51a809f1d8da9df0546a771e982a6bccb299c4bf12d1b0b11df88b0627563d726bb70c5121cb5722c75e35b54e6d43d09443738fe3ac8e5a8bb74b1667ddf6592359d9fc65a05a32b98a50c52f1339ed8b5fab5616d52d81a11579a83fc33e069c4d9cfb93b24d752937ced
N = [N1, N2, N3]

e = 3

c = [
0x10652cdfaa86ddbee1409ac7ac327a0c848081ee6e3b110867085f1074755785b0a5a6a2343b791695c3e91fdb370d5b26be3b6d2fc449c7788bbb1ab67ddc361b4115010618e39c883449b757fc1624369b440236ee65,
0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965,
0x10652cdfaa8ab16290cf92bacf31b23d6a0ea95c2ebd6eb8afe4f038d852a7f17e98f965f299b4d00126611d403c5208a145157ed1d71079fc558eaa888e993360fac35c7a816ad183190867b1b7580a2677cd6871aa65,
0x10652cdfaa86ddbee1409ac7ac327a0c848081ee6e3b110867085f1074755785b0a5a6a2343b791695c3e91fdb370d5b26be3b6d2fc449c7788bbb1ab67ddc361b4115010618e39c883449b757fc1624369b440236ee65,
0x10652cdfaa875a9ac01e472ea5896c1d460410508b9a7c723b5ba904fb5b64d68a1e96254ba04b08c92d51f1fe6c3d6bb426e1ee8c61c8a6ff1eeab9e07f51d8057f2f0c54b27c7006539f7148484ff26a02e4cb1d3165,
0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965,
0x10652cdfaa875a9ac01e472ea5896c1d460410508b9a7c723b5ba904fb5b64d68a1e96254ba04b08c92d51f1fe6c3d6bb426e1ee8c61c8a6ff1eeab9e07f51d8057f2f0c54b27c7006539f7148484ff26a02e4cb1d3165,
0x10652cdfaa8210601d22f4a15aa380233420f9ee9a276d3ac8e05cfc4f6f515f78331e8e74484e8533221e88f78671dd08622e78233e458978a35036680d1c5caaba2fa3bce3b914ad48501a276d6a88adc16db282e065,
0x10652cdfaa8ab16290cf92bacf31b23d6a0ea95c2ebd6eb8afe4f038d852a7f17e98f965f299b4d00126611d403c5208a145157ed1d71079fc558eaa888e993360fac35c7a816ad183190867b1b7580a2677cd6871aa65,
0x10652cdfaa8c2701b8bb7c11fc3218cc2d97cd4707f6de55637bc093f474d231b4d4fe8635261b8e4f772d0e51a25f8e713777a137be6f04e0d28ddd6ec0b852aaf357d33e08aed23e034fcd1ced38542fbeb5aa0eee65,
0x10652cdfaa8210601d22f4a15aa380233420f9ee9a276d3ac8e05cfc4f6f515f78331e8e74484e8533221e88f78671dd08622e78233e458978a35036680d1c5caaba2fa3bce3b914ad48501a276d6a88adc16db282e065,
0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965,
0x10652cdfaa8ab162128a955a58d3b780f2656800796eb70c345c56d7b8523d614ef4ca920471f56493c83ca48500033a0c0b31988ca6e66a76e0ed559b38616688941558b127260cdf70261822929efa0aa6b6d79d1665,
0x10652cdfaa8ab162128a955a58d3b780f2656800796eb70c345c56d7b8523d614ef4ca920471f56493c83ca48500033a0c0b31988ca6e66a76e0ed559b38616688941558b127260cdf70261822929efa0aa6b6d79d1665,
0x10652cdfaa8c2701b8bb7c11fc3218cc2d97cd4707f6de55637bc093f474d231b4d4fe8635261b8e4f772d0e51a25f8e713777a137be6f04e0d28ddd6ec0b852aaf357d33e08aed23e034fcd1ced38542fbeb5aa0eee65]

i = 0
for elm in itertools.permutations(c, 3):
    error = False
    C = [elm[0], elm[1], elm[2]]
    a = chinese_remainder(N, C)
    for n, c in zip(N, C):
        if a % n != c:
            error = True
            break
    if error == False:
        m = inv_pow(a, e)
        if m != 0:
            flag = ('%x' % m).decode('hex')
            print flag
            break
flag{wh00ps_srry_4_br0adcast}

INS'hAck 2018 参戦

この大会は2018/4/6 1:30(JST)~2018/4/9 1:30(JST)に開催されました。
今回もチームで参戦。結果は973点で553チーム中32位でした。
今回は自分が得点した問題は1問もありませんでした。
暗号の問題は1問は解きたかったので、残念です。

Byte Bandits CTF 2018 Writeup

この大会は2018/4/7 16:30(JST)~2018/4/8 16:30(JST)に開催されました。
今回もチームで参戦。結果は1051点で174チーム中9位でした。
自分で解けた問題は参加表明問題だけでしたが、Writeupとして書いておきます。

Greetings (misc 1)

freenodeで#BBCTFチェネルに入る。

06:33 *topic : Welcome to ByteBandits CTF https://ctf.euristica.in https://twitter.com/BanditsByte  flag{W3lc0me_t0_BBCTF_H4ve_a_nic3_5taY}
flag{W3lc0me_t0_BBCTF_H4ve_a_nic3_5taY}

Sunshine CTF 2018 Writeup

この大会は2018/4/6 5:00(JST)~2018/4/8 5:00(JST)に開催されました。
今回もチームで参戦。結果は1951点で780チーム中23位でした。
自分で解けた問題をWriteupとして書いておきます。

Welcome (Forensics 1)

問題にフラグが書いてある。

sun{take_this_free_FLAG}

My Secret Stash (Forensics 100)

gitのファイル群が添付されている。

$ cd .git
$ xxd -g 1 index
0000000: 44 49 52 43 00 00 00 02 00 00 00 01 5a ab 13 05  DIRC........Z...
0000010: 2f ad 33 86 5a ab 13 05 2f 55 fc 4e 01 00 00 04  /.3.Z.../U.N....
0000020: 00 5d 74 3d 00 00 81 a4 00 00 01 f5 00 00 00 14  .]t=............
0000030: 00 00 01 3c 9f ee ea b8 2f 7a fe 27 eb 0f 67 21  ...<..../z.'..g!
0000040: 2f 95 2d c8 6c 23 03 e9 00 07 73 65 63 72 65 74  /.-.l#....secret
0000050: 73 00 00 00 54 52 45 45 00 00 00 19 00 31 20 30  s...TREE.....1 0
0000060: 0a ce 69 c6 ab c7 c9 9b 63 50 5d f3 81 22 77 d6  ..i.....cP].."w.
0000070: 9b a4 67 4b 9d 8b 25 e0 4f a8 48 6f a2 6c c8 27  ..gK..%.O.Ho.l.'
0000080: 28 4e 8a 8f b8 2a 75 67 55                       (N...*ugU

$ python -c 'import zlib; print zlib.decompress(open("objects/9f/eeeab82f7afe27eb0f67212f952dc86c2303e9").read())'
blob 316I'm so very sorry, you will not find my secrets in here. There was a time at which I wanted to share my secrets with someone, but that was long ago and I don't trust anyone anymore. I want to keep all of my secrets to myself for now on! Good luck trying to find them, there's nothing to find. hehehehehehehehe!!!!!!

$ cat logs/refs/heads/master
0000000000000000000000000000000000000000 7e2927361b7e4101e07fc5a475bb244622a275e3 Carlos Staszeski <cstaszeski@gmail.com> 1521160193 -0400	commit (initial): vegan!
7e2927361b7e4101e07fc5a475bb244622a275e3 92fb7e7ebbc65d04ac311c3f1d4e496cd867e94d Carlos Staszeski <cstaszeski@gmail.com> 1521160586 -0400	commit: is
92fb7e7ebbc65d04ac311c3f1d4e496cd867e94d 3fe304a91a3049d9589e379b843f4dca9c47aafc Carlos Staszeski <cstaszeski@gmail.com> 1521160985 -0400	commit: Bobby

$ python -c 'import zlib; print zlib.decompress(open("objects/7e/2927361b7e4101e07fc5a475bb244622a275e3").read())'
commit 185tree 74967e81c7d6b83bb2647abc6890a3adfae0e96a
author Carlos Staszeski <cstaszeski@gmail.com> 1521160193 -0400
committer Carlos Staszeski <cstaszeski@gmail.com> 1521160193 -0400

vegan!

$ python -c 'import zlib; print zlib.decompress(open("objects/74/967e81c7d6b83bb2647abc6890a3adfae0e96a").read())' | xxd -g 1
0000000: 74 72 65 65 20 33 35 00 31 30 30 36 34 34 20 73  tree 35.100644 s
0000010: 65 63 72 65 74 73 00 8a de a5 38 cd 0f d8 27 09  ecrets....8...'.
0000020: 09 4b 9c 77 2d c3 a2 15 76 d4 d3 0a              .K.w-...v...

$ python -c 'import zlib; print zlib.decompress(open("objects/8a/dea538cd0fd82709094b9c772dc3a21576d4d3").read())'
blob 225So, you've discovered how to travel back in time did you? Well that's not going to help you much here, you see, my stash is so well hidden you will never ever ever find it! hahahahahahahahhahahahahahahahahahahah!!!!!!!!!!!!!

$ python -c 'import zlib; print zlib.decompress(open("objects/92/fb7e7ebbc65d04ac311c3f1d4e496cd867e94d").read())'
commit 229tree ed91e6d10fdb88d4a9e2f4471e7b60170ba70a37
parent 7e2927361b7e4101e07fc5a475bb244622a275e3
author Carlos Staszeski <cstaszeski@gmail.com> 1521160586 -0400
committer Carlos Staszeski <cstaszeski@gmail.com> 1521160586 -0400

is

$ python -c 'import zlib; print zlib.decompress(open("objects/ed/91e6d10fdb88d4a9e2f4471e7b60170ba70a37").read())' | xxd -g 1
0000000: 74 72 65 65 20 33 35 00 31 30 30 36 34 34 20 73  tree 35.100644 s
0000010: 65 63 72 65 74 73 00 94 7f 94 13 31 a9 eb 2d 90  ecrets.....1..-.
0000020: 87 05 45 34 89 cd 56 e0 61 7d a5 0a              ..E4..V.a}..

$ python -c 'import zlib; print zlib.decompress(open("objects/94/7f941331a9eb2d908705453489cd56e0617da5").read())'
blob 304I feel like we are becoming good friends you and I. Yes. I even considered letting you in on one of my secrets just now, but I didn't want to risk it falling into the wrong hands. So instead I stashed it away and destroyed it so that no one would ever be able to recover my secrets! muahahahahahah!!!!!!

$ python -c 'import zlib; print zlib.decompress(open("objects/3f/e304a91a3049d9589e379b843f4dca9c47aafc").read())'
commit 232tree ce69c6abc7c99b63505df3812277d69ba4674b9d
parent 92fb7e7ebbc65d04ac311c3f1d4e496cd867e94d
author Carlos Staszeski <cstaszeski@gmail.com> 1521160985 -0400
committer Carlos Staszeski <cstaszeski@gmail.com> 1521160985 -0400

Bobby

$ python -c 'import zlib; print zlib.decompress(open("objects/ce/69c6abc7c99b63505df3812277d69ba4674b9d").read())' | xxd -g 1
0000000: 74 72 65 65 20 33 35 00 31 30 30 36 34 34 20 73  tree 35.100644 s
0000010: 65 63 72 65 74 73 00 9f ee ea b8 2f 7a fe 27 eb  ecrets...../z.'.
0000020: 0f 67 21 2f 95 2d c8 6c 23 03 e9 0a              .g!/.-.l#...

$ python -c 'import zlib; print zlib.decompress(open("objects/9f/eeeab82f7afe27eb0f67212f952dc86c2303e9").read())'
blob 316I'm so very sorry, you will not find my secrets in here. There was a time at which I wanted to share my secrets with someone, but that was long ago and I don't trust anyone anymore. I want to keep all of my secrets to myself for now on! Good luck trying to find them, there's nothing to find. hehehehehehehehe!!!!!!

フラグが見つからない。手あたり次第調べる。

$ python -c 'import zlib; print zlib.decompress(open("objects/7b/82ac03c49c0b55a4a8b8ffb3c04c5fe565fba6").read())'
commit 258tree 74967e81c7d6b83bb2647abc6890a3adfae0e96a
parent 7e2927361b7e4101e07fc5a475bb244622a275e3
author Carlos Staszeski <cstaszeski@gmail.com> 1521160299 -0400
committer Carlos Staszeski <cstaszeski@gmail.com> 1521160299 -0400

index on master: 7e29273 vegan!

$ python -c 'import zlib; print zlib.decompress(open("objects/14/a5c7088e7638abb2232c8cac1c7dd4687819f0").read())'
commit 304tree c9936edd0f107fc91fdaa876def0dc960b000760
parent 7e2927361b7e4101e07fc5a475bb244622a275e3
parent 7b82ac03c49c0b55a4a8b8ffb3c04c5fe565fba6
author Carlos Staszeski <cstaszeski@gmail.com> 1521160299 -0400
committer Carlos Staszeski <cstaszeski@gmail.com> 1521160299 -0400

WIP on master: 7e29273 vegan!

$ python -c 'import zlib; print zlib.decompress(open("objects/c9/936edd0f107fc91fdaa876def0dc960b000760").read())' | xxd -g 1
0000000: 74 72 65 65 20 33 35 00 31 30 30 36 34 34 20 73  tree 35.100644 s
0000010: 65 63 72 65 74 73 00 bd 12 73 6e 7c 80 5c 83 49  ecrets...sn|.\.I
0000020: 4a 71 c3 66 a7 f8 85 0e e7 a3 79 0a              Jq.f......y.

$ python -c 'import zlib; print zlib.decompress(open("objects/bd/12736e7c805c83494a71c366a7f8850ee7a379").read())'
blob 17sun{git_gud_k1d}
sun{git_gud_k1d}

Source Protection (RE 100)

https://sourceforge.net/projects/pyinstallerextractor/からPyInstaller Extractorをインストール、展開する。

>pyinstxtractor.py passwords.exe
[*] Processing passwords.exe
[*] Pyinstaller version: 2.1+
[*] Python version: 27
[*] Length of package: 3188825 bytes
[*] Found 18 files in CArchive
[*] Beginning extraction...please standby
[+] Possible entry point: pyiboot01_bootstrap
[+] Possible entry point: passwords
[*] Found 194 files in PYZ archive
[*] Successfully extracted pyinstaller archive: passwords.exe

You can now use a python decompiler on the pyc files within the extracted directory

passwordsファイル内にフラグがあった。

sun{py1n574ll3r_15n7_50urc3_pr073c710n}

Visionary (Crypto 150)

スペースを除くprintableな文字をすべて使ったVigenere暗号。

chars = '!\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'

with open('visionary/Cipher1.txt', 'r') as f:
    c1 = f.read().strip()

with open('visionary/Decipher(Cipher1).txt', 'r') as f:
    p1 = f.read().strip()

with open('visionary/cipherFlag.txt', 'r') as f:
    encFlag = f.read().strip()

key = ''
for i in range(len(encFlag)):
    index = chars.index(c1[i]) - chars.index(p1[i])
    if index < 0:
        index += len(chars)
    key += chars[index]

print key

flag = ''
for i in range(len(encFlag)):
    index = chars.index(encFlag[i]) - chars.index(key[i])
    if index < 0:
        index += len(chars)
    flag += chars[index]

print flag
sun{Why_would_Any0n3_use_A_T@bl3_tH@t_LaRg3}

Missing Bytes (Scripting 200)

再帰を使いながら、ディレクトリのサイズが配下のサイズの合計と一致しない場合にsendコマンドでディレクトリ名を指定する。
コードは以下の通り。20ラウンド正解すると、フラグが表示される。

import socket
import re

def recvuntil(s, tail):
    data = ''
    while True:
        if tail in data:
            return data
        data += s.recv(1)

def check_dir(name, size):
    # 0: ok
    # 1: ng
    # 2: finish
    cmd = 'cd ' + name
    #print cmd
    s.sendall(cmd + '\n')
    data = recvuntil(s, '$ ')
    #print data

    cmd = 'ls'
    #print cmd
    s.sendall(cmd + '\n')
    data = recvuntil(s, '$ ')
    #print data

    rows = data.split('\r\n')
    num = get_entries_num(rows[0])
    sum_size = 0
    for i in range(num):
        name2, fd, size2 = get_row_info(rows[i+1])
        sum_size += size2
        if fd == 'DIR':
            res = check_dir(name2, size2)
            if res == 1:
                s.sendall('send ' + name2 + '\n')
                data = recvuntil(s, '\n')
                data += recvuntil(s, ' ')
                if 'Hooray!' in data:
                    data += recvuntil(s, '\n')
                    data += recvuntil(s, '\n')
                    print data
                    return 2
                else:
                    data += recvuntil(s, '$ ')
                    #print data
            elif res == 2:
                return 2

    cmd = 'cd ..'
    #print cmd
    s.sendall(cmd + '\n')
    data = s.recv(256)
    #print data

    if size == sum_size:
        return 0
    else:
        return 1

def get_entries_num(row):
    m = re.search('\((.+) entries\)', row)
    num = int(m.group(1))
    return num

def get_row_info(row):
    name = row[:7].strip()
    fd = row[8:12].strip()
    size = int(row[13:])
    return name, fd, size

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('chal1.sunshinectf.org', 30001))

data = recvuntil(s, '\n')
print data

print 'start'
s.sendall('start\n')

for i in range(20):
    print '**************************'
    print '******** Round %02d ********' % (i+1)
    print '**************************'
    data = recvuntil(s, '$ ')
    print data

    cmd = 'ls'
    print cmd
    s.sendall(cmd + '\n')
    data = recvuntil(s, '$ ')
    print data

    rows = data.split('\r\n')
    num = get_entries_num(rows[0])
    for j in range(num):
        name, fd, size = get_row_info(rows[j+1])
        if fd == 'DIR':
            print name
            res = check_dir(name, size)
            if res == 1:
                s.sendall('send ' + name + '\n')
                data = recvuntil(s, '\n')
                data += recvuntil(s, ' ')
                if 'Hooray!' in data:
                    data += recvuntil(s, '\n')
                    data += recvuntil(s, '\n')
                    #print data
                    break
                else:
                    data += recvuntil(s, '$ ')
                    #print data
            elif res == 2:
                break
sun{a11_ur_byt3s_4re_b3long_t0_m3}

0CTF/TCTF 2018 Quals Writeup

この大会は2018/3/31 10:00(JST)~2018/4/2 10:00(JST)に開催されました。
今回もチームで参戦。結果は225点で700チーム中85位でした。
自分で解けた問題をWriteupとして書いておきます。

Welcome (Misc)

freenodeで#0ctf2018チャネルに入ったら、フラグが表示された。

10:08 *topic : "Welcome to 0CTF / TCTF 2018". flag{Welcome_to_0CTF_2018!}. Any question, please mailto: ctf@0ops.net"
flag{Welcome_to_0CTF_2018!}

h4x0rs.club 1 (Web)

admin/admin(パスワードは何でも可)でキャプチャの値を正しく入力すればログインできる。
[PROFILE]ボタンを押すと、フラグが書かれている画面が表示された。
f:id:satou-y:20180410202704p:plain

flag{h0w_d1d_y0u_get_thiSs_gud_luck_for_next_one}