Posted on 29th October 2018 by Paul Ritchie

This is release three of three tools from my talk "Hacking with git" which I delivered at Glasgow BSides in 2018. The video of that talk is available at the URL below:

https://blog.secarma.co.uk/labs/hacking-with-git-the-video

The pace of the talk was structured to build to the crescendo where a reverse shell was delivered over GitHub. This post is about a proof-of-concept (PoC) tool which was generated to do that.

The code for this is available over at GitHub here:

https://github.com/cornerpirate/gitshell

If you have any questions then you can ping me on Twitter @cornerpirate or raise a ticket on GitHub.

Nothing new under the sun

While I had this idea many moons ago I realised I wasn't the first to implement a reverse shell over GitHub by the time of my talk in April 2018. There was at least one I could find. I am a fan of implementing my own stuff when I have the time available.  Give someone a fish and they will say "why are you giving me raw fish?" and "can you cook this for me too?". Make your own fishing net, and go catch fish and you have learned a lot of stuff. You will now be in the business of selling fish instead of just being a consumer. I urge you to make your own nets folks.

To be clear this is me not claiming ownership or even first implementation rights over the idea. Also saying you should live a little and implement your own stuff more :D.

Concepts of a Reverse Shell

I am assuming that pretty much everyone reading this knows what a reverse shell is. Sometimes it is nice to start simple though so:

  • A "Shell" is a term used to describe a command prompt. On windows that is "cmd.exe" or "powershell.exe" are examples, while Linux has a whole array of them with Bash being arguably the most popular. The idea is that you enter your commands into the prompt and the output is displayed to you.
  • A "Reverse Shell" is enabling access to the command prompt remotely by connecting it back to an attacker.

When an attacker establishes a reverse shell they have established remote interactive command execution on their target and it is definitely with malicious intent. Any traffic which traverses between network boundaries can be used for this so they are common over: TCP, UDP, ICMP, DNS, HTTP/HTTPS etc. Whatever a firewall allows out and in can be used.

A command prompt or shell is made of three  so-called "standard" communication streams:

  • stdin - input to the prompt. This would be the commands you type and their arguments.
  • stdout - output from the commands which are displayed in the command prompt window.
  • stderr - when exceptional circumstances occur well behaved programs present that info to stderr.

The following image (by Danielpr85) plots out how a process interacts with these streams:

Diagram explaining standard input, output and error streams

The trick for a reverse shell is to map these input and output streams to a network communication channel.

In the git shell PoC the channel is a commit over HTTPS to GitHub.com into a repository.

Priming a repository

The communication channel is a GitHub.com hosted repository. To prep yours follow these steps:

  1. Create a unique public repository. In theory you can use private repositories if you have a paid subscription but I don't so mileage may vary here. As this is a PoC only I have never exposed customer data to a public repository and neither should you.
  2. In your repository create two files. One called "in.txt" and the other "out.txt".

Nobody said this would be complicated! You should have something that looks like this:

02-added-files

That is all you need.

How does the Shell Work?

The "in.txt" file becomes the "stdin" stream meaning that an attacker places commands to execute in this file.  While the "out.txt" file is a merge of both "stdout" and "stderr" and is updated by the victim. For the coders in the room the algorithms are simple on both sides:

Algorithm on Victim's Side

  1. Clone the repository down.
  2. While True
    1. Git Pull - get the most recent changes from github.com
    2. Check If "in.txt" is modified.
    3. Decrypt "in.txt"
    4. Execute command from "in.txt", encrypt output and save into "out.txt"
    5. Git Commit - save changes to "out.txt" in local repository
    6. Git Push - upload our changes to github.com
    7. Wait – for a number of seconds.

Algorithm on Attacker's Side

  1. Clone the repository down.
  2. While True
    1. Git Pull - get the most recent changes from github.com
    2. Check If “out.txt” is modified and display results if it is.
    3. Read attacker’s input into “cmd”
    4. Encrypt and save “cmd” into "in.txt"
    5. Git Commit - save changes to "in.txt" in local repository
    6. Git Push - upload our changes to github.com
    7. Wait – for a number of seconds.

As I had limited time to develop the PoC the encryption parts of the shell have not been implemented yet. This is bleeding edge because it means the command output and history will remain in your repository, A MAJOR RISK IF YOU STICK CUSTOMER DATA IN THERE.

I would not suggest using this on engagements without implementing cryptography.

How to use the PoC

The PoC is configured to work on Windows targets with .Net 4.6.2 or newer installed. 

GitHub removed support for TLS 1.1 or lower meaning that older clients can no longer connect. Well done to GitHub for stamping out older protocols but it does limit the effectiveness of the PoC somewhat. A fully patched Windows 7 or supported Server version would work for sure.

Generate an authentication token. To do this when logged into GitHub visit this URL:

https://github.com/settings/tokens

As a minimum the token needs commit access to your respository so simply enable those:

03-generate-github-token

You need to obtain the PoC from GitHub here and upload the code to your victim by whatever means and then execute it. Once it is running it will prompt you for the URL to your repository, and your authentication token.

The attacker needs to run the "gitshell-attacker.py" script with command line arguments for the repo URL, token, and path to an empty folder such as "/tmp/something". They will then be able to execute commands and with a bit of patience get the responses:

04-GitShellExample

The output is a bit over the top at the moment but you can see what is going on.

Caveats

While several have been stated throughout it makes sense to just be clear:

  • This is a proof of concept. Do not use this on customer engagements unaltered. You would be exposing their data.
  • Treat your GitHub token carefully. This is as good as your credentials. Do not use a token for a github account you care about. Technically you will be exposing them to the victim PC where blue team analysis will then have the keys to your house.
  • My intent was to create something that operated through corporate proxies. Indeed a lot of code in the victim side is in development to enable this. What initially looked as if it worked turned out to be false because the "libgit2sharp" library does not honour sytem proxy settings. Part of the reason this has taken months to release publicly was the hope that the open tickets on the project for proxy support would have been addressed by now. They have not and it is still essentially the top question on the project.

Conclusion

This demonstrates that a reverse shell over GitHub is absolutely possible. It is at least the second tool to do this. This is not a vulnerability in GitHub, a Zero day or in anyway anything which should tarnish the reputation of GitHub. An attacker with any access to the Internet from inside your network can find some means of establishing remote control. This is just a fun way of doing it using git's commands to do so.

This is my final post in the series of tools on "Hacking with Git". It is also my final submission to SecarmaLabs because I have chosen to seek pastures new. It leaves me with a tear in my eye since I have been involved in all aspects of SecarmaLabs since it was founded. It was my whimsy to plaster this code all over the place:

  10 Print "Research"
  20 Print "Share"
  30 Goto 10
  

I believe in research, sharing that and passing things on. That also means passing on the reigns to the next generation when it comes time to do so. I leave SecarmaLabs in excellent hands and they will do fantastic things with it!