問題概要
picoCTFの「Collaborative Development」という問題の解説記事です。
- カテゴリ: General Skills
- 難易度: Easy
問題文
解説
ステップ1: ZIPファイルの確認
問題文に添付されている
challenge.zipファイルをダウンロードし、解凍します。$ unzip challenge.zip
Archive: challenge.zip
creating: drop-in/
creating: drop-in/.git/
creating: drop-in/.git/branches/
inflating: drop-in/.git/description
(中略)
inflating: drop-in/.git/logs/HEAD
creating: drop-in/.git/logs/refs/
creating: drop-in/.git/logs/refs/heads/
inflating: drop-in/.git/logs/refs/heads/main
creating: drop-in/.git/logs/refs/heads/feature/
inflating: drop-in/.git/logs/refs/heads/feature/part-1
inflating: drop-in/.git/logs/refs/heads/feature/part-2
inflating: drop-in/.git/logs/refs/heads/feature/part-3
inflating: drop-in/flag.py
解凍後、
drop-inディレクトリが作成され、その中にGitリポジトリが含まれていることがわかります。ステップ2: Gitリポジトリの調査
drop-inディレクトリに移動し、flag.pyファイルを確認します。いかにもフラグが含まれていそうですが、内容を見てみます。$ cd drop-in
$ cat flag.py
print("Printing the flag...")
flag.pyファイルにはフラグが含まれていません。print文があるだけです。なにか手がかりになるでしょうか?ステップ3: Gitの履歴を調査
Gitリポジトリの履歴を調査するために、
git logコマンドを使用します。$ git log --oneline
5e4b2da (HEAD -> main) init flag printer
履歴には1つのコミットしかありませんが、
init flag printerというメッセージがあります。フラグを出力する初期化のようです。どのような変更が行われたかを確認するために、
git showコマンドを使用します。$ git show 5e4b2da
commit 5e4b2dae1868abb644627483c78a683286dfe67c (HEAD -> main)
Author: picoCTF <ops@picoctf.com>
Date: Tue Mar 12 00:07:57 2024 +0000
init flag printer
diff --git a/flag.py b/flag.py
new file mode 100644
index 0000000..77d6cec
--- /dev/null
+++ b/flag.py
@@ -0,0 +1 @@
+print("Printing the flag...")
このコミットでは、
flag.pyファイルが新規に追加され、print("Printing the flag...")という内容だけが含まれていたようです。
このブランチには他に履歴がないため、他のブランチを調査します。ZIPファイルを解凍した際の出力から、
feature/part-1、feature/part-2、feature/part-3という3つのブランチが存在することがわかります。 creating: drop-in/.git/logs/refs/heads/feature/
inflating: drop-in/.git/logs/refs/heads/feature/part-1
inflating: drop-in/.git/logs/refs/heads/feature/part-2
inflating: drop-in/.git/logs/refs/heads/feature/part-3
ステップ4: 各ブランチの調査
各ブランチに切り替えて、
flag.pyファイルの内容を確認します。$ git checkout feature/part-1
$ cat flag.py
print("Printing the flag...")
print("picoCTF{t3@mw0rk_", end='')
feature/part-1ブランチでは、フラグの一部が追加されています。
同様に、git logでこのブランチ側のコミットを確認すると、mainとは別に「part-1 を追加したコミット」が存在するのが分かります。$ git log --oneline
300cff1 (HEAD -> feature/part-1) add part 1
5e4b2da (main) init flag printer
git showで差分を見ると、flag.pyに1行追加されているだけでした。$ git show 300cff1
commit 300cff1bf1f64637dd9ff603d90176e8e8bdeb01 (HEAD -> feature/part-1)
Author: picoCTF <ops@picoctf.com>
Date: Tue Mar 12 00:07:57 2024 +0000
add part 1
diff --git a/flag.py b/flag.py
index 77d6cec..6e17fb3 100644
--- a/flag.py
+++ b/flag.py
@@ -1 +1,2 @@
print("Printing the flag...")
+print("picoCTF{t3@mw0rk_", end='')
feature/part-2
次に
feature/part-2 を確認します。$ git checkout feature/part-2
Switched to branch 'feature/part-2'
$ cat flag.py
print("Printing the flag...")
print("m@k3s_th3_dr3@m_", end='')
ここではフラグの別パーツ
m@k3s_th3_dr3@m_ が出力されるようになっています。feature/part-3
最後に
feature/part-3 を確認します。$ git checkout feature/part-3
Switched to branch 'feature/part-3'
$ cat flag.py
print("Printing the flag...")
print("w0rk_798f9981}")
このブランチでは末尾パーツ(
} まで)が入っています。ステップ5: フラグを復元する
3つのブランチの
print(...) を見比べると、フラグが分割されているだけだと分かります。- part-1:
picoCTF{t3@mw0rk_ - part-2:
m@k3s_th3_dr3@m_ - part-3:
w0rk_798f9981}
これらを順番に連結すると、フラグが完成します。
使用したコマンドの軽い解説
git checkout
git checkout feature/part-1
ブランチ(またはコミット)を切り替えるコマンドです。今回のように「別ブランチにフラグの断片がある」タイプでは必須になります。
git log --oneline
git log --oneline
コミット履歴を1行で表示します。ブランチごとに「何が追加されたのか」を素早く把握するのに便利です。
git show <コミットハッシュ>
git show 300cff1
指定したコミットの差分を表示します。「どのファイルに、どんな変更が入ったか」を確認できます。
cat
cat flag.py
ファイルの中身を表示します。CTFでは「まず読む」が最短ルートになりがちです。
まとめ
この問題は、Gitのブランチに分散した変更(=フラグの断片)を追いかけて復元するタイプでした。
▼ポイントを整理すると次の通りです。
- 配布物に
.gitが含まれていたら、ブランチや履歴を疑う git checkoutでブランチを切り替え、ファイルの差分や内容を読む
閲覧ありがとうございました!
NEXT
次におすすめ
読み終わったら、そのまま次へ
【picoCTF】CanYouSee - 画像に隠されたフラグを見つけ出す
カテゴリ: Forensics難易度: Easy#picoCTF
次の記事へ →
同じカテゴリ/難易度/picoCTFでの表示順が近い記事を優先しておすすめしています。