読者です 読者をやめる 読者になる 読者になる

ブログの名前なんて適当で良いのでは

説明を求めるな、記事を読め

Internetwache CTF 2016のwriteupと感想

新たに某プロをお二方加えたチームで参戦した初のCTFで,とてもワクワクしていました.前回の反省点である問題を全部見なかったということはできました.(正確には誰かが解き始めてたやつは見なかった).今回もやるだけ問題でしたがなんとか4つフラグをサブミットできたのでそれのwriteupを書きました.Misc60, Crypto60, Rev50, Rev80の4つで合計250pt貢献したのとcrypto50のちょっとした補佐(それbase32じゃね?ってだけの発言)をしました.

Oh Bob![Crypto60]

Description: Alice wants to send Bob a confidential message. They both remember the crypto lecture about RSA. So Bob uses openssl to create key pairs. Finally, Alice encrypts the message with Bob's public keys and sends it to Bob. Clever Eve was able to intercept it. Can you help Eve to decrypt the message?
Attachment: crypto60.zip

とりあえず問題文は英語で読めないので(?),zip解凍するとこんなかんじ.

crypto60@ls
bob  bob2  bobo3  secret.enc

bobたちの中身を覗くと,

-----BEGIN PUBLIC KEY-----
MDgwDQYJKoZIhvcNAQEBBQADJwAwJAIdDVZLl4+dIzUElY7ti3RDcyge0UGLKfHs
+oCT2M8CAwEAAQ==
-----END PUBLIC KEY-----

secret.encの中身をのぞくと,

DK9dt2MTybMqRz/N2RUMq2qauvqFIOnQ89mLjXY=

AK/WPYsK5ECFsupuW98bCFKYUApgrQ6LTcm3KxY=

CiLSeTUCCKkyNf8NVnifGKKS2FJ7VnWKnEdygXY=

Base64エンコードされた文が3個ある.よってそれぞれの公開鍵で暗号化されてるんだなぁと思ったので, 秘密鍵を作成しようとした.そこで公開鍵の中身をopenssl使ってみてみると,Nがあまり大きくないことに気づいた.そこでpari/gpに投げてほっておくと素因数分解に成功していたので,その情報をもとに秘密鍵を作成してsecret.encの全文をそれぞれ復号するとフラグが出た.

FLAG: IW{WEAK_RSA_K3YS_4R3_SO_BAD!} やるだけ

Quick Run[Misc60]

Description: Someone sent me a file with white and black rectangles. I don't know how to read it. Can you help me?
Attachment: misc60.zip

zipファイルの中にやたらと長いREADME.txtがあり,Base64っぽかったのでデコードすると大量のQRコードが出てきた.QRコード問を解いたことのない私は,「あぁ..解けねぇ..」と思ったけど,とりあえず読み取ってみたらフラグでた.

FLAG: IW{QR_CODES_RUL3}

SPIM[Rev50]

Description: My friend keeps telling me, that real hackers speak assembly fluently. Are you a real hacker? Decode this string: "IVyN5U3X)ZUMYCs"
Attachment: rev50.zip

zipファイルの中身をみてみるとこんな感じ.

User Text Segment [00400000]..[00440000]
[00400000] 8fa40000  lw $4, 0($29)            ; 183: lw $a0 0($sp) # argc
[00400004] 27a50004  addiu $5, $29, 4         ; 184: addiu $a1 $sp 4 # argv
[00400008] 24a60004  addiu $6, $5, 4          ; 185: addiu $a2 $a1 4 # envp
[0040000c] 00041080  sll $2, $4, 2            ; 186: sll $v0 $a0 2
[00400010] 00c23021  addu $6, $6, $2          ; 187: addu $a2 $a2 $v0
[00400014] 0c100009  jal 0x00400024 [main]    ; 188: jal main
[00400018] 00000000  nop                      ; 189: nop
[0040001c] 3402000a  ori $2, $0, 10           ; 191: li $v0 10
[00400020] 0000000c  syscall                  ; 192: syscall # syscall 10 (exit)
[00400024] 3c081001  lui $8, 4097 [flag]      ; 7: la $t0, flag
[00400028] 00004821  addu $9, $0, $0          ; 8: move $t1, $0
[0040002c] 3401000f  ori $1, $0, 15           ; 11: sgt $t2, $t1, 15
[00400030] 0029502a  slt $10, $1, $9
[00400034] 34010001  ori $1, $0, 1            ; 12: beq $t2, 1, exit
[00400038] 102a0007  beq $1, $10, 28 [exit-0x00400038]
[0040003c] 01095020  add $10, $8, $9          ; 14: add $t2, $t0, $t1
[00400040] 81440000  lb $4, 0($10)            ; 15: lb $a0, ($t2)
[00400044] 00892026  xor $4, $4, $9           ; 16: xor $a0, $a0, $t1
[00400048] a1440000  sb $4, 0($10)            ; 17: sb $a0, 0($t2)
[0040004c] 21290001  addi $9, $9, 1           ; 19: add $t1, $t1, 1
[00400050] 0810000b  j 0x0040002c [for]       ; 20: j for
[00400054] 00082021  addu $4, $0, $8          ; 24: move $a0, $t0
[00400058] 0c100019  jal 0x00400064 [printstring]; 25: jal printstring
[0040005c] 3402000a  ori $2, $0, 10           ; 26: li $v0, 10
[00400060] 0000000c  syscall                  ; 27: syscall
[00400064] 34020004  ori $2, $0, 4            ; 30: li $v0, 4
[00400068] 0000000c  syscall                  ; 31: syscall
[0040006c] 03e00008  jr $31                   ; 32: jr $ra

あっ,MIPSだ,わかんない,読んだことない

チーム内slackにて...

某プロ「MIPSはちひろプロにお願いしよう」

ア => 頑張って読み始めた => い,意外と読める!! 上のMIPSコードを擬似言語的に表したのが以下.

string flag = "IW{Here's Flag}";
int t1;
for(t1 = 0; t1 < 15; ++t1){  
    printstring("%c", flag[t1] ^ t1);
}
exit(1);

したがってflagの文字列をn番目の文字はnでXORしているだけとわかるので以下 Solver.

"IVyN5U3X)ZUMYCs".split("").each_with_index do |c, i|
  print (c.ord ^ i).chr
end

FLAG: IW{M1P5_!S_FUN}

Eso Tape[Rev80]

Description: I once took a nap on my keyboard. I dreamed of a brand new language, but I could not decipher it nor get its meaning. Can you help me? Hint: Replace the spaces with either '{' or '}' in the solution. Hint: Interpreters don't help. Operations write to the current index.
Attachment: rev80.zip

zipファイルの中身をみるとpriner.tbというファイルがあり,BF系言語だなぁって思いながら調べてると発見した.

## %% %++ %++ %++ %# *&* @** %# **&* ***-* ***-* %++ %++ @*** *-* @*** @** *+** @*** ***+* @*** **+** ***+* %++ @*** #% %% %++ %++ %++ %++ @* %# %++ %++ %++ %% *&** @* @*** *-** @* %# %++ @** *-** *-** **-*** **-*** **-*** @** @*** #% %% %++ %++ %++ %++ %# *+** %++ @** @* %# *+** @*** ## %% @***

この記号列は, TapeBagelと呼ばれるBrainFuck系言語だということがわかった. 主な文法は以下の通り(https://esolangs.org/wiki/TapeBagel) 概要としては配列[0]~[2]とindex変数を用いて値を格納し, その値を出力に使うという文法.出力には, '@' + offsetという形式で, offset = 1ならば'A'が出力される.(ascii表みればわかる).したがって元の記号列を'@*'などで改行して整形し1文ずつ解析した.

今回使った命令の動作内容を以下に示す.

  • * => 0
  • ** => 1
  • *** => 2
  • %% => index = 0
  • %# => index += 1
  • #% => [0] = [1] = [2] = 1
  • ## => [0] = [1] = [2] = 0
  • %++ => [index] += 1
  • @ => print [len(の数)]
  • + => [index] = [左辺] + [右辺]
  • - => [index] = [左辺] - [右辺]
  • & => [index] = [左辺] * [右辺]

注意点 ネット上に転がってるInterprinterだと+などの命令の代入先が, [左辺]になっている([左辺] = [右辺] + [左辺]みたいな)ので注意.これは,"Hint: Interpreters don’t help. Operations write to the current index."から推測した)

参考として一文解析する

## %% %++ %++ %++ %# *&* @** => I

##より[0] = [1] = [2] = 0
%%よりindex = 0
%++より[index] += 1を3回して[0] = 3
%#よりindex += 1をしてindex = 1
*&*より[index] = [0] * [0] = 3 * 3 = 9をして[1] = 9
@**よりprint [1] + '@' = 9 + '@' => I

上記の手順を同様にすべての命令に行うと以下のようになる.

全体

## %% %++ %++ %++ %# *&* @** => I
%# **&* ***-* ***-* %++ %++ @*** => W
*-* @*** => @
@** => I
*+** @*** => L
***+* @*** => O
**+** ***+* %++ @*** => V
#% %% %++ %++ %++ %++ @* => E

%# %++ %++ %++ %% *&** @* => T
@*** => A
*-** @* => P
%# %++ @** => E
*-** *-** **-*** **-*** **-*** @** => B
@*** => A
#% %% %++ %++ %++ %++ %# *+** %++ @** => G
@* => E
%# *+** @*** => L
## %% @*** => @

IW@ILOVETAPEBAGEL@となるが, https://esolangs.org/wiki/TapeBagelのExample Programの"HELLO WORLD"のスペースが@で出力されているところから, "Hint: Replace the spaces with either ‘{’ or ‘}’ in the solution."を利用して@をそれぞれ{}に置き換えると,

IW{ILOVETAPEBAGEL}

反省点

  • opennsslとかのコマンドや鍵生成の方法に慣れておらず無駄に時間を食ったので, opensslはもちろんツールを手に馴染ませておくことが必要だった
  • 事前に分かっていたことだが, Pythonのリーディングが遅いので積極的にPython読もうと思った.