Attack All Around

今やCTFと競プロばかりだが、トビタテ生のアメリカ留学やTOEFL奮闘記

picoCTF 2021 writeup

こんにちは!Ken.Sです!

 

つい最近に留学の研究後記ブログを書いたばかりですが(と書いて保存してたらangstromCTFの方を先に公開することになるとは…)、今回もwriteupを書いていきます!今回かなり頑張ったので読んでくださると本当に嬉しいです!

 

picoCTFはチーム上限5人で、m1z0r3からは8人の参加希望があったので2チームに分けて対決してました!私率いるm1z0r3チームはなんとかもう一つのkum0r1に勝てましたドヤァ。AtCoderやってる人ならわかるtourist出しをやりました(笑)

 

また、picoCTFはpicoGymという形で問題が残るのであとで復習が出来るのが素晴らしい!勉強会で扱う問題を探しているときに実際の問題が残ってるの本当に助かるので有難いですね。

 

※問題文にヒントがありましたが、使ってないのは記載してません。

 

※もしこれを読んでくれているm1z0r3メンバーがいたら、一部問題を勉強会に使います!どれを使うかはもう決めているのでその問題の解説の最初に一言書いておきます。読んでもいいけど勉強会つまらなくなっちゃうよ!

 

 

 

 

Result

Ranking

f:id:partender810:20210331131455p:plain

Global 順位

f:id:partender810:20210331131520p:plain

Japanese Students 順位

全体で181位、日本人学生チームで6位でした!!

1位のチーム1万pt超えすごいなぁ…

 

Solves

Rev 9/17問

For 8/13問

Bin 6/16問

Cry 15/17問

Web 9/18問

Gen 7/7問

 

担当したcryptographyをこんなに解けてかなり嬉しいです!他の方に参考になれば幸いです。

 

 

Writeup

General skill

Obedient Cat 5pt

This file has a flag in plain sight (aka "in-the-clear").

ファイル:flag

見たらFlagがありました。

 

picoCTF{s4n1ty_v3r1f13d_1a94e0f9}

 

 

Python Wrangling 10pt

Python scripts are invoked kind of like programs in the Terminal... Can you run this Python script using this password to get the flag?

ファイル:ende.py, flag.txt.en, pw.txt

コード内に書いてあるusageの通りにやってもエラーを吐いてしまい…ende.pyに直接貰ったファイルの文字列を入れてみるとFlagが出ました。

 

picoCTF{4p0110_1n_7h3_h0us3_192ee2db}

 

 

Wave a flag 10pt

Can you invoke help flags for a tool or binary? This program has extraordinarily helpful information...

 ファイル:warm

./warmしてみます。

Hello user! Pass me a -h to learn what I can do! 

 

./warm -hしてみます。

Oh, help? I actually don't do much, but I do have this flag here: picoCTF{b1scu1ts_4nd_gr4vy_616f7182}

 

strings warm | grep "pico" でも見つけられますね

 

picoCTF{b1scu1ts_4nd_gr4vy_616f7182}

 

 

Nice netcat... 15pt

There is a nice program that you can talk to by using this command in a shell: $ nc mercury.picoctf.net 7449, but it doesn't speak English... 

ncしてみると8bit程度の数値がいくつか送られてきます。

最初の数値は112でchrしてみると'p'。これはASCIIですね。

 

picoCTF{g00d_k1tty!_n1c3_k1tty!_f2d7cafa}

 

 

Static ain't always noise 20pt

Can you look at the data in this binary: static? This BASH script might help!

ファイル:static, ltdis.sh

strings static でも一発で出ますがちゃんとやるならば ./ltdis.sh static -> static.ltdis.strings.txtを見るでOKです。

 

picoCTF{d15a5m_t34s3r_f5aeda17}

 

 

Tab, Tab, Attack 20pt

Using tabcomplete in the Terminal will add years to your life, esp. when dealing with long rambling directory structures and filenames: 

ファイル:Addadshashanammu.zip

まずunzipで解凍します。

 

そうするとこんな感じに

f:id:partender810:20210330120105p:plain

unzip結果

Tabキー使って長いディレクトリ名を打つ手間を省きます。fang-なんちゃらのディレクトリまで行きfileコマンドでこのファイルを調べるとELFだということが分かります。./f(Tabキー) で実行するとflagを出してくれました。

 

picoCTF{l3v3l_up!_t4k3_4_r35t!_6f332f10}

 

 

Magikarp Ground Mission 30pt

Do you know how to move between directories and read files in the shell? Start the container, `ssh` to it, and then `ls` once connected to begin. Login via `ssh` as `ctf-player` with the password, `ee388b88`

問題文の横にLaunch Instanceがあるのでクリックしてsshすべきサーバを教えてくれます。 

lsコマンドで何入ってるか見ると「1of3.flag.txt」と「instructions-to-2of3.txt」が入ってます。前者を見るとflagの途中しか見せてくれません。1of3だから仕方ないですね。次のflagを教えてくれそうなtxtファイルがありますね。

 

Next, go to the root of all things, more succinctly `/`

 

cd / ですね。lsとcatで「2of3.flag.txt」と「instructions-to-3of3.txt」を見ます。後者はこう書かれてました。

 

Lastly, ctf-player, go home... more succinctly `~`

 

cd ~ で移動し最後のflagの欠片を貰います。

 

f:id:partender810:20210330121904p:plain

サーバに侵入中…

 

picoCTF{xxsh_0ut_0f_\/\/4t3r_3ca613a1}

 

 

Web Exploitation

Ancient History 10pt

I must have been sleep hacking or something, I don't remember visiting all of these sites... http://mercury.picoctf.net:52731/ (try a couple different browsers if it's not working right) 

このサイトにアクセスしてソースを見ると変な関数が定義されてますね…長すぎる。

 

f:id:partender810:20210327145332p:plain

ソースコード内の関数

よくみたら同じ内容でした。ただ、同じに見えて実は違うところがあるのでは?という発想になるまで時間がかかり、調べてみたら上の画像の中央下部分にある/index.html?pとある箇所が次の行と異なりました。あとはここを抽出したらOK! と思ったのですが…incorrect

 

前の行と違うところだけを見ていたのでflag内で同じ文字が続いた場合、そこを飛ばしてしまってました。そこを注意してcorrectでした。

 

picoCTF{th4ts_k1nd4_n34t_bb660d55}

 

 

Binary Exploitation

What's your input 50pt

We'd like to get your input on a couple things. Think you can answer my questions correctly? 

nc mercury.picoctf.net 56827

ファイル:in.py 

Hint : What version of python am I running?

ヒントを基にコードを見ると2系。print("...") とあったのでよく見ないと分からないですね。

 

31行目のif res == city: がTrueになればFlagが手に入りますが、変数cityに何が入っているか分かりません。

 

これはチームメイトに教えてもらいましたが、2系はinput関数に脆弱性があるとのことで、入力された文字列と同じ名前の変数があるときにその内容がコピーされてしまうとのことです。なので都市の入力の際に"city"と打ち込めばOKです。

 

2系のあからさまな脆弱性を初めて体感したなぁ。

 

picoCTF{v4lua4bl3_1npu7_1599789}

 

 

Forensics

Wireshark doo dooo do doo... 50pt

Can you find the flag?

ファイル:shark1.pcapng

 

pcap系の問題はあまり解いたことがないのですがsolve数が多いので行けるのかなと思ったのが苦戦しました(笑)

 

Wiresharkのfilterを使ってパケットを絞るのだろう、どんなfilterが良いのかは過去のwriteupを見てました。

 

www.slideshare.net

 

「http.request && tcp.port == 80 」とやればパケットが二個に絞られました。あとはそのパケットをTCPストリームすると…

Gur synt vf cvpbPGS{c33xno00_1_f33_h_qrnqorrs}

 

あとはrot13ですね。

 

picoCTF{p33kab00_1_s33_u_deadbeef}

 

 

Cryptography

Mod 26 10pt

Cryptography can be easy, do you know what ROT13 is? cvpbPGS{arkg_gvzr_V'yy_gel_2_ebhaqf_bs_ebg13_jdJBFOXJ}

rot13ですね。さっきやったよ。

 

picoCTF{next_time_I'll_try_2_rounds_of_rot13_wqWOSBKW}

 

 

Mind your Ps and Qs 20pt

In RSA, a small e value can be problematic, but what about N? Can you decrypt this?

ファイル:values

そりゃNが小さいのは問題でしょうよ…。NをfactorDBで殴って終了です。

 

picoCTF{sma11_N_n0_g0od_73918962}

 

 

Easy Peasy 40pt

A one-time pad is unbreakable, but can you manage to recover the flag? (Wrap with picoCTF{}) 

nc mercury.picoctf.net 41934

ファイル:otp.py

Hint : Maybe there's a way to make this a 2x pad.

この問題、配点の割には時間がかかってしまいました。

 

keyの長さが50000で入力された文字列のchrとxorしてくれます。初めにflagをxorしたのをくれますが、keyが分からないので復元できません。10文字を入力に対してkey[i:i+10]を使うとしたら、次の入力に対してはkey[i+10:]が使われます。

 

最初にflagのxorにkeyを使っており、与えられた値とソースよりflagは32文字ということと、key[0:32]を使ってxorしたことが分かります。

 

このkey[0:32]を知りたいのですが、keyの並びに規則性あるのかな…全く見えず…ここでかなり苦戦しました。

 

入力の文字列長の合計が50000越えるようにして、keyを一周させればいいじゃん。"a"*(50000-32)をぶん投げ、次の入力でkeyの0文字目から使えるようにします。また"a"*32でも投げて得られた暗号文よりkey[0:32]を求めます。それを使って最初にもらった暗号化されたflagを復号して完了です。

 

picoCTF{abf2f7d5edf082028076bfd7a4cfe9a9}

 

 

New Caesar 60pt

We found a brand new type of encryption, can you break the secret code? (Wrap with picoCTF{})

ihjghbjgjhfbhbfcfjflfjiifdfgffihfeigidfligigffihfjfhfhfhigfjfffjfeihihfdieieih 

ファイル:new_caesar.py

new_caesar.pyによってこの暗号文が作られたようです。復元頑張りましょう。

 

flagという文字列を引数としたb16_encode関数によってb16文字列を生成し、その文字列を一文字ずつkeyによってshift関数で暗号文を生み出した結果こんなものになりました。

 

b16_encode関数はflagの一文字ずつをASCIIコードにして前4bit, 後4bitに分けます。その値によってa~pを決めます。0000ならaで1111ならpですね。flagの二倍の文字列長になります。

 

shift関数はkeyの文字によってa~pの間でrotateします。

 

復号はやるだけ、って感じでしたね。実装が面倒ですが…。

 

流れとしては、keyの長さが1でa~pのどれかと分かるのでkeyについてはbrute forceしてnew_caesar.py内の変数b16を求めます。

 

shift(c,k)の返り値をalfとすると、(t1+t2)%16 = alfとなるt1を求めます。alfは暗号文の1文字であり、kはbrute forceのkeyでt2はそれに基づく値です。t1に対応する文字列を足していくとb16となります。

 

最後のステップはb16からflagを復元します。

b16を2文字毎に見ていき、(前1文字 - "a")*16+(後1文字 - "a") をchrすれば復元できました。

 

brute forceしているので16種類のflagの候補が出てきます。その中で一番ぽいのを選んで終わりです。

 

gbgcgdgegfggghgi
qQqRY[YSVUT[UYWWWYUYTS
v`@`AHJHwBEDvCurJuuDvHFFFuHDHCvvBssv
et_tu?_0797f143e2da9dd3e7555d7372ee1bbe
TcNcd.N/&(&U #"T!SP(SS"T&$$$S&"&!TT QQT
CR=RS=DCBOBBCBCC@@C
321>112122??2
!01ûóõó"ýðÿ!þ -õ ÿ!óñññ óÿóþ!!ý..!
/
/ ê
ëâäâìïîíäîâàààâîâíì
ùÙùÚÑÓÑÛÞÝÜÓÝÑßßßÑÝÑÜÛ
ÈèÉÀÂÀÿÊÍÌþËýúÂýýÌþÀÎÎÎýÀÌÀËþþÊûûþ
íü×üý·×¸¿±¿î¹¼»íºìé±ìì»í¿½½½ì¿»¿ºíí¹êêí
ÜëÆëì¦Æ§® ®Ý¨«ªÜ©ÛØ Û۪ܮ¬¬¬Û®ª®©ÜܨÙÙÜ
ËÚµÚÛµÌËÊÇÊÊËËËÈÈË
ºÉ¤Éʤ»º¹¶¹¹º¹ºº··º
©¸¸¹st{}{ªuxw©v¨¥}¨¨w©{yyy¨{w{v©©u¦¦©
§§¨bcjljdgfelfjhhhjfjed

 

keyは"d"でした。

et tu? は「(ブルータス、)お前もか?」らしい。

 

picoCTF{et_tu?_0797f143e2da9dd3e7555d7372ee1bbe}

 

 

↓m1z0r3勉強会採用問題

Mini RSA 70pt

What happens if you have a small exponent? There is a twist though, we padded the plaintext so that (M ** e) is just barely larger than N. Let's decrypt this:  

ファイル:ciphertext

ciphertextにはN, e, cが書いてあります。

 

e=3であることとM^eがNよりちょっと大きいことから、c+N*k (k : 自然数)が立方数かを判断して、違うのであればkをインクリメントする、立方数ならばその3乗根を出してlong_to_bytesで終わりです。

 

picoCTF{e_sh0u1d_b3_lArg3r_60ef2420}

 

 

Dachshund Attacks 80pt

What if d is too small? Connect with nc mercury.picoctf.net 58978.

serverに繋げるとn, cととてつもなく大きなeが送られてきます。

 

eが大きいとdが小さくなって成立する攻撃あったな、Wiener's attackか。

 

公開鍵暗号 - RSA - Wiener's Attack - ₍₍ (ง ˘ω˘ )ว ⁾⁾ < 暗号楽しいです

 

実装例を丸パクリで終了。

 

picoCTF{proving_wiener_6907362}

 

 

No Padding, No Problem 90pt

Oracles can be your best friend, they will decrypt anything, except the flag's ciphertext. How will you break it? Connect with nc mercury.picoctf.net 28517.

Hint : What can you do with a different pair of ciphertext and plaintext? What if it is not so different after all...

このserverは、flagの暗号文以外は復号してくれるオラクルとなっています。

 

最初に送られてくる「Padding oracle attack」が本当にそうか怪しい。平文は恐らくb"(パディング)picoCTF{temp}(パディング)"と予想(違った)。cの値を変えて送ったら復号して違うパディングの平文が手に入るのかなと最初はこんな感じでした。

 

上手くいかないので、RSA Oracle Attackでググってみると、以下のサイトが。

 

plain RSAに対するLSB decryption oracle attackをやってみる - ももいろテクノロジー

 

mのbit数だけ問い合わせをするのに対して、このoracleは途中で止まってしまう仕様…。とりあえずこのサイトにある別の方法(リンクがある)をやってみます。

 

RSAに対する適応的選択暗号文攻撃とパディング方式 - ももいろテクノロジー

 

これやってみたら一発。

 

picoCTF{m4yb3_Th0se_m3s54g3s_4r3_difurrent_4005534}

 

 

It's Not My Fault 1 100pt

 What do you mean RSA with CRT has an attack that's not a fault attack? Connect with nc mercury.picoctf.net 47414

ファイル:not_my_fault.py

はじめに、これ解けたの本当に嬉しい!!今回解けた中で一番solves数が少ない問題でした!

 

このserverはまずProof-of-Workをします。これはやるだけで特に問題に関係ないですね。

 

次に512bitの素数p,q (※gcd(p-1,q-1) = 2) を生成し公開鍵n(=p*q)を公開します。d_pは1~2^20の間で、d_qは1~q-1の間でランダムで決めます。秘密鍵dは中国人剰余定理の要領で、(p-1)で割ったらd_pかつ(q-1)で割ったらd_qとなる(p-1)*(q-1)=phi以下の自然数が採用されます。phiを法としたdの逆元eを公開鍵として公開します。

 

最後に15分以内でp+qの値をserverに送り一致すればflagが手に入ります。

 

最初はp-1とq-1でCRTしているところに注目しました。gcd(p-1,q-1) = 2 なのでd_p, d_qが偶数である場合、秘密鍵dは偶数になり(p-1)*(q-1)での逆元は存在しないことになります。この点が何かしらの脆弱性なのかなと調べてみたけど分からず…。

 

次に気になった点としては、p+qを答えさせるのに15分もの猶予があることです。計算させるにもこれだけの時間がかかるとしたらbrute forceだろう。brute forceするとしたらd_pの値は最大100万程度だからいけるはず。けどd_pの値を仮に置いたところで何が分かるんだろう…。

 

RSA

 

このサイトを見て直感的に思ったこととして、自分でmをテキトーに設定し与えられたe, n で暗号化する。d_pをbrute forceして仮に置きd_pを秘密鍵のようにpow(c, d_p, n)を計算しm'を得る。m = m' ならいいなと思ったけどそんなことはありませんでした。

 

貰ったファイルを手元で動かしp, q, d_p, d_q, dなどを出力し色々確かめてみます。本来の秘密鍵を使えばm = m'になるはずですがそうはならないのでこの差分に何があるのかと調べたところなんと(m' - m)%p = 0でした!

 

終わってから考えるとフェルマーの小定理を使えば証明できました!

 

f:id:partender810:20210330231540p:plain

d_p = d mod p-1 がバレると復号出来てしまう証明

 

正しいd_pを選ぶとm' - m = pow(c, d_p, n) - pow(c, d, n) = k*p (kは整数)となります。なのでd_pをbrute forceしてgcd(m' - m, n) != 1になるようなd_pを見つけます。gcdが1出ない時それはpの値と合致するので p+q は簡単に求められます。

 

手元で動かすと分かるのですが、上記の式はe*d = 1 mod φ(n) である時しか成り立ちません。m = c^d mod nとならないためですね。d_p, d_qが偶数の時は逆元は存在しないので、上手くいくためには何回かserverにつなげて運良く奇数になることを願うのみです。

 

秘密鍵dを(p-1) or (q-1)で割った余りが分かると解読される脆弱性があるとは知りませんでした。

 

It's Not My Fault 2 ではd_pの範囲が1 ~ 1<<36 に増えてました。brute force出来ないようになってますね。どうにかしてd_pの候補を1<<36から1/(2^16)ほどカットできる方法があるのかな…?

 

picoCTF{1_c4n'7_b3l13v3_17'5_n07_f4ul7_4774ck!!!}

 

 

↓m1z0r3勉強会採用問題

Play Nice 110pt

Not all ancient ciphers were so bad... The flag is not in standard format. nc mercury.picoctf.net 21003

ファイル:playfair.py

 

Playfair cipherという暗号があるらしい。もらったコード内にもそのwiki URLがあるけどこの問題ではこのwikiを理解する必要は全くなく、コードを読んで暗号アルゴリズムを理解すれば良かったです。言ってみればただの換字式暗号でした。

 

暗号化するためのmatrix(6*6の大きさでアルファベット小文字と半角数字をランダムで散りばめたもののよう):既知 ncすれば教えてくれる&コード内にもある
暗号化されたメッセージ:既知 ncすれば教えてくれる元のplaintext = msgを二文字ずつ暗号化していく。(msgが奇数長なら"0"を加えるが今回はそこまで重要じゃない)
その二文字をs1,s2とすると、まず両者のindexを調べ("0" -> (0,0) "f" -> (5,2) etc)、p1,p2に格納する。
enc_msg = ""
if s1,s2が同じ行にある文字:
enc_msg += s1の一つ右+s2の一つ右の文字
elif s1,s2が同じ列にある文字:
enc_msg += s1の一つ下+s2の一つ下の文字
else:
p1x : s1の行番号, p1x : s1の列番号だとする
enc_msg = matrix[p1x][p2y] + matrix[p2x][p1y]このenc_msgが暗号化されたメッセージである

 

復号はこんな感じです。

enc_msgを2文字毎見る -> e1,e2
if 同じ行: 一つ左の文字を足す
elif 同じ列: 一つ上の文字を足す
else: matrix[e1x][e2y] + matrix[e2x][e1y]

 

cryptoというよりかはプログラミングでしたね。

 

3f4b60ebf36369258d8638d2038c7ad1

 

 

↓m1z0r3勉強会採用問題 

Double DES 120pt

I wanted an encryption service that's more secure than regular DES, but not as slow as 3DES... The flag is not in standard format. 

nc mercury.picoctf.net 31991

ファイル:ddes.py 

このserverは、まずKEY1, KEY2と生成します。0~9から6文字と空白2文字です。そこから入力を受け付けunhexlifyやpaddingなどをしたあと、DES方式でKEY1で暗号化しさらにKEY2で暗号化したものを送ってくれます。

 

DESを2回やる2DESが悪いって何か聞いたことあるな…。これだ!

 

中間一致攻撃 ‐ 通信用語の基礎知識

 

つまりは平文と暗号文が分かっている場合、鍵1と鍵2をbrute forceして求めることが出来ます。暗号文を鍵2でdecodeして鍵1でdecodeするというやり方ですと、鍵の長さをNとした際にO(N^2)とかなり時間がかかってしまいます。

 

そこで、平文を鍵1でencodeしたもの(Aとする)と、暗号文を鍵2でdecodeしたもの(Bとする)を記録しておきます。Aの中からBに含まれているものを探し、一致していればそのencode/decodeしたものが正しい鍵ペアとなり、探索を二分探索で行えばO(N log N)で済みます。birthday attackですね。

 

今回、ddes.pyを見ると0~9の中からランダムに構成された6文字と2文字分のスペースがそれぞれ鍵1,2に採用されています。つまり鍵1,2ともに10^6=100万通りしかありません。

 

サーバは初めに2DESによって暗号化されたflagを公開し、平文を入力すると同じ鍵ペアで暗号化してくれます。この平文と暗号文を頼りに上記の方法でbrute forceします。

 

pythonで「平文-(鍵1)->暗号文1」と「暗号文2-(鍵2)->暗号文1」の生成を行い、テキトーなファイルに"暗号文1 鍵1(もしくは鍵2)"という形で出力します。次に暗号文1が一致しているかの探索はpythonでやると遅いのでc++で記述しました。「暗号文2-(鍵2)->暗号文1」で生成された文字列をソートしておき、「平文-(鍵1)->暗号文1」を二分探索します。O( (KEY1の個数) * log(KEY2の個数) ) = O(10^7)程度ですね。競プロをやってた経験がここで生きました。

 

鍵長が短いためか異なる鍵ペアでも同じ結果となるものが多かったです。

 

あとは見つけた鍵で暗号化されたflagを復号して終わりです。

 

6d4e063d16d250b953d009e2ef07e241

 

 

↓m1z0r3勉強会採用問題

Compress and Attack 130pt

Your goal is to find the flag.  

nc mercury.picoctf.net 29350

ファイル:compress_and_attack.py

Hint : The flag only contains uppercase and lowercase letters, underscores, and braces (curly brackets)

この問題が一番悩みましたね…。

 

このserverは文字列を入力として受け付け、flag文字列の後ろに足してzlib.compress() でバイト列に圧縮します。次にSalsa20方式によって暗号化します。暗号化に必要なkeyは32バイトでos.urandom(32)によって定義されます。最後に暗号文と暗号化に使用したnonce, 暗号文の長さを表示します。

oracleのように入力を何回でも受け付けてくれ全て暗号化してくれます。

 

zlib.compress() を見ていきましょう。

str型をbytes型に圧縮します。どのように圧縮しているかは分からなかったのですが、zlib.decompressで元に戻せるとのことでした。

 

次にSalsa20について考えます。

色々調べたのですが、chacha20と同じように書かれていることが多く理解が難しかったです。wikiなどあるので参考にしてみて下さい。

 

Salsa20 - Wikipedia

 

自分なりの理解とすると長さ16のサイズが8bytesの配列を用意し、複雑な計算で値を決定します。その配列を2bytes毎にリトルエンディアン方式で長さ64の配列に格納します。この配列と平文をxorしたのが暗号文となります。

 

ではこの長さ64の配列を特定できたらflag+inputの圧縮bytesが分かりzlib.decompressで元に戻せるのではないのか、とこの配列のことだけを考えていきましたがどの文献を調べてもCrypto.Cipher.Salsa20と同じ挙動をするプログラムを作れず…。ここに数日使って考えてました。

 

ふと問題名について考えると、攻撃すべきはSalsa20ではなくzlib.compressじゃないのか?len()とれば分かるのにわざわざ暗号文の長さを表示させてるのは意味があるのではないのか?flagは55種類で構成されているというヒントからbrute forceでもするのか?

ここまで想像したらあと一歩頑張るだけで良かったです。

 

データの圧縮ですがzlib.compressがどのような挙動をしているかは不明ですが、辞書を作って圧縮しているそうです。例えばaaabbという文字列ならaが3個並んでbが2個並ぶという意味で圧縮すればa3b2のような形となり元の文字列が5文字なのに対し書き換えると4文字を圧縮することとなりさらに圧縮後の文字列長が短くなります。

 

つまり、flag+inputの形で圧縮するのでflagと同じ文字列をinputとすれば圧縮後の長さは他の文字をinputとした時より短くなり特定できるのでは?という考えに行きつきました。

 

flag+(flagの部分文字列)+(何か一文字) の (何か一文字)をbrute forceして圧縮率の良い入力を探します。有難いことに毎回一文字だけ他の文字と比べて暗号文の長さが短くなる時がありました。それをflagの部分文字列に追加していき、"}"が当てはまる時まで回します。serverに空文字送ると45の長さが返って来るのでそれを使っても良いですね。

 

私の部屋の通信が遅いせいか途中でタイムオーバーしてしまい、途中まで求めたflagの部分文字列をスタートにして求めました。solverには最初から求めるようなものを掲載しています。

 

この問題だけで6日かかった…。

 

picoCTF{sheriff_you_solved_the_crime}

 

 

↓m1z0r3勉強会採用問題

Scrambled: RSA 140pt

Hmmm I wonder if you have learned your lesson... Let's see if you understand RSA and how the encryption works. Connect with nc mercury.picoctf.net 6276.

Hint1 : Look at the ciphertext, anything fishy, maybe a little bit long?

Hint2 : What happens if you encrypt the same input multiple times?

Hint3 : Is RSA deterministic, why would outputs vary?

 

serverにつなげると公開鍵e, nに加えやけに値の大きい暗号文cが送られてきます。その後oracleのように任意の平文を暗号化してくれます。

 

まずcがnより大きいのでただのRSAではないことが分かります。c mod nを取っても何も分かりません…。

 

ヒントを参考に何回か同じ平文をoracleに投げてみます。ここで気付いたことは平文長1の時は何度やっても同じ暗号文が返ってくるのに対し、平文長2の時は異なる暗号文が送られてきて計2種類ありました。平文長3の時はもっと種類がありました。

 

さらに気付いたこととして平文"12"の暗号文の中に平文"1"の暗号文が含まれており"b"は含まれていない点です。

 

I will encrypt whatever you give me: 1
Here you go: 13124115897409148690175503414678311002550072264931973692606617424840875394178924924667165806108832225382916928826588194202873207482242336795957858653898547865981328797617704615680916248306354749186650700653148182638263380446877489886302315539251194333627159551808654634412960860616807864577972598755285353671
I will encrypt whatever you give me: 2
Here you go: 101313714858161761634424992049701340225225901427102268968811128642939843971178700310220868193986270827880834443468869250035948793946978960836348254108084878497428993736369171344812715172293673578722333182457607039902800607183698449846158886607662435088015414390779614690393026603998035663690508448583587232108
I will encrypt whatever you give me: 12
Here you go: 1312411589740914869017550341467831100255007226493197369260661742484087539417892492466716580610883222538291692882658819420287320748224233679595785865389854786598132879761770461568091624830635474918665070065314818263826338044687748988630231553925119433362715955180865463441296086061680786457797259875528535367153230702539676627077713255043960931601547634062672474402191718157569789042884730190065962186209672390181875607152200181525682605899965673289841280220588582699750835635714680926113598794384506889798456369904349419599058763732276368570777636231103073162515084138617288828974174983151895993498712348576936738885
I will encrypt whatever you give me: 123
Here you go: 462421867967343899092247904339366104356633194458564599507361558221364994129967069812583568887596621514840256516950454547665458461766413255685426477319761146914988512715132189205891743864191787311225979337320579909727351783274773056270868986792549936307841261246031472338304220554727128192453579090999110003105323070253967662707771325504396093160154763406267247440219171815756978904288473019006596218620967239018187560715220018152568260589996567328984128022058858269975083563571468092611359879438450688979845636990434941959905876373227636857077763623110307316251508413861728882897417498315189599349871234857693673888513124115897409148690175503414678311002550072264931973692606617424840875394178924924667165806108832225382916928826588194202873207482242336795957858653898547865981328797617704615680916248306354749186650700653148182638263380446877489886302315539251194333627159551808654634412960860616807864577972598755285353671

 

1文字毎に分け暗号化しそれを付け足してるのかと思いきや、"2"の暗号文は"12"に含まれていないので違うよう…。けど平文の長さに比例して暗号文の長さも長くなります。

 

ここで"12"の暗号文をSとTに分け、"1"の暗号文と一致するものをS、そうでないのをTとすると、"123"の暗号文にはSとTがともに含まれており、さらに異なる文字列Uがありました。

 

つまり平文をmとすると、{m[0:1], m[0:2], m[0:3], ... , m[0:n]} をそれぞれRSAで暗号化し暗号文をごちゃ混ぜにして繋げていると予想しました。

 

なので後の実装としては、{ p, pi, pic, pico, picoC, picoCT, picoCTF, picoCTF{ }の暗号文を配列に記憶します。次にstring.printableで回し、貰った暗号文の内記憶した暗号文を除いた文字列S'が最初に渡されるflagの暗号文に含まれていたら、その入力はflagの部分文字列であることが分かります。この際に記憶配列に今の暗号文を追加します。

 

これを繰り返しflagを求めます。

 

Compress and Attackと同様途中でタイムオーバーに...。通信弱いとつらい。

 

picoCTF{bad_1d3a5_2268684}

 

 

It is my Birthday 2 170pt

問題文が見れませんでした…。

内容的には、渡したpdfと後ろ1000バイトは同じである異なるpdfをこの二つ作り、このウェブサイトにアップロードしてください。この二つのpdfのSHA-1ハッシュ値は同じになるようにしてください。

ファイル:invite.pdf

Hint : SHAttered (他にもあったけど覚えてません…)

問題文がもう見れなくなっておりなんとなくこんな感じでしたとだけ…。

 

うーーん、Forensicsぽい。苦手だ。とりあえずSHA-1が良くないということは知ってるけど理由までは知らない…。昔SHA-1の衝突を使ったCTFあったらしいと聞いたことがあるぞ。ググりつつ人に聞いたりしてました。

 

とりあえずSHA-1の理解を。

 

www.slideshare.net

 

バイナリデータが二つ

xxxxABCxxxxxxxx

xxxxDEFxxxxxxxx

このようにある時SHA-1ハッシュ値がABCとDEFで衝突するとき、上の二つのSHA-1ハッシュ値も衝突します。まあそのABCとDEFのペアを見つけるのにかなりな時間がかかるんですけどね。

 

SHA-1 pdf collisionなどでひたすらググってました。githubとかで色んなコードコピペしたのに上手くいかず…。かなり唸ってました。

 

チームメイトとzoomで議論した時にふと「既に出てる衝突する二つのpdfの後ろに1000バイト引っ付ければ良くね?」と。ビンゴでした!!

 

picoCTF{h4ppy_b1rthd4y_2_m3_ed9cc7d0}

 

 

Pixelated 200pt

I have these 2 images, can you make a flag out of them?

ファイル:scrambled1.png, scrambled2.png 

Hint : Visual cryptography - Wikipedia , Think of different ways you can "stack" images

(実はチームメイトが解いたんですけど、自分も惜しかったので紹介させていただきます)

 

pngファイルは前回のutctfで初めて使ったPILを利用してみます。貰ったpngを重ねたらいいのだろう。PIL使ったり、片方のpngの透過度半分にしたりとかやったんですけど灰色の画像しか出てこない…。

 

PILのImage.composite() では上手くいかないようでNumpy arrayで画像を読み込み和を取れば一発で出たようです。チームメイトすごいなぁ。

 

f:id:partender810:20210331232307p:plain

sum.png

 

picoCTF{2a4d45c7}

 

 

↓m1z0r3勉強会採用問題

New Vignere 300pt

Another slight twist on a classic, see if you can recover the flag. (Wrap with picoCTF{})

ioffdcjbfjmcifelcaloifgcjecgpgiebpfeiafhgajafkmlfcbpfbioflgcmacg  

ファイル:new_vignere.py

Hint : Vigenère cipher - Wikipedia

new_vignere.pyで定義されているb16_encode(), shift関数はNew Caesarで与えられたファイルと同じ挙動です。ただ前問と違うのはkeyの長さが15未満とあるのでbrute forceできません。

 

Vigenere暗号のKEYの長さを特定するのにカシスキーテストというのが利用されます。平文内にある単語が複数回登場しその単語を同じKEYの部分で暗号化することで、同じ暗号文になります。その同じ暗号文が登場するindexを調べることでKEYの長さの候補をある程度絞ることが出来ます。

 

今回の場合、"iof"という暗号文が2回出てきています。1~3文字目と55~57文字目が"iof"となっており、差は54です。54を素因数分解すると {1, 2, 3, 6, 9, 18, 27, 54}となり、keyの長さが15未満であるから {1, 2, 3, 6, 9} に絞ることができます。

 

keyの長さが6以下であればbrute forceできそうです。長さ6の場合、keyは16種類の文字で構成されるので16^6 ≒ 16m 程度なのでちょっと待てば行けそうです。今回flagが"abcdef0123456789"のみで構成されているので復号した際にこれと合致すればOKです。

 

(brute force中…)

 

出ない……。keyの長さは9なのか?それは求められないからkeyの長さが6まで全て試したけど出ず…。

 

カシスキーテストを言及していることから恐らくkey長は9なのだろう…。brute force出来ないので別の方法を考えます。

 

今回flagの文字が制限されているのでkeyの選び方によってはその通りに復号されません。ということは、正しく復号できるようなkeyを探すのはそんなに難しくないのでは?となりました。

 

例えば暗号文の2文字2文字"io"が正しく復号される時のkeyの候補は、{(f, i), (f, j), (f, k), (f, l), (f, m), (f, n)}です。keyの1文字目は"f"であることが確定しました。このように暗号文の2文字毎見ていき合計18文字見たところで長さ9のkeyが特定できました。

 

こんな感じ↓  最初の数字をiとすると、i*2, i*2+1文字目を正しく復号出来るのは(s, t)です、という形です。s, tは"a"を0, "p"を15としています。

0
(5, 8)
(5, 9)
(5, 10)
(5, 11)
(5, 12)
(5, 13)
1
(2, 2)
(2, 3)
(2, 4)
2
(0, 12)
(0, 13)
(0, 14)
(0, 15)
3
(6, 11)
(6, 12)
(6, 13)
(6, 14)
(6, 15)
4
(15, 4)
(15, 5)
(15, 6)
5
(9, 2)
(9, 3)
(9, 4)
(9, 5)
6
(2, 0)
(2, 1)
(2, 2)
(2, 14)
(2, 15)
7
(14, 6)
(14, 7)
(14, 8)
(14, 9)
(14, 10)
(14, 11)
(14, 12)
(14, 13)
(14, 14)
(14, 15)
8
(15, 0)
(15, 14)
(15, 15)

keyが[5, 9, 2, 2, 0, 14, 6, 15, 15]となれば上記の候補に全て当てはまるようになります(隣り合う2つのペアは必ず上に含まれています)。つまりkeyは"fjccaogpp"でした。

 

綺麗にkeyが復元されてめっちゃ気持ちよかった!!

 

picoCTF{5342d0ee1ecd51dd9e75b1e929b59da1}

 

 

solverや問題などはこちらから!

github.com

 

 

picoCTFは簡単な問題や難しいけど誘導がそれなりにされている問題、普通に難しい問題と幅広く楽しかったです! 何より解ける問題が多かったのは有難いですね。しかも得点がsolves数によって影響しない方式だったので、せっかく解いたのに得点が下がるなんてこともなくて精神的に嬉しい(笑) でもIt's Not My Fault 1を解けた時はもっと点数欲しかったなぁと…(笑)

 

何より日本人6位で嬉しかった上に解いてて楽しかったです!!ありがとうございました!

 

 

それでは!

 

 

See you next time!

 

 

 

 

 

 

 

 

 

 

 

 

ångstromCTF 2021 writeup

2021年度初のCTFはångstromCTFに参加しました。前回のpicoCTFに続き解ける問題も多いけど悩まされる良いCTFでした。全く歯が立たないというよりこちらの方が良いですね。

 

 

 

Result

 

f:id:partender810:20210408103617p:plain

総合結果

 

結果は1430ptで158位でした! まあまあ頑張れたと思います。

 

Writeup

Misc

Sanity Check 5pt

Join our discord to talk to us and get the flag (clam might even say hi)! https://discord.gg/Dduuscw

As repentance for last year, the music video will be separate and on a strict opt-in basis. https://www.youtube.com/watch?v=dQw4w9WgXcQ

とりあえずDiscordに入れと、入ったけど分からない…。

結局、rolesチャンネルにあったメッセージに:三角の旗:マークのリアクション付けるとgeneralチャンネルに入れトピックにflagが書いてありました。これに気付くのに時間がかかり、他の問題を先に解いてました。

 

actf{always_gonna_give_you_up}

 

 

Survey 5pt

Thank you for participating in our CTF! We hope you had fun. Please fill out this survey to help us improve the competition for next year. We encourage each individual that participated in the CTF to submit a response.

This challenge does not affect time-based tiebreakers.

アンケートに答えて終わりです。

 

actf{roly_poly_fish_heads_are_never_seen_drinking_cappuccino_in_italian_restaurants_with_oriental_women_yeah}

 

 

Archaic 50pt

The archaeological team at ångstromCTF has uncovered an archive from over 100 years ago! Can you read the contents?

Access the file at /problems/2021/archaic/archive.tar.gz on the shell server.

今回は問題サイトにshellがあり、その中のarchive.tar.gzを探せという問題でした。

 

cd / でrootディレクトリに移動し、該当ファイルのあるディレクトリへ移動します。そしてtar.gzを解凍して終わり、と思いきや権限が無いよと怒られる。しかしこの中にどうやらflag.txtがあるようです。

 

なんとかして解凍せずに閲覧できないかと模索したら、その方法を発見!

【Linux】tar.gzを解凍せずに中身を参照する | ばちブロ

tar -zxOf archive.tar.gz flag.txt でOKです。

 

actf{thou_hast_uncovered_ye_ol_fleg}

 

 

Fish 60pt

Oh, fish! My dinner has turned transparent again. What will I eat now that I can't eat that yummy, yummy, fish head, mmmmmm head of fish mm so good...

ファイル:fish.png 

とりあえずこの写真を開いてみます。何も見えません…。 

 

うーん、背景透過の画像かなぁ。それをどうやったら見れるんだろう。と色々ググって試してみたけど何も分からず…。

 

そういやパワポに図を貼り付ける時にオプションでやると背景透過の画像でも背景が黒色になる時あったな、パワポに貼ってみるか!

 

出た。

 

f:id:partender810:20210407230921p:plain

これが想定解とは到底思えない

 

actf{in_the_m0rning_laughing_h4ppy_fish_heads_in_th3_evening_float1ng_in_your_soup}

 

 

Crypto

Relatively Simple Algorithm 40pt

RSA strikes strikes again again!

ファイル:source.py, output.txt

 

p, qが分かっているRSAです。やるだけですね。

 

actf{old_but_still_good_well_at_least_until_quantum_computing}

 

 

Exclusive Cipher 40pt

Clam decided to return to classic cryptography and revisit the XOR cipher! Here's some hex encoded ciphertext:

ae27eb3a148c3cf031079921ea3315cd27eb7d02882bf724169921eb3a469920e07d0b883bf63c018869a5090e8868e331078a68ec2e468c2bf13b1d9a20ea0208882de12e398c2df60211852deb021f823dda35079b2dda25099f35ab7d218227e17d0a982bee7d098368f13503cd27f135039f68e62f1f9d3cea7c
The key is 5 bytes long and the flag is somewhere in the message.

これが先程の問題と同じ点数とは…難易度が違う…。

 

ciphertextは16進数でかなりの桁数で、keyは5bytesなら単純にciphertext xor keyなら上位桁は変わらないのでは?ととりあえずlong_to_bytesしてみました。まあそんなんで解けるわけないですよね。

 

keyが5bytesならbrute forceできないしなぁ…とこの5bytesに注目しました。flagが平文にあるなら "actf{" という文字列があることが分かります。つまりxorして"actf{"となる部分があるはずなので、それを逆算してkeyの候補を絞ります。例えばciphertextの1byte目は"ae"です。aeを復号すると文字"a"になるのであれば、int("ae",16)^ord("a")がkeyの1byte目になります。となると次の"27"が文字"c"になって、と考えるとkeyの候補数は高々ciphertextの長さ程度です。

 

全て試して平文の中に"}"が含まれたものを出力していくと、その中にそれっぽいのを発見しました。

 

Congratulations on decrypting the message! The flag is actf{who_needs_aes_when_you_have_xor}. Good luck on the other crypto!

 

actf{who_needs_aes_when_you_have_xor}

 

 

Keysar v2 40pt

Wow! Aplet sent me a message... he said he encrypted it with a key, but lost it. Gotta go though, I have biology homework!

ファイル:source.py, output.txt

ふむ…難しいことしているな。outputの最後の方にflagっぽい文字列があるけど、どうやって復号するのかな。

 

あれ?これただの換字式暗号では?とquipquipに投げました。便利すぎるツールですね。ちゃんと平文と暗号文のアルファベットが全単射だったので上手くいったようです。

 

according to all known laws of aviation, there is no way a bee should be able to fly. its wings are too small to get its fat little body off the ground. the bee, of course, flies anyway because bees don't care what humans think is impossible. yellow, black. yellow, black. yellow, black. yellow, black. ooh, black and yellow! let's shake it up a little. barry! breakfast is ready! coming! hang on a second. hello? barry? adam? can you believe this is happening? i can't. i'll pick you up. looking sharp. use the stairs. your father paid good money for those. sorry. i'm excited. here's the graduate. we're very proud of you, son. a perfect report card, all b's. very proud. ma! i got a thing going here. you got lint on your fuzz. ow! that's me! wave to us! we'll be in row 118,000. bye! barry, i told you, stop flying in the house! hey, adam. hey, barry. is that fuzz gel? a little. special day, graduation. never thought i'd make it. three days grade school, three days high school. those were awkward. three days college. i'm glad i took a day and hitchhiked around the hive. you did come back different. hi, barry. artie, growing a mustache? looks good. hear about frankie? yeah. you going to the funeral? no, i'm not going. everybody knows, sting someone, you die. don't waste it on a squirrel. such a hothead. i guess he could have just gotten out of the way. i love this incorporating an amusement park into our day. that's why we don't need vacations. boy, quite a bit of pomp... under the circumstances. well, adam, today we are men. we are! bee-men. amen! hallelujah! students, faculty, distinguished bees, please welcome dean buzzwell. welcome, new hive city graduating class of... ...9:15. that concludes our ceremonies. and begins your career at honex industries! will we pick ourjob today? i heard it's just orientation. heads up! here we go. keep your hands and antennas inside the tram at all times. wonder what it'll be like? a little scary. welcome to honex, a division of honesco and a part of the hexagon group. this is it! wow. wow. we know that you, as a bee, have worked your whole life to get to the point where you can work for your whole life. honey begins when our valiant pollen jocks bring the nectar to the hive. our top-secret formula is automatically color-corrected, scent-adjusted and bubble-contoured into this soothing sweet syrup with its distinctive golden glow you know as... honey! that girl was hot. she's my cousin! she is? yes, we're all cousins. right. you're right. at honex, we constantly strive to improve every aspect of bee existence. these bees are stress-testing a new helmet technology. what do you think he makes? not enough. here we have our latest advancement, the krelman. actf{keyedcaesarmorelikesubstitution}

 

actf{keyedcaesarmorelikesubstitution}

 

 

sosig 70pt

Oh man, RSA is so cool. But I don't trust the professionals, I do things MY WAY. And I'll make my encryption EXTRA secure with an extra thicc e! You'll never crack it!

ファイル:output.txt

eが大きすぎるのでWiener's Attackですね。picoCTFでも同じ問題あったのでsolverコピペしてn,e,cだけ変えて終了です。

 

partender810.hatenablog.com

 

actf{d0ggy!!!111!1}

 

 

Home Rolled Crypto 70pt

Aplet made his own block cipher! Can you break it?

nc crypto.2021.chall.actf.co 21602

ファイル:server.py

このサーバは1を選ぶと任意の平文を暗号化してくれ、2を選ぶと「この平文を暗号化せよ」と言われ10回連続でサーバでの暗号化した結果と一致すればflagを出してくれます。

 

暗号化方式をざっくり言うと、まずkeyを96の長さで生成します。前1/3をk1, 真ん中1/3をk2, 残りをk3とし、平文をm(16 bytesとします)と置くと

c <- m & k1

c <- c ^ k1

c <- c & k2

c <- c ^ k2

c <- c & k3

c <- c ^ k3

としcが暗号文となります。平文が16bytes以上の場合は区切って同じように暗号化します。keyの値が分かれば簡単に暗号化できますね。

 

これって数学的に解くのかなとandしてからのxorに法則を見つけようとしたけど無理でした。

 

でもこれってbit演算だけだからk1,k2,k3が各々0,1である場合を出してみればいけるのでは?と考えたけど、結果からkeyは特定できず…。

 

でも各bitが他のbitに影響を及ぼさないから、全てのbitに対して0だった時の暗号文と1だった時の暗号文を記憶すればいけるのでは?となりました。つまり、平文のi bit目が0だった時に暗号文のi bit目が0か1かをans[2*i]に格納し、平文のi bit目が1だった時に暗号文のi bit目が0か1かをans[2*i+1]に格納しました。

 

1を選ぶのは2回だけで良くて、"0"*32と"f"*32を暗号化した結果を上記のようなans配列に記憶します。

 

次に2を選択し暗号文を2進数にして各bitを確認しans配列を用いて暗号文を生成します。これを10回繰り返して終了です。

 

actf{no_bit_shuffling_is_trivial}

 

 

Follow the Currents 70pt

go with the flow... 

ファイル:source.py, enc

keyをまず2bytesランダムで生成し、そこからzlib.crc32というのでkeyの長さを増やします。そのkeyとflagをxorした結果がencです。

 

zlib.crc32はチェックサムを計算しているようですが、詳しいことは分かりません(笑) ただ、最初のkeyの2bytesが決まれば、その後は一意に決まります。故にその2bytesをbrute forceしてkeyを作ってencとxorして、"actf"の文字列が含まれるのを出力して終わりです。

 

there are like 30 minutes left before the ctf starts so i have no idea what to put here other than the flag which is actf{low_entropy_keystream}

 

actf{low_entropy_keystream}

 

 

I'm so Random 100pt

Aplet's quirky and unique so he made my own PRNG! It's not like the other PRNGs, its absolutely unbreakable!

nc crypto.2021.chall.actf.co 21600

ファイル:server.py

第一にserver.pyについて、r1, r2(10進数でちょうど8桁)がこの乱数発生プログラムのseedになります。serverに"r"を送ると、getNum関数にて乱数を発生してくれます。r1の値を二乗すると16桁になります。その真ん中の8桁がr1(.seed)になります。r2についても同様です。そして、r1*r2を出力します。これは3回までやってくれます。

 

解法としては、r1*r2を素因数分解して8桁*8桁の形にします。自分はその作業が面倒だったので、素因数分解した際に片方が8桁の素数になるまでサーバとつなぎ直していました。

 

r1, r2が決まれば16桁の自然数の内真ん中8桁がr1(もしくはr2)となる平方数をbrute forceします(もっといい方法があるかも?)。gmpy2.irootで平方数かどうかチェックします。8桁をbrute forceするのでかなりの時間がかかりますが、サーバのコネクションは切れずに待っててくれます。

 

真ん中8桁がr1となる16桁の平方数はいくつか候補が出てきますが、次に乱数を発生した際にr1*r2の形なので、割り切れる候補が正しいr1の最初のseedになります。最初のseedが分かれば、次の乱数を予想するのは容易です。

 

最後に2回連続次の乱数を予想して当てればflagをくれます。

 

actf{middle_square_method_more_like_middle_fail_method}

 

 

Substitution 130pt

nc crypto.2021.chall.actf.co 21601

ファイル:server.py

これは個人的に物議をかm...失礼いたしました。

 

まずserver.pyの挙動の理解に時間がかかりました。flagのASCIIコードをm[0],m[1],...,m[n-1]とすると、valueが入力の値でlambda式とreduceを使って、

m[0]*pow(value,n-1) + m[1]*pow(value,n-2) + ... + m[n-2]*pow(value,1) + m[n-1] mod 691

を計算し出力してくれます。

 

ここからが長かった…。valueを0とすると125が返ってきてm[n-1]に該当します。chrすると"}"となるのでflagの最後の文字ということが分かります。ではここからどう他の文字を特定するのでしょう…。

 

こんな数学的な問題を扱うのは久しぶりな上、どうあがいても式が立てられない…。ググっても分からない…。

 

数学が得意そうなm1z0r3メンバーのAtCoder黄色ランク(上位数%)の凄腕に聞いてみました。

 

「それはラグランジュ補間をやるだけですね。」

 

なんだそれは。わざわざ解説記事も教えてくれたのに理解できないポンコツに成り下がり…。AtCoderでも全く同じ問題が出てたので、それをACしてた彼のソースコードをコピペして終了!

 

Submission #10506051 - AtCoder Beginner Contest 137

 

彼にこの問題の難易度聞くと、彼レベルでないと解けない程だと…。緑coderの僕には無理な話でした!なのになんで3桁solvesもあるの!?みんなプログラムスキルが高いのかググり力が高いのか…。

 

期間終盤でみんなが停滞している中、この問題correctになったことで1000pt台に乗ったのは嬉しかったです!

 

actf{polynomials_20a829322766642530cf69}

 

 

Oracle of Blair 160pt 

Not to be confused with the ORACLE of Blair. 

nc crypto.2021.chall.actf.co 21112

ファイル:server.py

出ました苦手なAES問題…。でも自力で解けたの本当に嬉しい!

m1z0r3の方、この問題勉強会で使うのであまり見ないよう…

 

このサーバは第一にkeyを32bytesランダムに決めます。次にwhile文に入り、入力をunhexlifyして、その結果"{}"が含まれていたらflagにreplaceしてくれます。7b7dを入力するとb"{}"になります。次に長さが16の倍数になるようpadしてivをランダムに決めます。そしてkeyとivを用いてAESのCBCモードでdecryptして出力します。

 

CBCモードと言ったらpadding oracle attackですよね。でも今回はpaddingを勝手にしてくれるので使えません。

 

そしてdecryptしてくれるのに全然気付かず、ずっとencryptを見ていました。

 

f:id:partender810:20210408004329p:plain

AES CBC decrypt

 

ここで、7b7dを送った時の返ってきた16進数と7b7d+"07"*7を送った時の返ってきた16進数の後半半分が一致していることが試して分かりました。その16進数の桁数の結果も踏まえて、flagの長さが25bytesということが分かりました。

 

上の図でCiphertextを左からc1, c2, c3 Plaintextをp1, p2, p3とすると、

p3 = enc(c3) xor c2

となります。ここでenc()とはkeyによって暗号化された値です。このサーバを使うとc2, c3は自分で決められp3は与えられることからenc(c3)を求めることができます。なぜenc(c3)を求めたいかというと、ここが分かると欲しいc2の値が分かります。

 

c2, c3は全て0としてenc(c3)を求めます。その後、7b7d + "07"*7 + "00"*16を送り付けます。c1, c2はflagとpaddingが該当し、c3は"00"*16です。enc("00"*16)は先程求めたので、貰った復号16進数の後ろ1/3がp3に該当するのを使うと

c2 = enc(c3) xor p3

とc2が求まり、long_to_bytesするとflagの後ろの部分とpaddingが見えました。

 

同じようにenc(c2)を求めます。c1 = "00"*16として送るとp2に該当する部分を利用し

enc(c2) = c1 xor p2 

 で求まります。その後、7b7d + "07"*7 + "00"*16を送り、

c1 = enc(c2) xor p2

でc1が求まり、flagの前半部分が分かりました。

 

これできたの本当に気持ち良かったです!苦手分野であるだけに喜びもひとしおです!

でもアメリカ大統領選挙のようなURLが問題文にあったのなんでだろう。

 

actf{cbc_more_like_ecb_c}

 

 

solverや問題はこちらから!

github.com

 

 

前回のpicoCTFに続いて(まだwriteupは公開で来てませんが)、結構crypto問題を解けたと思います(個人比)。3桁solvesのものをほとんど解けるようになったのは嬉しいなぁ。m1z0r3がもっと有名になると嬉しいですね!

 

それでは!

 

See you next time!

 

 

留学期間を終えて

こんにちは!Ken.Sです!

 

 

ついに…1年間の(オンラインがほとんどの)留学が終了しました!!

 

毎週研究室全体のミーティング、教授とは1,2週間に1度のペース、そして早稲田の方の研究室のゼミ(日本語, 英語)2つに参加させてもらい、50近くのパワポ資料作成を経て1つの論文を書き上げることが出来ました。

 

今回は、研究後記という形で書いていこうと思います。

 

 

留学前はブロックチェーンを使ってより公平なゲームを作ることができるのか?というResearch Questionで一年半研究してました。ブロックチェーンの改ざん不可能性の利用して、チートのできないブロックチェーンゲームを提案しました。ブロックチェーンを知らない方にとっては、いったい何の話だとなることでしょう…(笑) 

ブロックチェーン:暗号資産(仮想通貨)の取引を記録する技術

 

 

その後留学するためのTOEFLの対策で半年を費やし、去年の3月にアメリカへ出発しました。

 

 

アメリカに来てからは、どのようなゲームにブロックチェーンを取り入れると自分が提案したものよりさらにメリットの大きいものができるのか、を考えていきました。今あるオンラインゲームにおける潜在的な問題をブロックチェーンで解決できればいいな、といった感じでサーベイをしていました。特にブロックチェーンは取引に特化した技術だと思っているので、この特徴で解決できそうな問題を探していました。

 

そこで一つ見つけたのが、「ガチャ、ギャンブルではないか問題」。

ガチャは、ゲーム内通貨(魔法石etc)を払って、ゲーム内アイテム(SRキャラとかそんなやつ)を手に入れます。ゲーム内通貨はリアルマネーを払って手に入れることもできるのに対し、貰えるゲーム内アイテムの価値は毎回バラバラです。日本では改正資金決済法で言及されており、実際に「コンプリートガチャ」というものはユーザーの射幸心を煽りすぎるということで禁止されました。

 

アメリカ在住時の細かい話はこちらをどうぞ!

アメリカ留学始まってバタバタした話 - Attack All Around

第一回チキチキ!強制帰国レース - Attack All Around

I'll be back. - Attack All Around

 

自分でも見返してみたのですが、現地生活を事細かに書いててびっくりしてます(笑) この貴重な1ヶ月の気持ちを思い出すことができたので、ブログを書いててよかったなと思います。

 

 

帰国後2週間はこのように過ごしていました。この頃から自炊を手伝うようになり、今でもちょくちょく手伝っております。料理できる男子になりたいなと…。

2週間の自宅隔離の過ごし方。意識だけは高い大学院生の場合 - Attack All Around

 

 

日本に帰ってきてからは、ソーシャルゲームの問題や歴史、なぜ人はソシャゲにハマるのかなど調べていったのですが、色んな過程を経て既存のブロックチェーンゲームであるCryptoKittiesに注目しました。この時点でもう5,6月でした。

 

私生活の方では、トビタテの人達とひたすらオンラインで話してました。zoomで毎週のように話したりインスタライブをやってみたりオンライン脱出ゲームをやったり、自粛生活の中でも人と話す機会が多くて精神的にも助かっていました。トビタテのみんなありがとう!

 

 

夏にはソースコードを読み込んでデータをクローリングして公平性に欠けてるのでは?と気付き、そこを重点的に調べていきました。金融市場の公平性など色々サーベイしてたら半年かかり気付いたら冬。時間はかかりましたが、その分論文が書けるような成果がしっかりと出て良かったです。

 

夏休み期間になると週1で早稲田の研究室生とオンライン上で遊んでいました。人狼, Among us, boardgamearena, etc. この週1でも色んな人と話すというのが自分にとって本当にプラスに働いていました。研究でネガティブになっても、話せば晴れることが多くて気持ちを切り替えられました。

 

夏休みが明けても同様に遊んでいて、研究以外にも就活のストレスもあったので、いいリフレッシュになっていました。年末になると卒論修論学会などで研究室生も忙しくなりなかなか集まれなかったので、ドラクエⅣをアプリで遊んでいました。ゲームはいい気分転換になりました、やりすぎないようにするので大変でした(笑) 今はドラクエⅦをやり込んでます!なかなか進まない…。

 

 

12月に研究成果を論文にして、なんとか2月初旬の提出に間に合いました。

2月下旬に採択されたと知った時はこの研究だけでなく、2年半前に留学を決意した時から今までの過程までもが認められたような気がして、本当に嬉しかったです!!!

 

採択からは発表に向けた資料を作っていました。発表時間が短く、時間内に収めるのが本当に難しかったです。それに加えて英語での発表…。本番は緊張がすごかったですね(笑) 発表はともかく質問された時に何言ってるか理解できずに困惑してました…。

 

改めてこの一年を書いてみたら、色々紆余曲折があったなと思います。研究が一筋縄ではいかないことも含めて良い経験になりました。

 

コロナ禍で研究するための時間を確保するの比較的簡単かと思うのですが、家での作業が増える分OFFへのスイッチが難しいと感じました。そのスイッチが私は上手く働いてくれたので、今回の採択に繋がったのかなと思います。4月からはまた大学院生に戻りますが、今後とも切り替えを大事にして良い成果をあげたいなと思います。

 

f:id:partender810:20210331110712p:plain

去年の帰国後、一番見たかったのは日本の桜。今年も綺麗ですね。



 

 

 

改めまして、この一年私と関わってくださりました全ての方に御礼申し上げます。

 

それでは!

 

 

See you next time!

 

 

 

 

 

 

 

 

 

 

 

 

 

utctf 2021 writeup

こんにちは!Ken.Sです!

今回はutctfのwriteupです

 

UTCTF

 

m1z0r3は9779ptで72位でした

 

 

 

Beginner

 

Cipher Gauntlet

Can you make it through all of the encodings and ciphers?

ファイル:secret.txt 

 

中を見ると8bitの整数がたくさんあるので、まあASCIIだろうとchrしてみる。

 

そうすると以下のような文章が!

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.)
TmV3IGNoYWxsZW5nZSEgQ2FuIHlvdSBmaWd1cmUgb3V0IHdoYXQncyBnb2luZyBvbiBoZXJlPyBJdCBsb29rcyBsaWtlIHRoZSBsZXR0ZXJzIGFyZSBzaGlmdGVkIGJ5IHNvbWUgY29uc3RhbnQuIChoaW50OiB5b3UgbWlnaHQgd2FudCB0byBzdGFydCBsb29raW5nIHVwIFJvbWFuIHBlb3BsZSkuCm15eHFia2Rldmtkc3l4YyEgaXllIHJrZm8gcHN4c2Nyb24gZHJvIGxvcXN4eG9iIG1iaXpkeXFia3pyaSBtcmt2dm94cW8uIHJvYm8gc2MgayBwdmtxIHB5YiBrdnYgaXllYiBya2JuIG9wcHliZGM6IGVkcHZrcXt4eWdfaXllYm9fenZraXN4cV9nc2RyX21iaXpkeX0uIGl5ZSBnc3Z2IHBzeG4gZHJrZCBrIHZ5ZCB5cCBtYml6ZHlxYmt6cmkgc2MgbGVzdm5zeHEgeXBwIGRyc2MgY3liZCB5cCBsa2NzbSB1eHlndm9ucW8sIGt4biBzZCBib2t2dmkgc2MgeHlkIGN5IGxrbiBrcGRvYiBrdnYuIHJ5em8gaXllIG94dHlpb24gZHJvIG1ya3Z2b3hxbyE=

 

後半は明らかに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).
myxqbkdevkdsyxc! iye rkfo psxscron dro loqsxxob mbizdyqbkzri mrkvvoxqo. robo sc k pvkq pyb kvv iyeb rkbn oppybdc: edpvkq{xyg_iyebo_zvkisxq_gsdr_mbizdy}. iye gsvv psxn drkd k vyd yp mbizdyqbkzri sc lesvnsxq ypp drsc cybd yp lkcsm uxygvonqo, kxn sd bokvvi sc xyd cy lkn kpdob kvv. ryzo iye oxtyion dro mrkvvoxqo!

 

rot13ぽい文章が出てきました。途中にはflagがありそうですし、最初の単語はcongratulations! のようですね。

 

rot13しても文章にならない…。最初の文字がzになったのでもう3つシフトしてみたら(つまり上記の文をrot16したら)flagがでました。

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

 

utflag{now_youre_playing_with_crypto}

 

Sizzling Bacon

My buddy Francis is really into Bacon. He loves it so much that he gave me this encoded bacon-themed flag (he said he was inspired by the sound of sizzling bacon).

sSsSSsSSssSSsSsSsSssSSSSSSSssS{SSSsSsSSSsSsSSSsSSsSSssssssSSSSSSSsSSSSSSSSsSSsssSSssSsSSSsSSsSSSSssssSSsssSSsSSsSSSs}

 

とりあえず{}が見えるので換字暗号だろうと予想。{の文字の前には30文字あり今回のフォーマットはutflagなので、暗号文5文字が平文1文字になるのだろう。暗号文を5文字区切りで見たら平文aに該当しそうな暗号文21~25文字目がSSSSSでした。Sが0でsが1となる2進数でord('a')+(その2進数)とすれば解けるのでは?となりました。f,gに該当する部分もこの考え方で齟齬はありませんでした。あとはこれに沿って復号します。

 

それにしてもなぜベーコン?ベーコンを炒める音でこの暗号を思いついたのはなぜ?

追記:こんな暗号があるんですね 

Bacon's cipher - Wikipedia

 

utflag{crispybaconcipher}

 

 

Various Vernacular

This flag was intercepted. wmysau{foeim_Tfusoli}

Unfortunately, it seems to be encrypted. Additional encrypted text was also found.
Hkgxologflutleiaymt xgf Azutgkrftmtf ltmntf ERW wfr ELW wfmtk Rkweq.

 

HINT : The plaintext may not necessarily be in English. 

 

とりあえずwmysauがutflagなるんだろう。その後は???って感じでした。これが本当にbeginnerか?

ヒントを見ると英文が暗号化されたわけではなさそうなところが、さらに突き放された気分…。

 

換字式暗号だろうということから、なんとかquipquipというものがあることを思い出し、Cluesにwmysau=utflagと入れたらドイツ語の文章が出てきました(出てきた文をDeepLに入れて判明)。英語以外もやってくれるとかquipquipしゅごい。

https://www.quipqiup.com/

あとは辞書を作って完成です。

 

utflag{nicht_English}

 

 

Cryptography

 

Small P Problem

My buddies Whitfield and Martin were trying to share a secret key between themselves, and I was able to eavesdrop on their conversation. I bet I could probably figure out their shared secret with a little math...

p = 69691
g = 1001

A = 17016
B = 47643
Note: submit either the shared secret or the shared secret wrapped in utflag{}

 

うーん、これはなんだろう。gとpがあるのでElGamalっぽくy=pow(g,x,p)でyがA,Bに該当するんだろうととりあえずxを計算してみたらA,Bともに出てきました。

A = pow(g,12552,p),

B = pow(g,7919,p)

 

さてここからが分からない。秘密鍵ってこの12552と7919じゃないのか?utflag{125527919}と提出してもincorrectでした。

 

ここで少しうなって時間かけて、とりあえず上の2問を先に解きました。

 

自分が知らない暗号方式があるのでは?と、「暗号 g p A B」でググる初心者振り。そしたらDiffie-Hellman鍵共有を見つけてこれだ!!となりました。

www.slideshare.net

知ってました、知ってたんですけどね…。というかあんなググり方でヒットする検索エンジンすごい。

秘密鍵 = pow(g, 12552*7919, p) = 53919

 

utflag{53919}

 

illegal Prime

The NSA published the ciphertext from a one-time-pad. Since breaking one-time-pad is so easy, I did it for you.

To avoid legal trouble I can't tell you the key. On an unrelated note I found this really cool prime number.

ファイル:challenge.txt

まずillegal primeってなんだ?ところから入りました。

illegal primeとは、機密情報を含む素数のことです。例えば、100...00(電話番号10桁)00...01のような素数があったとして、私はこんな素数を見つけました!とその素数を公開します。その電話番号を持つ人にとっては迷惑な話です。電話番号以外にも機密情報を公開するのは違法ですが、素数として公開すれば法をかいくぐることができますねというお話です。

この記事が分かりやすくてオススメです。

違法素数を小学生でもわかるように例えで説明する | 数学の星

 

ということで、challenge.txtのpに情報が隠されているのだろうと踏んで探してみました。結果、long_to_bytes()したらkeyらしきものが見えました。

b'k = 5a0b05d9831438ac8561d2b0a42be1cf5613db21deb9a443e21c4d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f'

このkと与えられたcをどうしたらいいのかで悩み、中断…。k+cとかk-cとか考えてました。この記事のせいだ。

Physical One-time Pad

 

結局kとcのxorをlong_to_bytesでOKでした。悔しい。

 

utflag{pr1m3_cr1m3s____!!!}

 

 

Forensics

 

SHIFT

I just tried to download this flag, but it looks like the image got messed up in transit...

ファイル:SHIFT.png

解いてる人が多いのとPNGファイルの扱いが苦手なのでやってみました。

 

画像を見ると、文字が斜めになっていそうな感じです。画像の幅や高さを変えたらできるのかな?とか思っていました。

 

結局PILの使い方を先輩に教えてもらって、ピクセルを上手くずらすことができました。

画像の下の部分にいくにつれてよりずらすことで、斜めになった文字を直せました。

f:id:partender810:20210313161555p:plain

結果

utflag{not_when_i_shift_into_maximum_overdrive}

 

OSINT part2

Find the origins of the linked file found in part 1. 

HINT : Downloading and uploading the file might give more straight forward results

HINT : The solution involves an everyday tool used to find things.

 

とりあえずpart1はチームメイトが解いてたので、それを基にやってみました。part1のflagはある方のツイートにあったとのことで、それを見に行きました。すると、そのツイートに対してリプライがあり、画像ファイルがありました。問題文よりこの画像ファイルを発信源を探すのだろうと、画像検索。そしたら一発でした。

 

Tobias Maier

 

utflag{r3v3rs3d_t0_0r1g1nal}

 

solverなどはこちらです!

GitHub - ksbowler/UTCTF2021

 

次はLINE CTFに参加しようと思います!

それでは!

 

See you next time!

 

zer0pts CTF 2021 writeup

こんにちは、Ken.Sです!

 

久しぶりにCTFのwriteupです。今年初めて書くので拙い文章なのはご了承ください…。

 

https://2021.ctf.zer0pts.com/index.html#/

 

 

Crypto

 

war(sa)mup

Do you know RSA? I know.
author:theoldmoon0602
warsamup_05d9e1f890f75cc7aadf145af49fddbb.tar.gz

 

とりあえず中を覗いて見ると、平文mを色々パディングしておりそれをm'とすると、公開鍵に加えm'を暗号化したものとm'//2を暗号化したものを与えられています。

m'を2で割ったものは上位ビットが同じだからFranklin-Reiter Related Message Attackができるのでは?とチームメイトが発見。ここで私は起床しました。昨日は朝3時に論文発表していたんです。近日その模様が公開されるので乞うご期待!

 

そのチームメイトがこのサイトを使えばいけるのでは?となり早速読んでみる

Crypton/exploit.sage at master · ashutosh1206/Crypton · GitHub

 

そもそもこの攻撃をよく知らないのでここらでお勉強。

SageMathを使ってCoppersmith's Attackをやってみる - ももいろテクノロジー

InterKosenCTF 2020 - padrsa - HackMD

 

今回m1は平文をパディングしたもの、m2はm1//2となっています。

つまり、m1 = 2*m2 or m = 2*m2+1と上記サイトのa,bが分かります。Xornetさんのwriteupより考えると、

 

g2(x) = (x)^e - c2 = 0 mod n -> g2(x) = (x-m2)h2(x) mod n

g1(x) = (2*x)^e - c1 = 0 mod n もしくは

g1(x) = (2*x+1)^e - c1 = 0 mod n

-> g1(x) = (x-m2)h1(x) mod n

 

となります。h1(x),h2(x)はsageにぶん投げて求めてもらいます。

 

そして、先程載せたgithubのコードをsagemathにぶん投げます。

output.txtをコピペしてパラメータを定義し、このように実行します。

franklinreiter(c1,c2,e,n,2,1)

resultをそのまま表示させて、あとはpythonで2倍して1加えたものをlong_to_bytesすればflagが出てきました。

 

ほとんどコードを丸パクリしただけなので、写真でご勘弁…。

f:id:partender810:20210306133943p:plain

 

zer0pts{y0u_g07_47_13457_0v3r_1_p0in7}

 

他にも、easy pseudo random や janken vs yoshiking などを解いたんですけど歯が立たず…。公式writeupはこちらです。

 

hackmd.io

 

それでは!

 

See you next time!

「水曜どうでしょう」は全ての都道府県を訪れているのか?

こんにちは!Ken.Sです!

 

留学から帰国しステイホームが続いている中、契約しているNetflixで見つけハマった「水曜どうでしょう」。今回はそのどうでしょうについて語りたいと思います!どうでしょう知らない方は是非この記事の前に実物を見てください!

 

 

~ルール~

・サイコロや絵ハガキの旅は目的地をカウント(新幹線などで通過した県は除く)

・カブ企画は通過した県もカウント

対決列島は鹿児島決戦までに繰り越した県はカウントしない

・泊まった都道府県はカウント

・他は車など乗り物から降りて撮影してたらカウント(深夜バスでのSAは除く)

 

 

下の図は、初めてその都道府県を訪れた時の企画(略称)を記してます!

 

f:id:partender810:20210210000805p:plain

都道府県制覇(?)

 

都道府県制覇してました!!

 

怪しいとことしては千葉県、山梨県佐賀県…。

 

千葉県は成田空港があるので経由では何回も訪れているでしょう!

山梨県対決列島で通過しただけなので、本当に微妙です…。他の企画でも経由で訪れたことはなさそう? SAであれば深夜バスの時に訪れているかもですね。

佐賀県はサイコロ3でハウステンボス訪れた際の経由で鳥栖駅などで訪れていますね。

 

 

いずれ山梨県に注目した(?)企画が出ると良いですね!

ここ違うよ、とかあればコメントください!

 

 

それでは!

 

See you next time!

 

 

 

 

「米」

こんにちは! Ken.Sです!

 

2020年も残すところあと一日となりました。多くの人がそうであったように、私も今年は激動の一年となりました。初めて経験したことや新しく始めたことが多かった2020年、ありきたりではありますが振り返りたいと思います。

 

f:id:partender810:20200323000025p:plain

ここにいたはずの場所

 

今回のタイトルの「米」。これは、個人的今年の漢字です。

  • 米国に留学した
  • 米国の米が合わず、帰国したら日本の米のおいしさに感動し、高校からほとんど変わらなかった体重が激変した。
  • 「八十八」種類と言っていいくらいの経験と、「八十八」ほど成長をすることができた。

 

特に三点目が私の今年を象徴しています。今年は本当に多くの事を経験しました。先にも書いた「初めて経験したことや新しく始めたこと」を軸に思い返してみます。

 

毎年年末年始で忙しかったことはなかったのですが、去年から今年にかけては留学受入のためにTOEFL受験対策でひたすら英語を勉強した年越しとなりました。年明けすぐに受験した回で何とか達成しました!勉強してた半年は長~~く感じましたが、これで留学へのスタートラインに立ててほっとしました。

 

 

  • 留学&一人暮らし 3月

この一ヶ月は辛くも貴重な経験をできた一ヶ月でした。今まで一ヶ月の間一人で過ごした経験はなく、特に海外でというのはしんどかったです(笑)

 

研究を進める、というのは日本とアメリカでやる場所が違うだけでした。が、一人でなく研究室で研究するとなると、言語の壁を大きく感じました。いくらTOEFLで勉強したとはいえ実践となると難しいものがありました(笑) 今もその壁は感じますが、大変な思いをすればするほど深い経験になると思っているので、苦労したいと思います!

 

もう一つの一人暮らしについてですが、これがつらかった…。言語の壁もそうですし、食生活も変わりました。奨学金が多いわけではないので、貧乏生活でした…。自炊も初めての経験で、どういったものが必要で保存の仕方はどうでetc...はほとんど知らず、googleのある時代に生まれて本当に良かった!! 

 

ただ、経験の無さが如実に現れており…。朝はコーンフレーク、昼はサラダのみ、夜は冷凍食品のサイクルで、料理と言ってもキャベツを角切りする程度でした(笑)  味に飽きたということはあまりなかったのですが、色んなのを作れる技量があったらどれだけよかったことか… 買い物にも立地がそこまで良くはなく、坂の上り下りがつらかったです。

 

アメリカでやりたかったことはほとんど叶えられず仕舞いでしたが、経験値としては良いものを得られたと思います。

 

 

  • オンライン留学&お金をもらって研究するということ 4月~

日本に戻ってからは、多くのトビタテ生と交流したり日本のご飯を堪能したりであまりネガティブにはならなかったです。むしろ、年々新しく交流する方は減っていく一方で、同世代でしかも同じ留学を考えていた方達と携わることができたのはこの一年で一番良かったことです。

 

研究としては、またしても場所が変わっただけといった感じで悪影響はなかったです。

 

いつもと違うのは、奨学金をもらってオンラインで留学を続けるということです。研究のモチベーションにもなりますし、責任感も芽生えます。身を引き締めて留学を続けたいと思います!

 

 

  • 料理 4月~

アメリカでの食生活の反省から、次行けるようになった時にはもう少し作れるように…と始めた料理ですが、モチベーションは段々下がっており(笑) いずれは一人暮らしをするはずなので、ちゃんと勉強したいと思います。

 

 

研究の息抜きに、と好きだったプログラミングをちゃんと勉強しだしました。のほほんと3月まではやっていたのですが、4月に弊研究室に大物が現れて…。上位数%に該当するレベルの方で、もはや先生ですね。教わりながらどんどんモチベーションが上がっていき…ランクが上がるのに爽快感を得ながら続けています!

 

 

  • CTF本格始動 5月~

こちらも息抜きです(笑) 4月から今日まで、研究競プロCTFの3つしかやってないですね(笑) こちらはコンピュータセキュリティコンテストで、主に暗号問題を解いています。簡単に言うとちゃんと暗号化してデータを扱ってないから元通りに復号できちゃうよ頑張れ、って感じです。これも楽しいんですよね!

 

研究室に配属してから研究室での勉強会は参加していたのですが、ちゃんとコンテストに参加するのは今年からです。今まではボウリングやTOEFLで参加できず…だったのですがもったいないなって思ってます(笑)

 

 

  • ブログ 1月~

最後に今年始めたものとして、このブログがあります。思ったことを軸に、最近はCTFのwriteupや数学で面白かった問題などを紹介してます。書いていて多くの方に読んでいただきアクセス数が多いと嬉しいですし、また他の方のブログで紹介された時は格別でした!今後も続けていきますので、これからもご拝読お願いします!

 

 

新しい経験を基に2020年を振り返ってみました。去年も大変でしたが、今年はそれを上回る一年となりました。しかし多くの事を経験できたのは、今年の一番の良かったことだと思っています。来年もいつまでステイホームが続くか分かりませんが、家にいながら自分の成長に繋がることを続けていけたらなと思います!

 

 

それでは!良いお年を!

 

 

See you next year!