【picoCTF】Collaborative Development - ブランチを追ってフラグを復元する

問題概要

picoCTFの「Collaborative Development」という問題の解説記事です。

  • カテゴリ: General Skills
  • 難易度: Easy

問題文

picoCTF Collaborative Development

解説

ステップ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-1feature/part-2feature/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での表示順が近い記事を優先しておすすめしています。