Before you go, check out these stories!

0
Hackernoon logoHow to Hack GitHub (kind of) by@priansh

How to Hack GitHub (kind of)

Author profile picture

@prianshPriansh Shah

A commit a day keeps the bugs away! But weโ€™ll be doing 100 commits a day.

Itโ€™s no secret that GitHubโ€™s contribution chart isnโ€™t very secure. In fact, by pushing a repository with pre-configured commit history, you can gain the commits as contributions.

I love coding. I really do. And I really love open source. When I started out, open source was my favorite thing to do: build software, release it for everyone, and contribute to othersโ€™ projects.

Itโ€™s something I still love to do, but itโ€™s something Iโ€™ve been forced to sacrifice. Recently, I started working fulltime on Aiko AI, a startup aiming to bring the benefits of advances in AI to the general public by integrating them into everyday products. Weโ€™re behind popular products like Aiko Meet and Aiko Mail and our recent success has meant that I have had less and less time to do open source work.

Unfortunately, this means I had to choose between my passion for Aiko and my love for open source. Iโ€™ve continued to work on open source projects every now and then, but Aiko has taken priority, and that means I canโ€™t commit with the frequency I used to.

And that means my contribution chart will dry upโ€Šโ€”โ€Šunless we fill it up with commits ๐Ÿ˜‰

Sneak peek of my contribs chart in 2ย months

For those of you who donโ€™t frequent GitHub often, the contribution chart tracks your commits on a daily basis to see your coding activity/cointributions to open source over time. It is simultaneously the weirdest of all flexes and a nice little trophy to show for your open source efforts.

So much so that even some employers will look at your GitHub contribution chart to gain an idea of just how much of an avid coder you really are. Of course this isnโ€™t really a reflection of your coding ability; you may not use GitHub often, or you may be developing mostly closed source. Perhaps youโ€™re in a role where you commit infrequently but with large features/heavy loads. Or perhaps you look to this chart and feel a sense of insecurity as you think, all my friends have more GitHub commits!

Whether itโ€™s necessity, curiosity, or impostor syndrome that motivates you, thereโ€™s an easy fix to thisโ€Šโ€”โ€Šjust get a bunch of open source commits!

Of course this would take time and you canโ€™t go back and edit your historyโ€Šโ€”โ€Šor can you? Iโ€™m going to be showing you how to hack GitHubโ€™s contribution chart, and get that green pasture you yearn for so much.

Pictured: the hacker known asย _____

Before I get started Iโ€™ll point you towards Gitfiti, another project based on the same system that lets you draw art on your GitHub contributions.

Rather than art, weโ€™ll focus on commit history to gain fraudulent commits! Iโ€™ll try my best to explain what I can about bash, but this assumes some familiarity with terminal and gitโ€” if youโ€™re not comfortable with a CLI, I recommend you check out Bash Academy before diving into this.

Just want the script? Here it is.

Donโ€™t want to code? Check out Github Gardener, a free to use website thatโ€™ll help you out!

How Itย Works

Exploiting commit history we can โ€œauthorโ€ commits using gitโ€™s commit timestamps.

Letโ€™s start by authoring one commit at a date of our choice. To accomplish this weโ€™ll need to change two environment variables that git uses to set the commit timestamp, GIT_COMMITTER_DATE and GIT_AUTHOR_DATE. These two variables hold standard YY-MM-DD HH:MM:SS ISO format timestamps. Weโ€™ll also commit on that timestamp to cover all the basesโ€Šโ€”โ€Šthis way we can be completely sure that there is no way to differentiate our fake commit from one actually at that point in time.

export Y = 2000
export M = 12
export D = 20
export GIT_COMMITTER_DATE="$Y-$M-$D 12:00:00"
export GIT_AUTHOR_DATE="$Y-$M-$D 12:00:00"
git commit --date="$Y-$M-$D 12:00:00" -m "Committed on $M $D $Y"

This above snippet will โ€œauthorโ€ a commit from 12/20/2000. This can also be extended to โ€œauthorโ€ a commit from, say, 1/1/1970; way before you could have possibly coded this! As a result, your โ€œgitโ€ history is vulnerable (and not, in fact, a โ€œhistoryโ€, itโ€™s more a collection of pre-authored structures).

Write your own history! Didnโ€™t turn out so great for Churchill thoughโ€ฆ

We can then extend this to author a commit history every day from a set date. This is trivially achieved using a bash for loop, with structure:

for VAR_NAME in {start..end}

The indented block following will be able to use $VAR_NAME as a variable in its execution. As a result, bash for loops become ideal for us as we can iterate through years, months, and days, to author fake commit histories.

Letโ€™s Make Aย Script

The final version of this script is available as a Gist here.

We can achieve this โ€œexploitโ€ by looping through years, months, and days in that order:

for Y in {1999..2018}
for M in {01..12}
for D in {01..28}

We loop through every year from 1999 to 2018 (I chose 1999 as a guess pre-2000). We then loop through each month, and finally each day. Note that we only loop from 1 to 28, as February can be a 28 day month! We could loop through every day if we wanted to, but it wouldnโ€™t be valid for February; in this case you can use a conditional to select the days. Another approach Iโ€™ considered is using Python to set the year, month, and day to weekdays in order to choose only working daysโ€Šโ€”โ€Šwhichever you pick is up to you! Iโ€™ll stick with 1โ€“28 as this works the best from a speed perspective (it can take some time to author this many commits).

We also need to create a new file each time:

echo "Committed on $M/$D/$Y" > commit.md

Hereโ€™s a completed script to just create files and commit them en masse:

for Y in {1999..2018}
do
mkdir $Y
for M in {01..12}
do
cd $Y
mkdir $M
cd ../
for D in {01..28}
do
cd $Y/$M
mkdir $D
cd $D
echo "Committed on $M/$D/$Y" > commit.md
cd ../../../
export GIT_COMMITTER_DATE="$Y-$M-$D 12:00:00"
export GIT_AUTHOR_DATE="$Y-$M-$D 12:00:00"
git add $Y/$M/$D/commit.md -f
git commit --date="$Y-$M-$D 12:00:00" -m "$M $D $Y"
git push origin master
done
done
done

This will then author commits from 1999 to 2018. You can execute this from any bash prompt--I recommend placing it in an executable bash file and running that.

But this is clearly extremely slow! How can we make this faster?

  1. First off, unless you have nested git repos, we donโ€™t need to traverse back up the directory tree each time we commit.
  2. It also turns out that the โ€œpushโ€ to GitHub doesnโ€™t take into account the timestamps present (hence allowing you to push your old local git repos to GitHub), so we can just push at the end of our script.
  3. Lastly, while not really a speed enhancement, adding support for days 29 through 31 doesnโ€™t really affect our performance anymore with the above improvements, and GitHub will sanitize extra days automatically.

This increases the speed tenfold, and we can reach greater heights by pushing at the end.

for Y in {1999..2018}
do
mkdir $Y
cd $Y
...
git add commit.md -f
git commit --date="$Y-$M-$D 12:$i:00" -m "$i on $M $D $Y"
done
cd ../
done
cd ../
done
cd ../
done
git push origin master

Implementing these changes, along with removing the folders at the end for cleanup, we arrive with the final script:

Youโ€™ll notice Iโ€™ve introduced another bash loop with variable iโ€Šโ€”โ€Šthis controls how many commits are made each day, and can be used with this much, much faster script. If you get an โ€œinvalidโ€ date format error, please check youโ€™re using a date that exists after computers (the earliest date you can do is January 1, 1970), and that your version of bash is new enough to support leading zeroes in for loops.

The neatest part about this is that it authors commits in the FUTURE.ย 
This means that in the future you will have a commit every day!

Iโ€™ve put the completed script here. (shortlink: git.io/vxnon)

Example Run-through:

priansh@laptop:~$ cd ~/Documents/github
priansh@laptop:~$ mkdir gitsploit # make the repo folder anywhere
priansh@laptop:~$ cd gitsploit && git init
priansh@laptop:~$ # Next we'll set up tracking a GitHub repo
priansh@laptop:~$ git remote add origin <YOUR GITHUB REPO LINK HERE>
priansh@laptop:~$ echo "Hello World" > README.md && git add --all
priansh@laptop:~$ git commit -m "init" && git push -u origin master
priansh@laptop:~$ wget https://git.io/vxnon -O a_million_commits.sh
priansh@laptop:~$ chmod a+x a_million_commits.sh # make executable
priansh@laptop:~$ ./a_million_commits.sh

Post-Mortem

Iโ€™ll mention that GitHub can also be further exploited using bots (as they have no captcha!) and used for stars, follows, and more, although I wonโ€™t cover that in this quick article (nor do I encourage this as it borders on malicious).

Just a quick pic to prove this works:

20k commits!

You can delete the repo youโ€™re committing to in order to remove the fake history, or make it private and set contribution settings to public only, to accomplish the same effect as removing the fakes from your chart. (You can also overwrite the branch/commit history entirely.)

While weโ€™re not exploiting GitHub in a malicious way, this is still somewhat significant as some companies check your contribution count in the hiring processโ€Šโ€”โ€Šmeaning this could (potentially) affect your chances of landing a job. It will also make you the coolest kid at recess. Happy โ€œhacking!โ€

Like this, and more? At Aiko AI, we love open source projects and exploring and visualizing data!

Tags

Join Hacker Noon

Create your free account to unlock your custom reading experience.