BCACTF I Writeup

この大会は2019/6/9 13:00(JST)~2019/6/16 13:00(JST)に開催されました。
今回もチームで参戦。結果は5904点で902チーム中29位でした。
自分で解けた問題をWriteupとして書いておきます。

hello-world (0: welcome 50)

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

bcactf{hello!}

net-cat (0: welcome 50)

ncで接続するだけ。

$ nc challenges.ctfd.io 30126
bcactf{5urf1n_7h3_n37c47_c2VydmVyc2lkZQ}
bcactf{5urf1n_7h3_n37c47_c2VydmVyc2lkZQ}

wuphf (0: welcome 50)

BCACTFのDiscord, Twitter, Instagramにアクセスして、確認すると、フラグの断片があった。

[Discord]
Thanks for joining the Discord! The Discord flag-ment is bcactf{h17

[Twitter]
Thanks for checking out our twitter! Why don't you drop us a follow?
Flag-ment: _u5_uP_d3

[Instagram]
A high school-made, middle to high school-focused CTF. Follow for the latest news and updates.
Flag-ment: VwaGYuY29t}

見つけたフラグの断片を結合すると、フラグになる。

bcactf{h17_u5_uP_d3VwaGYuY29t}

executable (binary-exploitation 150)

$ ./executable-ubuntu
Welcome to the lottery!
So now we're going to pick a ginormous number!
If it's 1, you win!
Your number is 1804289383!
Try again next time!

Ghidraでアセンブリを見る。

    :
        004006a4 83 fb 01        CMP        EBX,0x1
        004006a7 75 7b           JNZ        LAB_00400724
        004006a9 bf 70 08        MOV        EDI=>s_Congratulations,_you're_our_luck_004008   = "Congratulations, you're our l
                 40 00
        004006ae e8 1d fe        CALL       puts                                             int puts(char * __s)
                 ff ff
    :

ebxが1のときに正解する。面倒なので、75 7bを90でつぶして何でも正解するようにして実行する。

$ ./executable-ubuntu_mod
Welcome to the lottery!
So now we're going to pick a ginormous number!
If it's 1, you win!
Your number is 1804289383!
Congratulations, you're our lucky winner!
-
-
[
-
-
-
-
-
>
+
<
]
>
-
-
-
-
.
+
.
-
-
.
+
+
.
-
[
-
-
-
>
+
<
]
>
-
-
.
+
+
+
[
-
>
+
+
+
<
]
>
+
.
+
[
-
-
-
-
-
>
+
<
]
>
.
>
-
[
-
-
-
-
-
>
+
<
]
>
.
+
[
-
-
-
>
+
+
<
]
>
.
[
+
+
>
-
-
-
<
]
>
-
.
-
[
-
>
+
+
<
]
>
-
.
-
[
-
-
-
>
+
<
]
>
-
.
-
.
>
-
[
-
-
-
-
-
>
+
<
]
>
+
.
-
-
-
[
-
>
+
+
<
]
>
.
+
+
+
+
+
+
+
+
+
+
.
[
-
-
>
+
<
]
>
-
-
-
.
-
-
[
-
-
-
>
+
+
<
]
>
-
-
-
.
+
+
[
-
>
+
+
+
<
]
>
.
[
-
-
-
>
+
<
]
>
-
-
-
.
+
+
+
[
-
>
+
+
+
<
]
>
.
+
+
+
+
+
+
+
.
-
[
-
-
-
>
+
<
]
>
-
-
.
-
-
-
-
-
-
-
.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
.
+
[
-
-
>
+
<
]
>
+
.
+
.
+
+
.
+
[
-
>
+
+
<
]
>
.
-
-
.
-
-
-
.
+
+
+
+
+
+
+
+
+
+
+
+
+
.
-
-
[
-
>
+
+
+
+
+
<
]
>
.
+
+
+
+
+
+
+
+
.
+
.
-
-
-
-
-
-
-
.
+
+
.
+
.
>
-
-
[
-
-
>
+
+
+
<
]
>
.

そのまま結合すると、Brainfuck言語になっている。

--[----->+<]>----.+.--.++.-[--->+<]>--.+++[->+++<]>+.+[----->+<]>.>-[----->+<]>.+[--->++<]>.[++>---<]>-.-[->++<]>-.-[--->+<]>-.-.>-[----->+<]>+.---[->++<]>.++++++++++.[-->+<]>---.--[--->++<]>---.++[->+++<]>.[--->+<]>---.+++[->+++<]>.+++++++.-[--->+<]>--.-------.---------------.+[-->+<]>+.+.++.+[->++<]>.--.---.+++++++++++++.--[->+++++<]>.++++++++.+.-------.++.+.>--[-->+++<]>.

https://sange.fi/esoteric/brainfuck/impl/interp/i.htmlで実行すると、フラグが表示される。

bcactf{3x3cut4bl3s_r_fun_124jher089245}

basic-numbers (crypto 50)

2進数をASCIIコードとして、文字にしていく。

codes = '01100010 00110001 01101110 01100001 01110010 01111001 01011111 01110011 00110000 01101100 01110110 00110011 01100100 01011111 01100111 00110000 00110000 01100100 01011111 01110111 00110000 01110010 01101011'
codes = codes.split(' ')

flag = ''
for code in codes:
    flag += chr(int(code, 2))

flag = 'bcactf{%s}' % flag
print flag
bcactf{b1nary_s0lv3d_g00d_w0rk}

cracking-the-cipher (crypto 50)

シーザー暗号。https://www.geocachingtoolbox.com/index.php?lang=en&page=caesarCipherで復号する。

Rotation 2:
the password is learning_caesar_ciphers_is_fun!
bcactf{learning_caesar_ciphers_is_fun!}

three-step-program (crypto 125)

最初の暗号はBase64。デコードする。

>>> base64.b64decode('MzIgLSAgfDMgVGltZXMgQSBDaGFybXwgLSAzMg==')
'32 -  |3 Times A Charm| - 32'

次の暗号のヒントになっているようだ。Base32と推測して、3回デコードする。

>>> import base64
>>> enc = 'JJGTEVSLKNBVISSGINCU2VCTGJFVETCWKNGVGTKLKJEEKQ2VJNEUSNC2KZKVCS2OJFNE4RKPKNFUUSKSJNKTITSDKJFEERKUI5GTETKJLJGVMQ2RJNLEWUSLIZAVES2DJRFE2RKDK5JU2SKKJBCTEVKLJBDUSWSUI5KTETSLKZEVKS2TLJKEWUSFIU2FKU2WJRBEIVCFKFJVASKWIFKU2USLIRDUUR2FGJJEWQ2LKJGFMR2TJNCUYSSIIRFU2U2UJFCTEVKJKZJUMSKKJNKU6VK2KRFVES2VGZKEWUSKIJCVIR2XKNBEUNKGIZDVMMSEJRFEERKDKRJVOR2SJJKUGV2TJVFDKR2VGRLVGSKLJUZEKSKWJNHEWWSKKVDVCSSUJFJEERJUK5JVKTCCIZKEKVCDIVFFUQKWKFITEQSJJZEVKV2SGJDEYQSCKVBVMSSTJFFEMRSFKMZEISKFLJCVSTKTIZEUUTCGJ5JVUV2KJJAVKNSVKNMUWTSBKZKU2MSUJJLEYRCFKEZEETCKJNDECVCSKZFU4QSVI5ITEU2LJZCEMU2VJNDEYRSOIVKVCS2OJRFE4RKPKFNFIS2SINCTEUSTKZGEERCVKNJEGRKKGVDEISKXINBEOVSDIVGVES2DJM2UIVKXKNFUKSS2I5LE2VSLLBGEKWSVJFJFGUCLLJHEKQ2QJI2UQVJWKE6T2PJ5'
>>> for i in range(3):
...     enc = base64.b32decode(enc)
...
>>> enc
'Why english so ard to tok. \nNo speak more English. \nAil gi you tu hints to read my encrypted languich. \n\n1. SALT iz key to gret food!\n2. Le francais crypte le meilleur'

次の暗号のヒントになっているはず。SALTが鍵になっている。暗号から考えるとシフト暗号。シフト数が変わると推測し、復号する。

import string

enc = '''lhlm oad lamaew eyhmgs. lg i sxsro rgu ntee qhj a qesg? dbfcp rgu stne xtve tm lhtl xac, b'dl rh wadr gn jhm ayw zayw at zowr. 
mvscey{bu57_j0n_o4i7_kgbhmffhlqe} bfm, te htjnpw, feim lixx at hhf't mx ko dbepwx...'''

key = 'SALT'.lower()

flag = ''
i = 0
for c in enc:
    if c in string.lowercase:
        idx = string.lowercase.index(c)
        idx = idx - string.lowercase.index(key[i%len(key)])
        if idx < 0:
            idx += 26
        flag += string.lowercase[idx]
        i += 1
    else:
        flag += c

print flag

復号結果は以下の通り。

that was simple enough. so i heard you came for a flag? since you have made it this far, i'll go easy on you and hand it over.
bcactf{ju57_y0u_w4i7_znjhbmnhaxm} but, be warned, next time it won't be so simple...
bcactf{ju57_y0u_w4i7_znjhbmnhaxm}

tupperware (crypto 175)

いろいろ巨大な数字になることを推測して、組み立ててみたがうまくいかない。
タイトルにヒントがあるかと考え、調べていたら、「タッパーの自己言及式」というものがあることがわかった。
en.wikipedia.org
これを使うのであれば、数字3桁部分のみ情報があればよいので、数字3桁部分のみ抜き出す。

from word2number import w2n

with open('k', 'r') as f:
    data = f.read().split('\n')[14]

data = data.replace('<span class="Apple-converted-space">\xc2\xa0 </span>', ' ')
nums = data[31:-12].split(', ')

num_str = ''
for i in range(len(nums)):
    if i != len(nums) - 1:
        num_al = ' '.join(nums[i].split(' ')[:-1])
        num = str(w2n.word_to_num(num_al)).zfill(3)
        num_str += num + ' '
    else:
        num = str(w2n.word_to_num(nums[i])).zfill(3)
        num_str += num

print num_str

実行結果は以下の通り。

004 858 487 703 217 654 168 507 377 105 634 002 647 731 128 499 307 244 851 441 090 357 865 711 033 443 419 793 531 999 883 261 579 086 703 285 988 550 325 970 512 343 063 312 965 327 580 978 241 840 458 705 778 582 504 607 655 879 151 828 149 694 589 867 198 840 959 598 497 597 989 866 084 694 560 490 675 801 786 347 730 851 438 931 275 584 908 138 190 409 481 880 911 319 491 978 644 808 036 817 873 514 056 590 135 331 578 105 862 821 454 454 617 375 919 870 245 363 440 066 372 700 053 263 362 863 694 129 133 765 441 926 533 609 503 994 018 565 319 382 913 454 161 429 058 505 655 350 780 911 229 203 432 392 967 236 137 647 780 308 966 936 691 439 636 980 058 266 693 498 568 235 464 310 907 628 785 433 105 091 526 639

https://takitamblog.tk/skrypty/Tupper/でこの結果を入力し、グラフに表示させる。さらにGraph options and functionsで、Flip verticallyとFlip horizontallyを使って向きを変えると、フラグが表示された。
f:id:satou-y:20190616200532p:plain

bcactf{a11_0ccur}

runescape (crypto 180)

換字式暗号と推測し、ASCII文字に1:1で適当に変換する。

ABCBDE{EFGHIGJBKCJCLKMNMNMOGFKPFGCDQRGJMSLONJPCJJSKNJPTSJSCLURCAGDNBMIAMDNDIDNSJBNURGFM_CABVGEPRNWXLTJSUHFMDIOQYKZ}

https://quipqiup.com/で復号する。

BCACTF{ FREQUENCY ANALYSIS IS VERY GREAT WHEN SOLVING ANNOYING MONO ALPHABETIC SUBSTITUTION CIPHERS_ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}
bcactf{frequencyanalysisisverygreatwhensolvingannoyingmonoalphabeticsubstitutionciphers_abcdefghijklmnopqrstuvwxyz}

a-major-problem (crypto 200)

https://major-system.info/en/ で各単語の数値(何行目か)を得る。

Pave 98
Pop  99
Poke 97
Pop  99
Dutch 116
Dozen 102
Denim 123
Deism 103
Loot   51
Thatch 116
Pal 95
Atheism 103
Rough 47
Ditch 116
Tonal 125

ASCIIコードとして文字にする。

bcactf{g3t_g/t}

これはフラグとして通らなかった。Roughの行数がずれたと考え、48にして考えると、フラグとして通った。

bcactf{g3t_g0t}

split-the-red-sea (forensics 100)

Stegsolveで開き、Red plane 1を見ると、フラグが書いてある。
f:id:satou-y:20190616201452p:plain

bcactf{7w0_r3d5_sdf3wqa}

bca-craft (forensics 125)

datapacks\bcacraft\data\bca\functions\flag.mcfunctionを見ると、フラグ文字列が入っている。

tellraw @a ["Hello ", {"selector": "@p", "color": "yellow"}, "! The flag is: ", "b", "c", "a", "c", "t", "f", "{", {"text": "m1n3cr4f7_b347s_f0rtn1t3", "color": "blue", "bold": true, "obfuscated": true, "hoverEvent": {"action": "show_text", "value": {"text": "Good luck! ", "extra": [{"text": "Hint: Where does Minecraft store its worlds?", "color": "dark_gray", "italic": true}]}}}, "}"]
bcactf{m1n3cr4f7_b347s_f0rtn1t3}

file-head (forensics 125)

pngのファイルヘッダが壊れている。修正すると、画像を見ることができ、フラグが書かれている。
f:id:satou-y:20190616205022p:plain

bcactf{f1l3_h3ad3rs_r_c001}

open-docs (forensics 150)

解凍すると、word/secrets.xmlBase64文字列が入っている。

PHNlY3JldCBmbGFnPSJiY2FjdGZ7ME94TWxfMXNfNG00ejFOZ30iIC8+
$ echo PHNlY3JldCBmbGFnPSJiY2FjdGZ7ME94TWxfMXNfNG00ejFOZ30iIC8+ | base64 -d
<secret flag="bcactf{0OxMl_1s_4m4z1Ng}" />
bcactf{0OxMl_1s_4m4z1Ng}

wavey (forensics 150)

wavファイルが添付されている。Audacityで開き、スペクトグラムを見る。
f:id:satou-y:20190616205314p:plain

bcactf{f331in_7h3_vib3z}

the-flag-is (forensics 200)

pdfファイルが添付されている。PDFStreamDumperで開き、0x172-0x1D2を見ると、フラグが入っていた。

BT /F1 16 Tf 100 700 Td (bcactf{d0n7_4g3t_4b0u7_1nCr3Men74l_uPd473s}) Tj ET
bcactf{d0n7_4g3t_4b0u7_1nCr3Men74l_uPd473s}

large-pass (reversing 100)

Ghidraでデコンパイルする。

undefined8 main(void)

{
  long in_FS_OFFSET;
  long local_20;
  long local_18;
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  local_18 = 0x4cf7983ffb7741c8;
  __printf_chk(1,"Password: ");
  __isoc99_scanf(&DAT_0010098f,&local_20);
  if (local_18 == local_20) {
    puts("Correct password.");
  }
  else {
    puts("Incorrect Password.");
  }
  if (local_10 == *(long *)(in_FS_OFFSET + 0x28)) {
    return 0;
  }
                    /* WARNING: Subroutine does not return */
  __stack_chk_fail();
}

入力した文字を数値として扱い、0x4cf7983ffb7741c8と比較している。

>>> 0x4cf7983ffb7741c8
5546068866699313608L
5546068866699313608

survey (0: welcome 25)

簡単にコメントして、Submitしたら得点となった。