SECCON 2017に参加してみました
チームlryhとして参加しました! 私が解けたのは100P(1番易しい)4問。ザコ専ですよ! 笑
それでも楽しめたし,勉強にもなった。
雑感
一応セキュリティコンテストと銘打ってますが,あまりセキュリティ関係なくないですか! どちらかというと,IT技術の総合格闘技といった印象でした。
想定より (事前調査しろよという話ですが) プログラムを書く必要があって少し驚きました。BoostとOpenCV入れるところから始めましたよ。詰まった際の対処に自信がなく今回はC++で解きましたが,やはり書き捨てはPythonの方が早いので,次回は準備しておきたいです。
感覚的にはクイズを解くようなイメージで,そこが凄く楽しめました。そして他の人のWrite-Upを見て感動..。
得意とするReversingは不発で残念だった。もっと色んなバリエーションの解析を練習する必要があると感じました。
解いた問題の感想
色々な人がWrite-Upを書かれています。私は感想だけ簡単に。
Run me! (Programming 100P)
フィボナッチ数列の問題。解けました。
普通に実行すると日が暮れてしまうので高速化します。
全然知らなかったのですが,Pythonって任意精度の計算をしてくれるんですね。私は桁あふれを懸念してBoostのcpp_intで書いてしまいました。勉強になります。
putchar music (Programming 100P)
謎のC言語の1ラインコードの問題。解けました。
標準出力をPCM PlayerにPipeすると某映画の音楽が流れる。このネタ全然知らず,結構解析に時間を使ってしまいました 泣!
チームメンバ曰く,竹迫先生が学会でLT発表していたそうですね。
echo "main(t){for(;;t++)putchar((t*3&t>>5)|(t*5&t>>7));}">a.c&&gcc a.c 2>/dev/null&&sudo sh -c "./a.out>/dev/dsp" #css2017_ipsj CSSx2.0
— Yoshinori (y0sh1) (@takesako) 2017年10月23日
ところでこのプログラム,私の環境で実行するとHDDが「ビビビビ...」って悲鳴を上げるんですよ。もしや入出力を制御して動作音で音楽を制御...(ピカーン!) とか思い筐体に耳を近づけてしまいました。あほか! 笑
Baby Stack (PWN 100P)
スタンダードなPWNの問題です。正答者少なく着手しませんでした...。時間終了後やってみたら意外に解けました。
ROPの考え方自体は定石通りで良いのですが,Go言語で書かれており解析に少し時間がかかりました。色んな言語での演習を積んでおかないとと反省。
JPEG file (Binary 100P)
Jpegの画像が1ビットだけ壊れているそうで,復元する問題です。一応解けました。
最初はヘッダの内容をツールで解析。その後直接バイナリ等を調べてみるも良くわからず。
もうね。ファイルは12kbなので総当たりで調べましたよ。全ビットを1つずつ反転した画像を出力して,あとはWindowsのプレビュー機能でみる。簡単ですね (ニッコリ)
ヘッダが怪しいと睨んでいた通り,最初の1024バイトの総当たりだけで答えが出ました。
#include <bits/stdc++.h> #include <boost/filesystem.hpp> using namespace std; namespace fs = boost::filesystem; int main() { const fs::path src( "tktk-892009a0993d079214efa167cda2e7afc85e6b9cb38588cba9dab23eb6eb3d46" ); int number = 0; for( int i = 0; i < 1024; ++i ) { for( int j = 0; j < 8; ++j ) { // Copy it const fs::path dst( string("img/") + to_string(number) + string(".jpg") ); fs::copy_file( src, dst, fs::copy_option::overwrite_if_exists ); // Open copied file FILE* fp = fopen( dst.c_str(), "r+b" ); if( fp == NULL ) { fputs( "No such file\n", stderr ); exit( EXIT_FAILURE ); } // Rewrite bit unsigned char c = 0; fread( &c, 1, 1, fp ); c ^= 1 << j; // Reverse j-th bit fseek( fp, i, SEEK_SET ); // back because fp was moved by fread fwrite( &c, 1, 1, fp ); // Finalize fclose( fp ); ++number; } } }