CTF勉強会参加

金曜の深夜から土曜日にかけてCTF勉強会#5に行ってきた。
exploit codeってのは理屈は知っていたんだけど実際動かしてみるのは初めてだったのでかなり解くのに時間がかかった。
gdbGUIでしか使ってなかったのでいちいちコマンドを調べつつという非効率的な作業になってしまった。(DDDかInsight入れておけばよかった)

100点(一番簡単)の問題はこんな感じ。

static void cpy(char *string, int offset, int value)
{
    *((int *)(string + offset)) = value;
}
int main(int argc, char *argv[])
{
    ...
    cpy(argv[1], atoi(argv[2]), atoi(argv[3]));
    ...
}

argv[1]には実行したいコード(例えば/bin/shをexecvするような)を与える。(コマンドの引数にバイナリを渡す)
argv[2]に負の値を入れるとスタックが書き換えられるので、argv[3]に実行したいアドレスを入れておく。
そうするとcpy()が戻るときに引数で与えたコードが実行される。バイナリがsetuidされているので、別の権限でシェルが動く。
こんな単純なコードでも何時間かかかった。やれやれ。

300点の問題だと

void argv_cpy(const char *src, char *dst, int offset, int size)
{
    memcpy(dst, src + offset, size);
}
int main(int argc, char *argv[])
{
    char buffer[64];
    ...
    argv_cpy(argv[1], buffer, atoi(argv[2]), atoi(argv[3]));
    ...
}

みたいになっているのだが、スタックの実行可能属性が外れているので、初回のargv_cpyの呼び出しでスタックを乗っ取り、もう一度argv_cpyを呼び出させて、その際に自分で用意したコードを実行可能エリアにコピーさせる、のように若干複雑になっている。(まだ検証してないのでそれが正解かどうかわからないのだが)
スタックの状態を紙に書かないとさっぱり。スタック専用のメモアプリみたいなのがあると楽かも。