Weird Wired World

Programming, Security

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発表していたそうですね。

ところでこのプログラム,私の環境で実行すると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;
        }
    }
}