Special instruction challenge チュートリアル

(まずは正答をなぞってみる)

■ まずは正答をなぞってみる

まず,解説はあとまわしにして,ひととおり解いてみましょう.

手始めに,競技サーバのインフォメーションページにブラウザで接続し, まずは競技の説明をよく読んでみてください.

ここには以下のようなことが書いてあります.

(攻撃ポイントの取得)

最初に攻撃ポイントの取得です.

開発環境がインストールしている環境から,以下のようにして競技サーバに GDBで接続します.以下は Blackfin の場合です.

なおここでは競技サーバが127.0.0.1上で動作しているとして説明しています.

また,接続が切断されてしまうなど,うまく接続できない場合には, 「環境構築」の競技サーバのパラメータの調整を確認してみてください. (とくにsize-connect.txtとrun.shのlimitの調整)

$ /usr/local/cross-gcc494/bin/bfin-elf-gdb bfin-elf.x
GNU gdb (GDB) 7.12.1
...
(gdb) target remote 127.0.0.1:10000
...(接続まで,ちょっと時間がかかります)...
(gdb) break nputs
(gdb) continue
(gdb) info registers
...
r1             0x1bdc   7132  ←これがポインタっぽい
...
(gdb) x/48c $r1
0x1bdc: 83 'S'  69 'E'  67 'C'  67 'C'  79 'O'  78 'N'  123 '{' 89 'Y'
0x1be4: 111 'o' 117 'u' 85 'U'  115 's' 101 'e' 77 'M'  97 'a'  110 'n'
0x1bec: 121 'y' 68 'D'  83 'S'  80 'P'  87 'W'  104 'h' 105 'i' 108 'l'
0x1bf4: 101 'e' 78 'N'  111 'o' 116 't' 75 'K'  110 'n' 111 'o' 119 'w'
0x1bfc: 105 'i' 110 'n' 103 'g' 125 '}' 0 '\000'        0 '\000'        0 '\000'
        0 '\000'
0x1c04: 0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'
        0 '\000'        0 '\000'        0 '\000'
(gdb) 
以下のキーワードが取得できています.
SECCON{YouUseManyDSPWhileNotKnowing}
実際の競技では,このキーワードをスコアサーバにコミットすれば, 攻撃ポイントとして得点が入ります.

接続先とxコマンドによるダンプは,他アーキテクチャでは以下のようにしてください.

アーキテクチャ接続先ダンプコマンドキーワード備考
MSP430
target remote 127.0.0.1:10001
(gdb) x/48c $r13
SECCON{YouCanSaveElectricityMore}
MN10300
target remote 127.0.0.1:10002
(gdb) x/48c $d1
SECCON{TheTimeOfTheMultimediaCame}
V850
target remote 127.0.0.1:10003
(gdb) x/48c $r7
SECCON{ACarHasManyMicroController}
MIPS64
target remote 127.0.0.1:10004
(gdb) x/48c $a1
SECCON{LetsStudyComputerArchitecture}
mips64-elf-gdbが無い場合は,mips-elf-gdbを利用する

実はこれらは,runme.xを実行できる環境(/home/user/tools/cross-gcc494に インストールされる,特殊命令対応のパッチ適用済みのエミュレータ)ならば, 以下のようにして実行できます.

$ /home/user/tools/cross-gcc494/bin/bfin-elf-run --environment user bfin-elf.x
SECCON{YouUseManyDSPWhileNotKnowing}
$ /home/user/tools/cross-gcc494/bin/msp430-elf-run msp430-elf.x
SECCON{YouCanSaveElectricityMore}
$ /home/user/tools/cross-gcc494/bin/mn10300-elf-run mn10300-elf.x
SECCON{TheTimeOfTheMultimediaCame}
$ /home/user/tools/cross-gcc494/bin/v850-elf-run v850-elf.x
SECCON{ACarHasManyMicroController}
$ /home/user/tools/cross-gcc494/bin/mips64-elf-run --memory-region 0x100000,0x10000 mips64-elf.x
SECCON{LetsStudyComputerArchitecture}

(防御ポイントの取得)

次に,競技サーバからrunme.xというファイルをダウンロードします.
競技サーバのインフォメーションページの 「Program for password to commit your team flag」というリンクから ダウンロードできます.

競技サーバを初回起動してからrunme.xのダウンロードまでが早すぎると, runme.xが未更新で,サイズゼロの空ファイルになっているかもしれません.
その場合には,しばらく待ってからダウンロードしなおしてください. (5分ごとに更新されます)

以下で runme.x のアーキテクチャを調べます.

$ file runme.x
runme.x: ELF 32-bit LSB executable, Analog Devices Blackfin, version 1 (SYSV), statically linked, stripped
この場合は Blackfin のようです.
アーキテクチャに応じて,runme.xの実行環境を利用して以下のようにして実行します.
(Blackfin)
$ /home/user/tools/cross-gcc494/bin/bfin-elf-run --environment user runme.x

(MSP430)
/home/user/tools/cross-gcc494/bin/msp430-elf-run runme.x

(MN10300)
/home/user/tools/cross-gcc494/bin/mn10300-elf-run runme.x

(V850)
/home/user/tools/cross-gcc494/bin/v850-elf-run runme.x

(MIPS64)
/home/user/tools/cross-gcc494/bin/mips64-elf-run --memory-region 0x100000,0x10000 runme.x

(ARM)
/home/user/tools/cross-gcc494/bin/arm-elf-run runme.x

(RL78)
/home/user/tools/cross-gcc494/bin/rl78-elf-run runme.x

(MicroBlaze)
/home/user/tools/cross-gcc494/bin/microblaze-elf-run runme.x

(MIPS)
/home/user/tools/cross-gcc494/bin/mips-elf-run runme.x

(AArch64)
/home/user/tools/cross-gcc494/bin/aarch64-elf-run runme.x
最初のうちは runme.x は Blackfin の実行ファイルだけです.
競技サーバにログインして以下のファイルを書き換えると, 様々なアーキテクチャが適用されるようになります.
(count.txt の初期値はゼロです)
$ echo 300 > /home/user/tmp/count.txt
runme.xを実行すると,以下のようにしてパスワードが取得できます.
$ /home/user/tools/cross-gcc494/bin/bfin-elf-run --environment user runme.x
PASSWORD:XXXXXXXX
このパスワードを利用して,以下のようにしてチームフラグを競技サーバの 9999番ポートにコミットします.
チームフラグは実際の競技時に提供されるものなので,とりあえずtestflagとかに しておきます.
$ echo "XXXXXXXX testflag" | nc 127.0.0.1 9999
Valid password.
「Valid password.」と応答が返ってくれば,成功です.
成功すると,競技サーバの flag.txt というページ(インフォメーションページの, 「Flag page」からリンクされています)に,コミットしたチームフラグが 以下のようにして掲載されます.
Team flags:
---- XX:XX:XX runme.x renewal ----
---- XX:XX:XX runme.x renewal ----
---- XX:XX:XX runme.x renewal ----
...
testflag
たまに「Updating files... wait for seconds.」のように言われます.
このときはrunme.xの更新中ですので,しばらく待ってまたrunme.xをダウンロード しなおして,やってみてください.
(デフォルトでは5分おきの更新です.更新時間は競技サーバの /home/user/tmp/interval.txt で調整できます)

これでチームフラグが flag.txt に掲載されれば,そのチームに防御ポイントとして 得点が入る,という競技です.

攻撃ポイントは1度きりですが,防御ポイントは5分に1回,flag.txt がチェック され,チームフラグが掲載されていれば得点が入ります. つまり継続的に得点が入ります.
またチームフラグと runme.x は5分おきに更新されます.
よって競技者は継続的に防御ポイントを取得するには, 更新のたびに最新のrunme.x を実行して, 最新のパスワードを取得して, 最新のチームフラグをflag.txtに掲載しつづける必要があります.

■ おしまい