[Çözüm] GIT Capture the Flag, Git İç Yapısı ve Git Objeleri

Giriş

Merhaba. Onbeş gün kadar önce ödülsüz tek soruluk bir GIT CTF 1 sorusu yayınlamıştım. Hiç kimseden yanlış dahi olsa bir cevap gelmedi.

Çözümünü yayınlıyorum.

GIT Objeleri

Git is a content-addressable filesystem. Great. What does that mean? It means that at the core of Git is a simple key-value data store. What this means is that you can insert any kind of content into a Git repository, for which Git will hand you back a unique key you can use later to retrieve that content. 2

Git çekirdeği, basit bir key-value veri tabanıdır. İstediğiniz herhangi bir içeriği Git ile saklayabilirsiniz ve akabinde Git size bunu eşsiz bir Id döndürür.

Git obje veritabanı .git/objects klasörüdür.

Boş bir repo oluşturalım ve içinde hiçbir obje olmadığını teyit edelim.

$ git init test-repo && cd test-repo
Initialized empty Git repository in C:/Users/guneysu/AppData/Local/Temp/test-repo/.git/

$ find .git/objects
.git/objects
.git/objects/info
.git/objects/pack

$ find .git/objects -type f ^C

$ find .git/objects -type f

Git veri tabanına elle bir obje oluşturalım.


$ echo 'test content' | git hash-object -w --stdin
d670460b4b4aece5915caf5c68d12f560a9fe3e4

git hash-object komutu, verdiğiniz içeriğini git veritabanında saklandığında size vereceği benzersiz ID’yi döndürür. -w parametresi ise sadece ID döndürmekle kalmaz, bu objeyi de veritanına kaydeder. --stdin ile içeriğini standart inputtan alacağımızı bildirdik. Bu parametreyi vermeseydik, dosya yolunu vermemiz gerekecekti.

Yukarıdaki komutun çıktısı, 40 karakterlik bir SHA-1 hash değeridir.

Git veritabanını tekrark kontrol edelim.

$ find .git/objects -type f
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4

git cat-file komutu ile git objelerinin içeriğini görüntüleyebilirsiniz.

$ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
test content

GIT objeleri hakkında bu kadar bilgi şimdilik yeterli. Şimdi git notes komutundan bahsedelim.

git notes

Git objelerini değiştirmeden, notlar ekleyip çıkarmayı sağlayan komuttur. 3 Varsayılan olarak refs/notes/commits içerisinde saklanır fakat bu yol değiştirilebilir.

Yukarıdaki test repomuza bir commit yapalım.

$ echo 'test content' > test-content.txt

$ git add test-content.txt && git commit -m 'initial commit'
[master (root-commit) 5ae0756] initial commit
 1 file changed, 1 insertion(+)`
 create mode 100644 test-content.txt

$ git show -s 5ae0756
commit 5ae0756572c1928be31044dd20b94773798cd184 (HEAD -> master)
Author: Ahmed Şeref Güneysu <[email protected]>
Date:   Sat May 16 13:57:26 2020 +0300

    initial commit

Bu commite bir not ekleyelim:

$ git notes add -m 'Tested-by: Ahmed Şeref <[email protected]>' 5ae0756

5ae0756 ID’li commit detayını tekrar gösterelim ve notların commit bilgisi ile nasıl bir arada gösterildiğini görelim.

$ git show -s 5ae0756
commit 5ae0756572c1928be31044dd20b94773798cd184 (HEAD -> master)
Author: Ahmed Şeref Güneysu <[email protected]>
Date:   Sat May 16 13:57:26 2020 +0300

    initial commit

Notes:
    Tested-by: Ahmed Şeref <[email protected]>

Ve Çözüm !

GIT CTF reposunu 4 klonlayalım.

$ git clone [email protected]:guneysus/git-ctf.git
Cloning into 'git-ctf'...
remote: Enumerating objects: 2, done.
remote: Counting objects: 100% (2/2), done.
remote: Total 2 (delta 0), reused 2 (delta 0), pack-reused 0
Receiving objects: 100% (2/2), done.

$ cd git-ctf/

$ git log --abbrev-commit
commit 8ed07cc (HEAD -> master, origin/master, origin/HEAD)
Author: Ahmed Şeref Güneysu <[email protected]>
Date:   Wed Apr 29 17:10:20 2020 +0300

    Empty commit

8ed07cc commitimizde herhangi bir not gözükmüyor.

Yukarıda notların refs/notes/commits içerisinde saklandığından bahsetmiştik. Bu yazı yazıldığı an itibariyle git notlarının clone veya fetch ile çekmenin basit bir yolu henüz yok. 5

Bunun için çalıştırmamız gereken komut:

$ git fetch origin refs/notes/*:refs/notes/*
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 269 bytes | 22.00 KiB/s, done.
From github.com:guneysus/git-ctf
 * [new ref]         refs/notes/commits -> refs/notes/commits

Notlarımızı sunucudan çektik, bakalım commit detaylarımızda bu bilgileri görebilecek miyiz?

$ git log --abbrev-commit
commit 8ed07cc (HEAD -> master, origin/master, origin/HEAD)
Author: Ahmed Şeref Güneysu <[email protected]>
Date:   Wed Apr 29 17:10:20 2020 +0300

    Empty commit

Notes:
    Flag: parchment

Evet, bayrağımızı bulduk: parchment 🎊

Git reposunun git notlarını da içeren halini aşağıda Resources kısmından da indirebilirsiniz.

Parchment.png
By IgniX - Own work, CC BY-SA 3.0, Link