概要
TSG LIVE! 6 CTF に1人チームで参加した。
結果は150点で、50チーム (正の点数を取ったのは24チーム) 中16位だった。
解けた問題
Truth about Pi (Web)
サーバーのプログラムを表すと考えられるJavaScriptのソースファイルと、2個のjsonファイルが与えられた。
以下のJavaScriptコードのindex
に当てはまるデータをフォームから送り、digit
が0になるようにするとflagが得られる。
const pi = Math.PI.toString();
const digit = parseInt(get(pi, index));
ここで使われているget()
関数は、Lodashの_.get()
であると考えられる。
この関数は、文字列で表されたオブジェクトのプロパティを取得できるようだ。
Firefoxのブラウザーコンソールでいろいろ試した所、index
にvalueOf.length
を入れれば0が得られることがわかった。
フォームの入力欄はtype="number"
となっているので、ここを開発者ツールでtype="text"
に書き換えた後、
valueOf.length
を入力して送信することで、flagが得られた。
TSGLIVE{I_have_ZERO_knowledger_about_ZERO}
Single RSA (Crypto)
3個の数値N, e, c
が書かれたテキストファイルと、それを生成したと考えられるPythonのソースコードが与えられた。
このソースコードによれば、素数p
を用いて、N
はp
、e
は固定、c
はflag
をe
乗してN
で割った余りとなっている。
また、d = pow(e, -1, phi)
という意味深な文が書かれていた。 (phi
はp
から1を引いた値である)
Pythonのインタラクティブモードを用い、このd
を計算した後、c
をd
乗してN
で割った余りを求め、
その値を文字列(以下のコードではans
)に変換することで、flagが得られた。
ans = ""
value = pow(c, d, N)
while value > 0:
ans = chr(value & 0xff) + ans
value >>= 8
TSGLIVE{Two_heads_are_better_than_one,_even_if_the_one's_a_poor_cryptographer's.}
解けたかと思った問題
decompile me (Rev)
ELFファイルbf
と、それを生成したと考えられるPythonのソースコードcompiler.py
が与えられた。
ELFファイルをTDM-GCCのobjdump
を用い、
-d
オプションや-D
オプションで逆アセンブルしようとしたが、結果は空だった。
そこで、
C:\MyInstalledApps\TDM-GCC-64\bin\objdump -m i8086 -M x86-64 -b binary -D bf > dump.txt
というコマンドを実行したところ、逆アセンブルを行うことができた。
さらに、compiler.py
を読むと、単純なパターンに基づいてBrainfckのプログラムを変換しているようだった。
そこで、それに合わせて、逆アセンブル結果からBrainfckのプログラムを出力する以下のプログラムを書き、実行した。
parse.pl
#!/usr/bin/perl
use strict;
use warnings;
my @prev = ();
while(my $line = <STDIN>) {
chomp($line);
if ($line =~ /inc\s+\%rbx/) {
print ">";
} elsif ($line =~ /dec\s+\%rbx/) {
print "<";
} elsif ($line =~ /inc\s+\%al/) {
print "+";
} elsif ($line =~ /dec\s+\%al/) {
print "-";
} elsif ($line =~ /syscall/) {
if ($prev[@prev - 4] =~ /mov\s+\$0x0/) {
print ",";
} elsif ($prev[@prev - 4] =~ /mov\s+\$0x1/) {
print ".";
}
} elsif ($line =~ /je/) {
print "[";
} elsif ($line =~ /jne/) {
print "]";
}
push(@prev, $line);
}
その結果、以下の出力が得られた。 (見やすいように手動で改行を補っている)
得られたBrainf*ckのプログラム
>,>>+++++++[<++++++++++++>-]<[<->-]<[<+>[-]]<
>,>>+++++++[<++++++++++++>-]<-[<->-]<[<+>[-]]<
>,>>+++++++[<++++++++++>-]<+[<->-]<[<+>[-]]<
>,>>+++++++[<+++++++++++>-]<-[<->-]<[<+>[-]]<
>,>>++++++++[<+++++++++>-]<+[<->-]<[<+>[-]]<
>,>>+++++++[<++++++++++++>-]<++[<->-]<[<+>[-]]<
>,>>+++++++[<++++++++++>-]<-[<->-]<[<+>[-]]<
>,>>+++++++++++[<+++++++++++>-]<++[<->-]<[<+>[-]]<
>,>>+++++++[<+++++++++>-]<-[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>+++++++[<+++++++++++++>-]<[<->-]<[<+>[-]]<
>,>>++++++[<++++++++++>-]<[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>+++++++[<+++++++++>-]<-[<->-]<[<+>[-]]<
>,>>+++++[<+++++++++>-]<[<->-]<[<+>[-]]<
>,>>+++++++[<+++++++++++++>-]<++[<->-]<[<+>[-]]<
>,>>++++++[<++++++++++>-]<[<->-]<[<+>[-]]<
>,>>++++++[<+++++++>-]<+[<->-]<[<+>[-]]<
>,>>+++++++++[<++++++++++++++>-]<-[<->-]<[<+>[-]]<
>+<[>->>++++++[<+++++++++++++>-]<.>>+++++++[<++++++++++>-]<+.>>++[<+++++>-]<.<<<<[-]]>[->++++++++[<++++++++++>-]<-.>>+++++[<+++++++++++++++>-]<.>>++[<+++++>-]<.>]
このプログラムの出力をオンラインBrainf*ckデバッガに入れ、
flagの書式に基づく適当な入力TSGLIVE{aaa}
を入れて実行したところ、生成されたBrainf*ckのプログラムは
「正解の文字を作り、それが入力と一致しているか比較する」という動作を繰り返しているようだった。
さらに、ブレークポイント(上記ツールでは@
)を追加して観察したところ、正解の文字は[<->-]
の直前で完成するようだった。
そこで、この位置にデータを出力する命令.
を追加して実行したところ、以下のflagのような文字列が得られた。
TSGLIVE{>+++++++[<++++++++++++>-]<+}
これを提出しようとしたところ、競技の終了時刻を約7分過ぎており、提出ができなかった。
したがって、これが本当に正解のflagかはわからない。
反省
制限時間が短いにもかかわらず、1問(b64dir)に固執して時間を無駄に使ってしまった。
そのためか、flagのような文字列が得られたのに提出ができないという事態を発生させてしまった。
このような場合は、問題は最初に一通り読み、解けそうな問題から取り組むべきだっただろう。