LoginSignup
0
0

More than 3 years have passed since last update.

TSG LIVE! 6 CTF Writeup

Posted at

概要

TSG LIVE! 6 CTF に1人チームで参加した。
結果は150点で、50チーム (正の点数を取ったのは24チーム) 中16位だった。

問題&PoCファイル

解けた問題

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のブラウザーコンソールでいろいろ試した所、indexvalueOf.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を用いて、Npeは固定、cflage乗してNで割った余りとなっている。
また、d = pow(e, -1, phi)という意味深な文が書かれていた。 (phipから1を引いた値である)

Pythonのインタラクティブモードを用い、このdを計算した後、cd乗して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を読むと、単純なパターンに基づいてBrainf*ckのプログラムを変換しているようだった。
そこで、それに合わせて、逆アセンブル結果からBrainf*ckのプログラムを出力する以下のプログラムを書き、実行した。

parse.pl
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のような文字列が得られたのに提出ができないという事態を発生させてしまった。
このような場合は、問題は最初に一通り読み、解けそうな問題から取り組むべきだっただろう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0