はじめに
初めまして、ゆゆゆうたです。
ライブコーディング音楽とvvvvとゲーム開発に興味があるしがない苦学生です。
これまでにはゲーム開発、CTF、ライブコーディング、競技プログラミングに取組んできました。
今回のアドカレでは前に作ったゲームについてのお話をしようと思ったのですが、余りにも量が膨大になりそうだったので今日は急遽内容を変更し、タイムアタックと称してCpawでCTFを行いそれらのWriteUpを書く、という内容にします。
(いやほんとにCpawのWriteUpって充実しすぎてて、もうn番煎じもいいとこですが)
この記事で少しでも皆さんのCTFに対する敷居を下げられたらな、と思います。
特に部員の方々にはぜひ見てほしいです。
CTFってなんだよ
CTFとは、Capture the flagと呼ばれるセキュリティコンテストの一つで、ITに関する技術や知識を競うコンテストです。それぞれ11つジャンルがあり、それは以下の通りに分類されます。細かい説明はさすがにしませんが、キーワードだけは置いておくので気になったらググってみてください。
Crypto(暗号解読)
Web(ウェブサイトの脆弱性をボコボコにしたりする)
Reversing(ファイル解析)
Pwn(脆弱性攻撃)
Forensic(隠されたデータの探索)
Network(パケット解析・認証突破)
PPC(競技プログラミングみたいなやつ)
Steganography(画像・音声データの解析)
Recon(ネットストーカー)
Trivia(雑学)
Misc(その他)(上記のジャンルに分類できない問題はすべてこれ)
今回標的にするCTFサイト
今回はCpawCTF様にて提供されている問題を解いていきたいと思います。初心者向けの解いて楽しい解けてうれしいタイプの問題がたくさんあるので、このWriteUpを見ずに一度問題にトライしてみることをお勧めします。
#実行環境
OS:Windows10
プログラムはすべてWSL環境で実行しているものとします。また、一般的なLinuxコマンドについてはインストールが完了しており、パスも通っているものとして話を進めます。
(WSLのセットアップはこちらを参照してください)
(追記 MacOSを用いたCTFについて)
MacOSなんですが、ELFファイルの実行などが出来なかったり、一部ツールが使用できなかったりする場合があるので、可能な限り上記の環境に揃えておくと問題は発生しにくいと思います。
どうしてもMacOS上で行いたい場合は、VMWareかVirtualBoxを用いてLinuxの仮想環境を構築した状態で行ってください。
ただ、これも環境によって一部コマンド・ショートカットキーが使用できないことがありますのであまり推奨しません。
##WriteUpに入る前に
以下のサイトは目を通しておいてください。(解法の短縮化のため)
#WriteUp
Level1
Q1.[Misc] Test Problem
これはさすがに解けてください。お願いします。説明も省略します。
ただ私はコピペミスか何かで何回かリジェクトされてしまったことがあるので、もしかしたら手打ちでやったほうがいいかもしれません。
Q6.[Crypto] Classical Cipher
これは典型的なシーザー暗号です。
シーザー暗号というのは平文のアルファベットを何文字かずらして違う文章にする、単一換字式暗号の一つです。
しかし悲しいかな、このシーザー暗号は古典暗号、我々現代人からすれば雑魚以外の何物でもありません。
それに今のご時世「シーザー暗号 変換」とかGoogleで調べちゃうとすぐにシーザー暗号の復号(暗号化された文章を元に戻すこと)Webツールがホイホイ出てきてしまいます。こんなのとか
てことでこのサイトに暗号化された文をコピペして、変換しちゃいましょう。これでflagがゲットできます。
(大文字か小文字かは気をつけてください)
Q7.[Reversing] Can you execute ?
拡張子がないファイルをダウンロードします。普通はどんなファイルでも「txt」「exe」といったように拡張子(そのファイルがどのようなファイルかを示すもの)が付くんですが、このファイルにはそれがありません。
ってことでLinuxコマンドの「file」を用いてこのファイルがどのようなものかを探ってみると、
file exec_me
exec_me: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l,
for GNU/Linux 2.6.24, BuildID[sha1]=663a3e0e5a079fddd0de92474688cd6812d3b550, not stripped
なるほど、このファイルはELFファイルらしいことがわかります。
ELFファイルは主にLinux環境で動作する実行ファイルなので、WSL上ではそのまま動作します。
ということで以下のコマンドで実行するとflagがゲットできます。
./exec_me
Q8: [Misc] Can you open this file ?
前の問題と同じようにfileコマンドを使用すると、
file open_me
open_me: Composite Document File V2 Document,
Little Endian, Os: Windows, Version 10.0, Code page: 932, Author: v, Template: Normal.dotm,
Last Saved By: v, Revision Number: 1, Name of Creating Application: Microsoft Office Word,
Total Editing Time: 28:00, Create Time/Date: Mon Oct 12 04:27:00 2015,
Last Saved Time/Date: Mon Oct 12 04:55:00 2015,
Number of Pages: 1, Number of Words: 3, Number of Characters: 23, Security: 0
「Document」という言葉が出てきていることからこのファイルは文書ファイルであることがわかります。
今回はWordに読ませてみるために、Word既定の「doc」という拡張子を付けてWordでこのファイルを開くとflagがゲットできます。
(追記)なぜ拡張子を設定するのか
拡張子には「そのファイルがどの形式に従っているのか」を分かりやすく表す目的もあるのですが、もうひとつ「アプリケーション側でも認識可能な形にする」といった役割があります。
実際、文書ファイルであったとしても「.doc」といったような拡張子がなければ文書ファイルとして認識してくれないことが多いです。音声ファイルの拡張子とかを変えてみるとまず音は聞けなくなってしまうのがいい例です。
これを無理矢理読み込ませたりすると、結果的にデータの損失につながったり、エラーの原因になったりと、様々な問題の温床となってしまうことがあります。(これが原因で解答が迷宮入りになったりすることも…)
それらの問題を解消するために、バイナリファイルでもない限り極力拡張子のないファイルを作らないように問題に取り組んでみましょう。
Q9.[Web] HTML Page
今度はWebページの中からflagをゲットする問題です。web問題を解くときはキーボードのF12キーを押し、ディベロッパーツールを表示することを忘れないようにすること、隅から隅までページを見ることを心掛けましょう。
さて、上二つの心構えを遵守していると、
Do you read description of this page?
なんか明らかに怪しい文が出てきました。
英文中の「description」という単語を調べると、どうもhtmlファイルの中に記述される、Webページの概要(要約)を示すテキスト情報であることがわかります。
ということで、先に開いておいたディベロッパーツールのElementsタブでhtmlソースをくまなく探すとどこかにflagが記述されています。これでflagをゲットできます。
Q10.[Forensics] River
渡される画像にはどうもExif情報といった様々なメタデータが引っ付いているようです。
ということでさっそくこちらのjpgをこのサイトに投げるとこんな感じに。
地図から川の名前を読み取り、flagゲットです。
いやほんとに文明の進歩って恐ろしいですね。皆さんも写真のメタデータには気を付けてくださいね。
Q11.[Network]pcap
今回はネットワークパケットの解析問題です。ということでパケット解析の虎の子、WireSharkをインストールしましょう。そこから話が始まります。
さて、ダウンロードしたファイルをwiresharkで開くとこんな感じの画面が出てくると思います。
もう見たらわかると思いますがflagが出てますね。こういったデータが平文でポンポンやり取りされていたら日本は終わります。
Q12.[Crypto]HashHashHash!
今回はSHA1といったNSAが考案した暗号を解きます。一見難しそうですが、こういうのはほんとにググったら何とかなります。
ということで問題の暗号文をそのまま検索してみましょう。するとびっくりするレベルであっさりとflagがゲットできます。
(これが実現できているのはひとえにレインボーテーブルというテクニックのおかげです。レインボーテーブル万歳。)
Q14.[PPC]並べ替えろ!
なんかいきなり競技プログラミングみたいなやつ来ましたね。まあこういうのはコード書いてなんぼです。書きましょう。
まずデータをこんな感じで成型して、
15
1
93
52
66
31
87
0
42
77
46
24
99
10
19
(省略)
テキストファイルとして読み込んでコードをパパっと書いて、終わりです。これでflagをゲットできます。
#include<stdio.h>
#include<stdlib.h>
int main(){
FILE *fp;
int i, j,n=0, tmp;
int array[100];
char filename[] = "test.txt";
char str[100];
fp = fopen(filename,"r");
if(fp == NULL) {
printf("%s file not open!\n", filename);
return -1;
}
while(fgets(str,100, fp) != NULL){
array[n] = atoi(str);
n++;
}
fclose(fp);
for (i=0; i<n; ++i) {
for (j=i+1; j<n; ++j) {
if (array[i] < array[j]) {
tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
}
}
for (i=0; i<n; ++i){
printf("%d", array[i]);
}
return 0;
}
Level2
Q13.[Stego]隠されたフラグ
配られた画像を見ると、どうも点々が描画されているのがわかります。形的にどうみてもモールス信号ですので、翻訳にかけてflagをゲットします。
ただ、この問題に限り、サイトごとで微妙に出力が違うときがあります。いくつか翻訳サイトを載せておきますので、もし望んだflagが出力されなければいろいろ試してみてください。
https://l08084.github.io/morse-code-translate-website/
http://www.inv.co.jp/~ike/mores-chg.html
https://morsecode.doratool.com/
Q15.[Web] Redirect
fc2のサイトとかが消えてたりすると「n秒後にホームに戻ります」みたいなページが出てくる時がありますよね。まさしくあれがリダイレクトです。
先ほどのweb問題と同じようにディベロッパーツールを起動し、リンクを押してみると確かに所定のページには飛ばないことがわかると思います。
そこで、ディベロッパーツールで表示する項目をelementsからnetworkへと変更します。
すると、何かしらのプログラムに悪さをされて閲覧できなかった本来のページの情報が出ていることがわかりますよね。
こちらのデータをダブルクリックしてみると、flagをゲットできます。
Q16.[Network+Forensic]HTTP Traffic
いつものようにパケット解析をするところですが、ちょっとパケットの中身を見てみると、どうもパケットの中に結構なデータが隠されていることがわかります。
そこで、これらのデータを[ファイル]→[オブジェクトをエクスポート]→[HTML]でまとめてエクスポートしてあげましょう。
フォルダを作り、jsやcssファイルをフォルダでこんな感じで分けて、拡張子の付いていないhtmlファイルにきちんと拡張子をつけて行きましょう。(ブラウザアプリにhtmlページとして認識させるために必ず必要です。)
htmlファイルを開くとボタンが出てくるのでそのボタンを押下するとflagをゲットできます。
Q17.[Recon]Who am I ?
ネットストーカー問題です。TwitterIDとよくプレイされているとされるゲームの名前を一緒に検索するとflagがゲットできます。
皆さんは安易にゲームID等を見せないようにしましょうね。
Q18.[Forensic]leaf in forest
テキストファイルでこのファイルを開いてみると、
夢に出てきそうなのが出てきました。怖いので「lovelive!」という文字列を一文字で置換し続けると、自然にflagがゲットできます。
Q19.[Misc]Image!
今回はzipファイルが渡されるので、解凍してみます。
なるほど、と思い片っ端から閲覧していきますが、大した情報は出てきませんでした。
ただ、一つだけあった画像ファイルを閲覧すると、こんな感じの画像が。
多分どこかしらにデータがあるのかな、と思い、様々なファイルをくまなく閲覧した結果、meta.xmlを閲覧すると、
<?xml version="1.0" encoding="UTF-8"?>
<office:document-meta xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:smil="urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:officeooo="http://openoffice.org/2009/office" office:version="1.2"><office:meta><meta:creation-date>2015-10-16T09:50:35.362650845</meta:creation-date><dc:date>2015-10-16T10:06:25.173018557</dc:date><meta:editing-duration>PT1M11S</meta:editing-duration><meta:editing-cycles>4</meta:editing-cycles><meta:generator>LibreOffice/4.2.8.2$Linux_X86_64 LibreOffice_project/420m0$Build-2</meta:generator><meta:document-statistic meta:object-count="17"/></office:meta></office:document-meta>
この中のOpenDocumentに着目し、ググるとどうもOpenDocumentはzip形式で圧縮されたファイルとのこと。
documentということもあり、wordでzipフォルダを開くとflagをゲットできました。
事前知識がなければかなりのひらめきが必要です。
Q20.[Crypto]Block Cipher
cソースファイルが渡されるので、そのソースを読み取りflagを手に入れる問題です。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[]){
int i = 0;
int j = 0;
int key = atoi(argv[2]);
const char* flag = argv[1];
printf("cpaw{");
for(i = key - 1; i <= strlen(flag); i+=key){
for(j = i; j>= i - key + 1; j--){
printf("%c", flag[j]);
}
}
printf("}");
return 0;
}
復号前の文と、何文字分ずらすかをコマンドライン引数に入れて実行すると、flagをゲットできます。
私の場合はコマンドライン引数の仕様をうまく理解してなかったため、コアダンプばかり起こしていました。反省。
Q21.[Reversing]reversing easy!
今回はIDAという逆アセンブリを用いて問題を解きました。IDAのインストール
IDAで問題のバイナリファイルを開くと、こんな感じの画面が出てきます。
IDAってホントに高機能なソフトで、無料なのにどのような関数がどのタイミングで呼び出されてるとかをわかりやすく表示してくれます。
text viewのほかにもタブがあるので、いろいろと閲覧してみます。するとHex-view(バイナリの16進数ダンプ)タブに切り替えたときに、
いかにもな文字列が出てきました。flagに関係のないであろう記号などを除いてつなげると、flagが入手できます。
逆アセンブリってどの文字列が対応してるのかわからないくらい変な文字が紛れ込んだりするので、いやどこが簡単なんだよ、って初見では思いました。
Q22.[Web]Baby's SQLi - Stage 1-
これはwebサイトの脆弱性を突いたSQLインジェクションを行う問題です。どうも、テーブル内のデータを参照すればflagが得られそうなので、フォームに以下のSQL文を打ち込みます。
SELECT * FROM palloc_home
すると、お目当てのテーブルが出現し、flagをゲットできます。
かんたんにこのSQL文を解読すると
SELECT...データを取得する。
*...テーブル内のすべてを
FROM palloc_home...palloc_homeから
みたいな感じです。
SQLは意外なタイミングで使用することがあるので、簡単な命令だけでも覚えておくと得です。
Q28.[Network] Can you login?
Wiresharkでパケットを眺めてみると、
明らかに見えちゃいけない認証情報が見えていることがわかります。これは、FTPプロトコル自体が認証のためのユーザ名・パスワードや転送データを暗号化せず、平文でやり取りするためだからです。
このプロトコルを重大な機密データの送信の際に日常的に使うと世界は終わります。今のご時世には明らかに即していないプロトコルです。(もちろんFTPは現在も限定的な用途に使用されています。)
ipも丸見えなので、今回はFileZillaを用いてファイルの取得を行っていきます。FileZillaのインストール
FileZillaはClientの方をインストールしてください。
FileZillaで先ほどの情報を用いFTPサーバに接続します。(Clientの方をダウンロードしてくださいといったのはこのため)
また、接続する前に、隠しファイルの強制表示を行う設定をしておいてください。(CTFでは隠しファイルに重要な情報が入っていることがあるため)
設定のほうは、[サーバ]→[隠しファイルの強制表示]で簡単に行えます。
接続が成功したらFTPサーバから.hidden_flag_fileをダウンロードし、stringsコマンドかテキストエディタで閲覧するとflagが手に入ります。
もちろん、以下のようにコマンドをターミナルで打ち込んでも接続・ファイルのダウンロードは行えます。
$ ftp
ftp> open
(to) 157.7.52.186
Connected to 157.7.52.186.
220 Welcome to Cpaw CTF FTP service.
Name (157.7.52.186:user): cpaw_user
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -l
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r-- 1 ftp ftp 36 Sep 01 2017 dummy
226 Directory send OK.
ftp> ls -la
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x 2 ftp ftp 42 Jun 18 2019 .
drwxr-xr-x 2 ftp ftp 42 Jun 18 2019 ..
-rw-r--r-- 1 ftp ftp 39 Sep 01 2017 .hidden_flag_file
-rw-r--r-- 1 ftp ftp 36 Sep 01 2017 dummy
226 Directory send OK.
ftp> get .hidden_flag_file
local: .hidden_flag_file remote: .hidden_flag_file
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for .hidden_flag_file (39 bytes).
226 Transfer complete.
39 bytes received in 0.00 secs (8.2742 kB/s)
終わりに
ここまで閲覧いただきありがとうございます。もしわかりにくいところがあればコメントでご指摘のほどよろしくお願いいたします。
さて、ここまでWriteUpを見た方ならわかると思いますが、ちょっとのひらめきがあればこれらの問題は誰にでも解けるとわかったと思います。そこまで専門的なことをやってませんからね。(そうと信じたい)
もしそう思われた方は、是非とも今すぐ自分で今回の問題を解いてみてください。自分で解くことにより、また違う発見ができると思いますよ。
今回はLevel2までのWriteUpしか掲載しませんでしたが、機会があればLevel3のWriteUpにも挑戦し、WriteUpを掲載してみようと思います。
それでは、次の記事でお会いしましょう。