neilsriv blog

git ctf


this is my write up for git ctf, a set of challenges centered around git operations

TLDR:

  • every flag is the name of a git branch that you can checkout to start the relevant challenge

clone #

1> ssh player@ctf.mrnice.dev -p 12345

password is player

1> git clone gamemaster@localhost:~/ctf-repo
2> cat README.md
3Now, to proceed - `git checkout` the branch named `start-here`, and then read me again.

start-here #

1> cat README.md
21. Add 2 files to the root of the repo: `alice.txt` and `bob.txt`.
32. Commit your changes (should be only one commit!).
43. Push your changes to the remote repo.
54. If you did it right, you should get your flag.
 1> touch alice.txt bob.txt
 2> git add .
 3> gc -m 'new files'
 4> git push
 5remote: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 6remote: 
 7remote: Pushed a branch: start-here
 8remote: 
 9remote:         ()__
10remote:         ||  Z__
11remote:         ||  |   Z____
12remote:         ||  |   |    |
13remote:         ||  |   |    |
14remote:         ||__|   |    |
15remote:         ||  /___|    |
16remote:         ||      /____/
17remote:         ||
18remote:         ||
19remote:         ||
20remote:         /\                
21remote:     ___/  \___
22remote: 
23remote: You won! The flag is scorpion-treenware-gestatory (basic-1)
24remote: 
25remote: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
26remote: 

flag = scorpion-treenware-gestatory

basic #

basic-1 #

1> cat README.md
2To solve this level you need to remove the file called `deleteme.txt`.
 1> l
 2-rw-r--r-- 1 player player   72 Feb 28 04:46 README.md
 3-rw-r--r-- 1 player player   32 Feb 28 04:52 deleteme.txt
 4-rw-r--r-- 1 player player   27 Feb 28 04:46 dontdeleteme.txt
 5
 6> rm deleteme.txt
 7> ga .
 8> gc -m 'delete'
 9> git push
10remote: You won! The flag is sidespins-areae-regalio (basic-2)

flag = sidespins-areae-regalio

basic-2 #

 1> cat README.md
 2To solve this level, you need to add two new files (call them whatever you want) under a directory called `newdir`.
 3> mkdir newdir
 4> touch newdir/one.txt newdir/two.txt
 5> ga .
 6> gc -m 'dir files'
 7> git push
 8remote: You won! The flags are
 9remote: macrochiropteran-jupon-lutecium (merge-1)
10remote: turbulator-feere-reinclined (log-1)

flags = macrochiropteran-jupon-lutecium & turbulator-feere-reinclined

merge #

merge-1 #

1> cat README.md
2Take a look at the runme.py script. It's unfinished, and the rest of the work is in another **branch**...
3
4(There's no need to edit files to solve this level. Only git commands will suffice.)

now we finally have more an involved challenge. Let’s take a look at runme.py

runme.py
 1#!/usr/bin/env python3
 2
 3def print_something_cool():
 4    # I'll finish the rest of the work in another branch... zZzZ
 5    raise NotImplementedError("I'll implement the rest of this script in the steek-shabandar-taenifuge branch.")
 6
 7def main():
 8    print_something_cool()
 9
10if __name__ == "__main__":
11    main()
1> gco steek-shabandar-taenifuge

This branch also has a runme.py file

runme.py
 1#!/usr/bin/env python3
 2
 3import base64
 4
 5def print_something_cool():
 6    something_cool = b'CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXy4tIi0uXwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLi0iLS5fJyAgICAgICBgLS5fCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLi0iLS5fJyAgICAgICBgLS5fICAgICBfLi0nfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIF8uLSItLl8nICAgICAgIGAtLl8gICAgIF8uLXxfLi0nXy4tJ2AtLl8KICAgICAgICAgICAgICAgICAgICAgXy4tIi0uXycgICAgICAgYC0uXyAgICAgXy4tfF8uLScgICB8Xy4tJyAgICAgICAgYC0uXwogICAgICAgICAgICAgXy4tIi0uXycgICAgICAgYC0uXyAgICAgXy4tfF8uLScgICAgICAgICAgIGAtLl8gICAgICAgICBfLi18CiAgICAgXy4tIi0uXycgICAgICAgYC0uXyAgICAgXy4tfF8uLScgICAgICAgICAgICAgICAgICAgICAgIGAtLl8gXy4tJ18uLWAtLl8KIF8uLScgICAgICAgYF8uLSItLl8gXy4tfF8uLScgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxfLi0nICAgICAgIGAtLl8KYC0uXyAgICAgXy4tJyAgICAgICBgXy4tJy0uXyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwtLl8gICAgICAgICBfLi0nCiAgICBgLS5ffC0uXyAgICAgXy4tJyAgICAgICBgXy4tJy0uXyAgICAgICAgICAgICAgICAgICAgICAgICBfLi0nLS5fYC0uXyBfLi0nCiAgICAgICAgICAgIGAtLl98LS5fICAgICBfLi0nICAgICAgIGBfLi0nLS5fICAgICAgICAgICAgIF8uLScgICAgICAgYC0uX3wKICAgICAgICAgICAgICAgICAgICBgLS5ffC0uXyAgICAgXy4tJyAgICAgICBgXy4tJy0uXyAgICB8LS5fICAgICAgICAgXy4tJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYC0uX3wtLl8gICAgIF8uLScgICAgICAgYF8uLSctLl9gLS5fIF8uLScKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYC0uX3wtLl8gICAgIF8uLScgICAgICAgYC0uX3wKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgLS5ffC0uXyAgICAgICAgIF8uLScKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAtLl8gXy4tJyAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIgo=CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXy4tIi0uXwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLi0iLS5fJyAgICAgICBgLS5fCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLi0iLS5fJyAgICAgICBgLS5fICAgICBfLi0nfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIF8uLSItLl8nICAgICAgIGAtLl8gICAgIF8uLXxfLi0nXy4tJ2AtLl8KICAgICAgICAgICAgICAgICAgICAgXy4tIi0uXycgICAgICAgYC0uXyAgICAgXy4tfF8uLScgICB8Xy4tJyAgICAgICAgYC0uXwogICAgICAgICAgICAgXy4tIi0uXycgICAgICAgYC0uXyAgICAgXy4tfF8uLScgICAgICAgICAgIGAtLl8gICAgICAgICBfLi18CiAgICAgXy4tIi0uXycgICAgICAgYC0uXyAgICAgXy4tfF8uLScgICAgICAgICAgICAgICAgICAgICAgIGAtLl8gXy4tJ18uLWAtLl8KIF8uLScgICAgICAgYF8uLSItLl8gXy4tfF8uLScgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxfLi0nICAgICAgIGAtLl8KYC0uXyAgICAgXy4tJyAgICAgICBgXy4tJy0uXyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwtLl8gICAgICAgICBfLi0nCiAgICBgLS5ffC0uXyAgICAgXy4tJyAgICAgICBgXy4tJy0uXyAgICAgICAgICAgICAgICAgICAgICAgICBfLi0nLS5fYC0uXyBfLi0nCiAgICAgICAgICAgIGAtLl98LS5fICAgICBfLi0nICAgICAgIGBfLi0nLS5fICAgICAgICAgICAgIF8uLScgICAgICAgYC0uX3wKICAgICAgICAgICAgICAgICAgICBgLS5ffC0uXyAgICAgXy4tJyAgICAgICBgXy4tJy0uXyAgICB8LS5fICAgICAgICAgXy4tJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYC0uX3wtLl8gICAgIF8uLScgICAgICAgYF8uLSctLl9gLS5fIF8uLScKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYC0uX3wtLl8gICAgIF8uLScgICAgICAgYC0uX3wKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgLS5ffC0uXyAgICAgICAgIF8uLScKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAtLl8gXy4tJyAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIgo='
 7
 8    print(base64.b64decode(something_cool).decode())
 9
10def main():
11    print_something_cool()
12
13if __name__ == "__main__":
14    main()

let’s see what this outputs when we run it

 1> python runme.py
 2
 3                                                     _.-"-._
 4                                             _.-"-._'       `-._
 5                                     _.-"-._'       `-._     _.-'|
 6                             _.-"-._'       `-._     _.-|_.-'_.-'`-._
 7                     _.-"-._'       `-._     _.-|_.-'   |_.-'        `-._
 8             _.-"-._'       `-._     _.-|_.-'           `-._         _.-|
 9     _.-"-._'       `-._     _.-|_.-'                       `-._ _.-'_.-`-._
10 _.-'       `_.-"-._ _.-|_.-'                                   |_.-'       `-._
11`-._     _.-'       `_.-'-._                                    |-._         _.-'
12    `-._|-._     _.-'       `_.-'-._                         _.-'-._`-._ _.-'
13            `-._|-._     _.-'       `_.-'-._             _.-'       `-._|
14                    `-._|-._     _.-'       `_.-'-._    |-._         _.-'
15                            `-._|-._     _.-'       `_.-'-._`-._ _.-'
16                                    `-._|-._     _.-'       `-._|
17                                            `-._|-._         _.-'
18                                                    `-._ _.-'  
19                                                        "

Hmm not sure what to do with that. Let’s take a look at the git log

1> git log
2commit 916cd9d5ca15e8f09e1b44fdc43d4bc955915715 (HEAD -> steek-shabandar-taenifuge, tag: steek-shabandar-taenifuge-tag, origin/steek-shabandar-taenifuge)
3Author: Shay Nehmad <shay.nehmad@guardicore.com>
4Date:   Mon Jun 1 22:33:51 2020 +0300
5
6    Finished working on the runme script. Merge me into macrochiropteran-jupon-lutecium branch.

Ah need to merge these branches together

1> gco macrochiropteran-jupon-lutecium
2> git merge steek-shabandar-taenifuge
3> ga .
4> gc -m 'merged'
5> git push
6remote: You won! The flag is poseuse-citronwood-manganese (merge-2)

flag = poseuse-citronwood-manganese

merge-2 #

1> cat README.md
2Take a look at the runme.py script. It's unfinished, and the rest of the work is in another **branch**...
3
4(There's no need to edit files to solve this level. Only git commands will suffice.)

getting a sense of deja-vu…

 1> cat runme.py
 2#!/usr/bin/env python3
 3
 4import base64
 5import os
 6
 7def print_something_cool():
 8    something_cool = <some base64 encoded stuffs>
 9
10    # I'll define cool file in the cannoneer-dephlegm-holoptychius branch.
11    assert os.path.exists("./cool_file"), "couldn't find cool file: It's in the cannoneer-dephlegm-holoptychius branch"
12
13    print(base64.b64decode(something_cool).decode())
14
15def main():
16    print_something_cool()
17
18if __name__ == "__main__":
19    main()

time to go to another branch

1> gco cannoneer-dephlegm-holoptychius
2> l
3...
4-rw-r--r-- 1 player player   57 Feb 28 05:19 cool_file

this branch has a new file cool_file, let’s merge that into the first branch and see what happens

1> gco poseuse-citronwood-manganese
2> git merge cannoneer-dephlegm-holoptychius
3> git push
4remote: You won! The flags are
5remote: twee-enfamish-stropharia (merge-3)
6remote: parallelizing-barnhardtite-base (rebase-1)

success! flags = twee-enfamish-stropharia & parallelizing-barnhardtite-base

merge-3 #

1> cat README.md
2Take a look at the runme.py script. It's unfinished, and the rest of the work is in another **branch** (gemstone-introrsely-gouts). But this time, things aren't so harmonious. Don't panic!
3
4(You can edit files to solve this level. Only git commands will suffice.)

(I assume that the last line is a typo and that I don’t need to edit files)

1> gco gemstone-introrsely-gouts

nothing special, just another version of the runme.py file. let’s git merge again and see what happens

1> gco twee-enfamish-stropharia
2> git merge gemstone-introrsely-gouts
3Auto-merging runme.py
4CONFLICT (content): Merge conflict in runme.py
5Automatic merge failed; fix conflicts and then commit the result.

merge conflict ☹, okay maybe we can edit the files (at least to resolve a merge conflict)

1> vim runme.py
2def print_another_cool_thing():
3<<<<<<< HEAD
4    message = "Your cool (*/?~I\*)"
5=======
6    message = "You're cool (*/?~I\*)"
7>>>>>>> gemstone-introrsely-gouts
8    print(message)

let’s take the grammatically correct one

runme.py
1def print_another_cool_thing():
2    message = "You're cool (*/?~I\*)"
3    print(message)

time to push up again

1> ga .
2> gc
3> git push
4remote: You won! The flags are
5remote: multichord-ethicalism-fenestration (merge-4)
6remote: lomentaceous-mididae-hexadecane (revert-1)

flags = multichord-ethicalism-fenestration & lomentaceous-mididae-hexadecane

merge-4 #

this time the README.md directly lists what branch we need to go look at, unconvincing-mesothermal-miles, but let’s take a look at the runme.py first

runme.py
1def print_yet_another_thing():
2    process = subprocess.Popen(['git', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
3    stdout, stderr = process.communicate()
4    print("The current git version you're playing with is " + stdout.decode())

and when trying to run it, I get an error:

1Traceback (most recent call last):
2  File "runme.py", line 25, in <module>
3    main()
4  File "runme.py", line 22, in main
5    print_yet_another_thing()
6  File "runme.py", line 15, in print_yet_another_thing
7    process = subprocess.Popen(['git', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
8NameError: name 'subprocess' is not defined

okay let’s try to git merge and see what happens

1> git merge unconvincing-mesothermal-miles
2Auto-merging runme.py
3CONFLICT (content): Merge conflict in runme.py
4Automatic merge failed; fix conflicts and then commit the result.

another conflict again, this time it seems slightly more complicated

 1def print_yet_another_thing():
 2<<<<<<< HEAD
 3    process = subprocess.Popen(['git', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 4    stdout, stderr = process.communicate()
 5    print("The current git version you're playing with is " + stdout.decode())
 6
 7def main():
 8    print_something_cool()
 9    print_another_cool_thing()
10    print_yet_another_thing()
11=======
12    pass  # will implement in another branch
13>>>>>>> unconvincing-mesothermal-miles

let’s keep the fully implemented version of print_yet_another_thing and main

1def print_yet_another_thing():
2    process = subprocess.Popen(['git', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
3    stdout, stderr = process.communicate()
4    print("The current git version you're playing with is " + stdout.decode())
5
6def main():
7    print_something_cool()
8    print_another_cool_thing()
9    print_yet_another_thing()

now commit, push, and

remote: You won! The flag is reappraise-veratroyl-garfishes (merge-5)

flag = reappraise-veratroyl-garfishes

merge-5 #

lots of instructions in the README.md this time

1Take a look at the `should_rename_this.py` script. It's finished, but the name isn't very clear about what the script does. The script was given a better name in another **branch** (vicomtesses-apery-vanillin). 
2
3Merge the changes from that branch, ending up with: 
4- The new code from the reappraise-veratroyl-garfishes branch
5- The new name from the vicomtesses-apery-vanillin branch

I hope git handles renames well 🤞

1> git merge vicomtesses-apery-vanillin
2CONFLICT (rename/rename): Rename "runme.py"->"should_rename_this.py" in branch "HEAD" rename "runme.py"->"scripts/print_cool_stuff.py" in "vicomtesses-apery-vanillin"
3Automatic merge failed; fix conflicts and then commit the result.

okay let’s see what we are working with

 1> gst
 2On branch reappraise-veratroyl-garfishes
 3Your branch is up to date with 'origin/reappraise-veratroyl-garfishes'.
 4
 5You have unmerged paths.
 6  (fix conflicts and run "git commit")
 7  (use "git merge --abort" to abort the merge)
 8
 9Unmerged paths:
10  (use "git add/rm <file>..." as appropriate to mark resolution)
11	both deleted:    runme.py
12	added by them:   scripts/print_cool_stuff.py
13	added by us:     should_rename_this.py

looks like we can get rid of runme.py, the new name of the file should be print_cool_stuff.py, and the correct contents are in should_rename_this.py. normally, I’d just delete the extraneous files and manually rename the should_rename_this.py file, but today I’ll try git mv since this is a git-ctf particularly

 1> ga runme.py # stages the deletion of the runme.py file
 2> rm scripts/princ_cool_stuff.py
 3> ga should_rename_this.py
 4> git mv should_rename_this.py scripts/print_cool_stuff.py
 5> gst
 6On branch reappraise-veratroyl-garfishes
 7Your branch is up to date with 'origin/reappraise-veratroyl-garfishes'.
 8
 9All conflicts fixed but you are still merging.
10  (use "git commit" to conclude merge)
11
12Changes to be committed:
13	renamed:    should_rename_this.py -> scripts/print_cool_stuff.py

looks like that should do the trick, let’s commit and push

remote: You won! The flag is merge-levels-done-you-win (final)

flag = merge-levels-done-you-win

🎉 finished all the merge levels, let’s tackle log next

log #

pretty clear that this section should be all about the git log (and maybe reflog too)

log-1 #

1> cat README.md
2The next flag can be found in the commit message of the current branch's grandparent (2 commits back from now).

pretty straightforward challenge

1> git log
2...
3commit e16a3e386eadfa32a6de83b6bba165e3b4eba9ad
4Author: Shay Nehmad <shay.nehmad@guardicore.com>
5Date:   Tue Jun 2 17:30:30 2020 +0300
6
7    The flag is insatiably-skyjackers-program (log-2) ^_^

flag = insatiably-skyjackers-program

log-2 #

1> cat README.md
2The flag was hidden in one of the commit messages in the current branch's history. The commit message where it's hidden has the text "The flag is hidden here" in it.
3
4Find it.

there’s at least 200 commits

 1> git log
 2...
 3commit 72c899f49c11943ec140f88ec6d2b79ea49ce32d
 4Author: Shay Nehmad <shay.nehmad@guardicore.com>
 5Date:   Tue Jun 2 17:45:45 2020 +0300
 6
 7    commit 200
 8
 9commit 283058e235fcd9acf260827dcecb7fb52c2cfd28
10Author: Shay Nehmad <shay.nehmad@guardicore.com>
11Date:   Tue Jun 2 17:45:45 2020 +0300
12
13    commit 199

let’s use grep to help find the correct commit

 1> git log | grep "the flag" -B 10 -A 2
 2    commit 128
 3
 4commit fae3dfb00a8f28c29e5f163dc07f3847a9a50928
 5Author: Shay Nehmad <shay.nehmad@guardicore.com>
 6Date:   Tue Jun 2 17:41:37 2020 +0300
 7
 8    commit 127
 9    
10    THE FLAG IS HIDDEN HERE
11    The flag is hidden here
12    the flag is hidden here
13    
14    The flag is originates-anagyrine-untolerative (log-3)
15--

flag = originates-anagyrine-untolerative

log-3 #

1> cat README.md
2The flag is hidden in one of the changes in this branch's history. I wrote "The flag is ..." to a file, and then deleted it.
3
4Find it.

time to find content within the commit history

1> git log -p -- justafile.txt | grep flag
2-The flag is belialist-interlaying-mize (log-4)
3+The flag is belialist-interlaying-mize (log-4)
4    The flag is hidden here
5    the flag is hidden here
6    The flag is originates-anagyrine-untolerative (log-3)
7    Look at my grandparent commit message to find the flag...
8    The flag is insatiably-skyjackers-program (log-2) ^_^

flag = belialist-interlaying-mize

log-4 #

1> cat README.md
2The flag is hidden 198 commits before this one.
3
4Find it, but don't start manually counting ¯\_()_/¯

okay so now we need something that can pick a N number of commits before

1> git log HEAD~198
2commit 0548382e835a5dad7e4731c6af08dc2e9eacd53d
3Author: Shay Nehmad <shay.nehmad@guardicore.com>
4Date:   Tue Jun 2 23:31:23 2020 +0300
5
6    pamphletary-harnessing-petticoaterie

flag = pamphletary-harnessing-petticoaterie

log-5 #

1> cat README.md
2This level is not a challenge, but a code for later. 
3Write down this flag: log-flag-meteorical

huh?

okay maybe flag = log-flag-meteorical

turns out this is the last log level anyways, will just keep track of this. let’s tackle rebase

rebase #

rebase-1 #

things may start getting rough on this one

 1> cat README.md
 2In this level, we have a **base** branch and a **topic** branch.
 3
 4The base branch is		parallelizing-barnhardtite-base
 5and the topic branch is		parallelizing-barnhardtite-topic
 6See the difference:					   ^^^^^
 7
 8The base branch introduced the script which prints all the resources in the `runme_resources/` folder. 
 9
10In the topic branch, we will need to add specific resources. To do this, run the `add_resources.sh` script and commit the new changes. Make sure you also remove the `add_resources.sh` script! There's no need for it in the base branch!
11
12We will get diverging histories. Instead of merging and pushing, we want to rebase the topic branch on the base branch, and push a clean, linear history.
 1> gco parallelizing-barnhardtite-topic
 2> chmod +x add_resources.sh  # the script was not executable mode
 3> rm add_resources.sh
 4> git add .
 5> gc -m 'changes'
 6> git rebase -i parallelizing-barnhardtite-base
 7> gco parallelizing-barnhardtite-base
 8> git rebase -i parallelizing-barnhardtite-topic
 9> git push
10remote: You won! The flag is downfalling-bumbled-sootiness (rebase-2)

okay got this one to eventually work but not sure if I did everything perfect. I initially rebased parallelizing-barnhardtite-topic on parallelizing-barnhardtite-base and tried pushing but ran into an error. on closer reading of the instructions, I realized I needed to push the base branch. so I checked out the base branch, rebased the changes of the topic branch onto the base branch, and hoped for the best.

flag = downfalling-bumbled-sootiness

rebase-2 #

 1> cat README.md
 2# rebase-2
 3
 4In this level, the commits are all out of order.
 5Reorder them using an interactive rebase, and push
 6this branch with the commits in the correct order.
 7
 8The correct order is:
 9
10> First base: Who
11> Second base: What
12> Third base: I Don't Know

this one seems pretty easy honestly

 1> git rebase -i origin/master
 2pick 86a5b92 updating README for the stage.
 3pick 32a2878 add empty "base" files
 4pick bd7753b What's on second
 5pick 8e1009e I don't know's on third
 6pick 376b18e Who's on first
 7# edit the file to move the last commit to 3rd
 8pick 86a5b92 updating README for the stage.
 9pick 32a2878 add empty "base" files
10pick 376b18e Who's on first
11pick bd7753b What's on second
12pick 8e1009e I don't know's on third
1> git push --force
2remote: You won! The flag is rebase-levels-done-you-win (final)

flag = rebase-levels-done-you-win rebase finished

revert #

revert-1 #

1> cat README.md
2I committed some lines I didn't mean to to the runme.py file! Please undo my mistakes.

from the log, it’s pretty clear that the most recent commit should be reverted

1commit 1948a60c6ee8098fce8524b48426ec06b9938d58 (HEAD -> lomentaceous-mididae-hexadecane, tag: lomentaceous-mididae-hexadecane-tag, origin/lomentaceous-mididae-hexadecane)
2Author: Shay Nehmad <shay.nehmad@guardicore.com>
3Date:   Sat Jun 6 14:33:43 2020 +0300
4
5    Oops - didn't mean to commit this.
1> git revert 1948a60c6ee8098fce8524b48426ec06b9938d58
2> git push
3remote: You won! The flag is redamage-bundh-passerina (tag-1)

flag = redamage-bundh-passerina

tag #

ngl, I have no idea what git tags are

tag-1 #

1> cat README.md
2To pass this stage, push a new lightweight tag called my-new-tag that tags this commit.

time for some chat gpt … looks like they are either simple messages or rich metadata that can be attached to a commit

let’s do this

1> git tag my-new-tag
2> git push origin my-new-tag
3remote: You won! The flags are
4remote: individually-nonintroversive-chalcomancy (tag-2)
5remote: hands-trooshlach-nongassy (hooks-1)

flags = individually-nonintroversive-chalcomancy & hands-trooshlach-nongassy

tag-2 #

1> cat README.md
2The flag is *in* the tag of the commit previous to this.

let’s look at the log

1> git log
2commit bee5d7a8c47f3a2016e4558ba81aa7ece1cf0134 (tag: individually-nonintroversive-chalcomancy-flag)
3Author: Shay Nehmad <shay.nehmad@guardicore.com>
4Date:   Fri Jun 12 02:32:27 2020 +0300
5
6    commit 10

let’s see what’s in this tag

 1> git show individually-nonintroversive-chalcomancy-flag
 2tag individually-nonintroversive-chalcomancy-flag
 3Tagger: Shay Nehmad <shay.nehmad@guardicore.com>
 4Date:   Fri Jun 12 02:33:43 2020 +0300
 5
 6You found the flag :)
 7
 8<E2><95><B0>(*<C2><B0><E2><96><BD><C2><B0>*)<E2><95><AF>
 9
10This is a final flag, write it down:
11
12nine-botchy-remarker (final)

flag = nine-botchy-remarker

tags finished!

hooks #

hooks-1 #

1> cat README.md
2**For this stage, you must run the script setup_hooks_stage.sh first!**
3
4You need to add more than 100 files into the `add_files_here` directory, and you can't do it in more than 3 commits. Shouldn't be too hard, should it?

seems simple but there must be more to it

1> for x in {1..100} ; do touch file$x ; done
2> ga .
3> gc -m '100 files'
4You're trying to add too many files at once! I only allow one file at a time, but you are trying to add 101!

let’s check what the pre-commit hook is doing

1> cat githooks/pre-commit
2#!/bin/sh
3how_many_new_files=$(git status -s | grep '^A' | grep add_files_here | wc -l) 
4
5if [ $how_many_new_files -ne 1 ]; 
6then
7    echo "You're trying to add too many files at once! I only allow one file at a time, but you are trying to add "$how_many_new_files"!"
8    exit 1
9fi

let’s just make this true

1...
2if [ true ];

and attempt again

1> gc -m '100'
2> git push
3remote: You won! The flags are
4remote: cyprus-akees-metope (hooks-2)
5remote: geared-tidal-consolidated (remote-1)

flags = cyprus-akees-metope & geared-tidal-consolidated

hooks-2 #

1> cat README.md
2**For this stage, you must run the script setup_hooks_stage.sh first!**
3
4Try to commit something.
5
6Note: Make sure you undo what the previous stage did! If you're unsure what it did, go back and make sure you do understand it.

let’s check to make sure that the previous pre-commit hook doesn’t do anything

1> file .git/hooks/pre-commit
2.git/hooks/pre-commit: broken symbolic link to ../../githooks/pre-commit

will need to remove that broken symlink

1> rm .git/hooks/pre-commit

now let’s try and commit something

1> gc -m 'try' --allow-empty
2Commit message: try
3Write 'git is awesome' in your commit message

need a specific commit message

1> gc -m 'git is awesome' --allow-empty
2> gc -m 'git is awesome' --allow-empty
3Commit message: git is awesome
4I agree; git is awesome!
5[cyprus-akees-metope aec100c] git is awesome
6> git push
7remote: You won! The flag is hooks-levels-done-you-win (final)

flag = geared-tidal-consolidated

hooks are cool I guess

remote #

remote-1 #

1> cat README.md
2To pass this stage you'll need a file with the correct password. This work has ALREADY been pushed to a different fork of this repository, which you'll find at 
3
4gamemaster@localhost:~/forked-ctf-repo
5
6You'll have to merge changes from the same branch on the remote.
7
8Note: no need to edit files in this stage, only git commands will suffice.

I’m thinking to add a new remote that points at the specified fork, merge changes from that remote, and push

1> git remote add fork gamemaster@localhost:~/forked-ctf-repo
2> git fetch fork geared-tidal-consolidated
3> git merge fork/geared-tidal-consolidated

nailed it

1> git push
2remote: You won! The flag is main-levels-done-you-win (final)

flag = main-levels-done-you-win

conclusion #

that was fun, probably took a couple hours over a couple days to get through everything


#blog #tech #git #ctf #git_ctf