Security implications of ANSI escape codes in Git sever responses
SummaryThe Git client does not validate messages received from a Git server, and will print anything received, including ANSI escape codes, to the terminal. The security implications of allowing ANSI escape codes to be written to the terminal depend on terminal, shell, resources and configuration options, but can vary from messing up a user's terminal configuration to execution of arbitrary commands.
This lack of client-side validation can be exploited by running a malicious Git server, or though a MITM attack.
For an overview of the types of attacks which are possible with ANSI escape codes, here are some useful links: 1, 2, 3.
ExampleThe remainder of this article will be devoted to demonstrating this discovery in action.
Setting up git serverTo start the git server, I used the command:
git daemon --enable=receive-pack --verbose --base-path=/home/user/git --export-all
"--enable=receive-pack" allows anyone - unauthenticated - to push to your git server. It's a good feature to enable for testing, but whatever you do, do not expose it to the internet. You don't need it to follow along with this blog post.
"--base-path" should point to the "root" of your Git server (kind of like how "/var/www/html" is the root of some Unix web servers).
Then, we create a repository:
echo "Hello" > file1
echo "Goodbye" > file2
git add file1 file2
git commit -m "Initial commit"
Intercepting and modifying packetsInstall the NoPE Proxy extension for Burp Suite. In the "Server Config" tab of NoPE Proxy, add a proxy with Server Address localhost, Server Port 9418 and any port number for Listen Port (I used port 1000).
Then, on the "TCP Intercept" tab, click the button marked "Intercept is OFF". It should then say "Intercept is ON".
Now, to run our requests through the proxy, we use the command:
git clone git://localhost:1000/repo
Skip through all of the packets until you get to one that contains the text "Counting objects" (see below) . You can skip through packets by clicking on the button directly to the right of the "Intercept is ON" message.
As we can see, these are the messages that the server is sending to be displayed in the client.
You can modify these, but if you change the length of a line, you must also change the four digit length at the start of the line to match.
To insert these escape codes into the packet, change to "Hex" mode. The ASCII/hex representation of the escape codes is:
1b 5b 33 30 6d 1b 5d 31 31 3b 3f 07
Here is an example of what your modified packet should look like:
Once the client receives the packet, we see the following output:
The meaning of the escape sequenceNow, to explain the escape sequence:
\033[30m changes the font color to black, so the user will not be able to see any more text output from the terminal, assuming that they currently have a black background.
\033]11;?\007 displays some information about terminal colors. Importantly for us, bash displays the information to the command prompt, not the standard output, so it is as if the user had typed the information in themselves.
user@computer:~$ echo -ne "\033]11;?\007"
bash: 11: command not found
bash: rgb:0000/0000/0000: No such file or directory
The output from this command will always begin with "11;", so if the user hits ENTER after \033]11;?\007 is printed to the terminal, then they will execute the program named "11" in their PATH, if there is one.
Since the text is black, the user should hopefully not be able to see the command, and will instead see a message telling them to press ENTER, which most users will do, especially if a convincing reason is given (e.g. "Download interrupted. Press ENTER to continue.").
The only problem which remains is that most users don't have a program called "11" in their path. If an attacker's method of exploitation is to convince a user to clone a repository from a malicious git server, then in the instructions for downloading, they can simply add an instruction asking the user to change their PATH variable before cloning, or an instruction asking them to clone the repository into /usr/local/bin. The "11" program, of course, will just be contained in the git repository.
If a MITM method of exploitation is chosen, and you can't think of a way to get a program called "11" onto the user's computer, you will probably need to think of a better escape string.