Announcement

Collapse
No announcement yet.

Exploiting wildcards on Linux

Collapse
This topic is closed.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Exploiting wildcards on Linux

    http://www.net-security.org/article.php?id=2061

    Is this a real concern for most Linux users or not?
    Using Kubuntu Linux since March 23, 2007
    "It is a capital mistake to theorize before one has data." - Sherlock Holmes

    #2
    Am I right in thinking that this is only likely to be a problem on shared servers, as you wouldn't be likely to create those files yourself by accident?
    samhobbs.co.uk

    Comment


      #3
      Agreed Feathers McGraw!

      Comment


        #4
        From my POV, if you are the only user of your machine this "security risk" is no risk at all. You are not likely to create files with the names of shell command parameters.

        Tar has the following privileges:
        -rwxr-xr-x 1 root root 353840 Feb 4 07:16 /bin/tar
        It shows that world has execute privileges only, and doesn't need sudo unless paths are outside the home account.

        If the machine in question is a server then the * wild card will be a problem if one or more people who have access to an account on that server creates those malicious file and the shell.sh file. In the example given below, from the article, "leon" created the malicious files and the shell.sh file. His account name will be on the malicious files in the archive.tar file, revealing him as the culprit. Leon being able to hijack the tar command to execute a shell script as root is the least of his employer's problems.


        Code:
        Running [B]tar cf archive.tar *[/B] on a folder with these files seems pretty straightforward and benign.
         
        [root@defensecode public]# ls -al
        drwxrwxrwx.  2 user user  4096 Oct 28 19:34 .
        drwx------. 24 user user  4096 Oct 28 18:32 ..
        -rw-rw-r--.  1 user user 20480 Oct 28 19:13 admin.php
        -rw-rw-r--.  1 user user    34 Oct 28 17:47 ado.php
        -rw-rw-r--.  1 user user   187 Oct 28 17:44 db.php
        -rw-rw-r--.  1 user user   201 Oct 28 17:43 download.php
         
        The problem arises if the user created a couple of fake files and a shell script that contains any arbitrary command.
         
        [root@defensecode public]# ls -al
        drwxrwxrwx.  2 user user  4096 Oct 28 19:34 .
        drwx------. 24 user user  4096 Oct 28 18:32 ..
        -rw-rw-r--.  1 user user 20480 Oct 28 19:13 admin.php
        -rw-rw-r--.  1 user user    34 Oct 28 17:47 ado.php
        -rw-r--r--.  1 leon leon     0 Oct 28 19:19 [B]--checkpoint=1[/B]
        -rw-r--r--.  1 leon leon     0 Oct 28 19:17 [B]--checkpoint-action=exec=sh shell.sh[/B]
        -rw-rw-r--.  1 user user   187 Oct 28 17:44 db.php
        -rw-rw-r--.  1 user user   201 Oct 28 17:43 download.php
        -rwxr-xr-x.  1 leon leon 12 Oct 28 19:17 [B]shell.sh[/B]
         
        By using the * wildcard in the tar command, these files will be  understood as passed options to the tar binary and shell.sh will be  executed as root.
        "A nation that is afraid to let its people judge the truth and falsehood in an open market is a nation that is afraid of its people.”
        – John F. Kennedy, February 26, 1962.

        Comment


          #5
          Originally posted by GreyGeek View Post
          His account name will be on the malicious files in the archive.tar file, revealing him as the culprit.
          Sure, in this case, but there is no guarantees of that. The shell.sh could potentially do anything...including removing all traces of itself left on the machine (and in the archive.tar)

          But surely all good admins know to avoid (and how to avoid) bare wildcards in their commands (or any automated backup scripts they might use)...for a multitude of reasons and not just this one.

          Comment


            #6
            If you were hosting a shared server with shell access, how would you prevent this attack?

            Would you have to build tar yourself and remove those options (has anyone used them?), or is there another way of doing things?

            Kubicle, this sounds like I may be about to learn something ... can you see anything wrong with the way I have used wildcards in this script?

            Code:
            #! /bin/bash
            # Backup script for www.samhobbs.co.uk
             
            # USE FULL PATH
            BACKUP_DIR="/media/backup/website/"
            DRUPAL_DIR="/var/www/samhobbs/"
            ENCRYPTION_KEYWORDFILE="/home/sam/.mcryptpasswordfile"
             
            # External email address to send monthly encrypted backup files to
            EXTERNAL_EMAIL="you@yourexternalemail.com"
             
            # redirect errors and output to log file
            exec 2>&1 1>>"${BACKUP_DIR}backup-log.txt"
             
            NOW=$(date +"%Y-%m-%d")
             
             
            # Headers for log
            echo ""
            echo "#==================================================== $NOW ====================================================#"
            echo ""
             
            # Back up Drupal with Drush
            drush archive-dump default -r $DRUPAL_DIR --tar-options="-z" --destination=$BACKUP_DIR$NOW.tar.gz
             
            # clean up old backup files
            # we want to keep:
            #               one week of daily backups
            #               one month of weekly backups (1st, 8th, 15th and 22nd)
            #               monthly backups for one year
            #               yearly backups thereafter
             
            # seconds since epoch (used for calculating file age)
            SSE=$(date +%s)
             
            [B]FILES_LIST=( "$BACKUP_DIR"* )[/B]
             
            for file in "${FILES_LIST[@]}"; do
              if [[ $file = *20[0-9][0-9]-[0-9][0-9]-[0-9][0-9].tar.gz ]]; then
                FILENAME=$(basename "$file")
                FILENAME_NO_EXTENSION=${FILENAME%%.*}
                FILE_YEAR=$(echo $FILENAME_NO_EXTENSION | cut -d'-' -f 1)
                FILE_MONTH=$(echo $FILENAME_NO_EXTENSION | cut -d'-' -f 2)
                FILE_DAY=$(echo $FILENAME_NO_EXTENSION | cut -d'-' -f 3)
                SSE_FILE=$(date -d "$FILE_YEAR$FILE_MONTH$FILE_DAY" +%s)
                AGE=$((($SSE - $SSE_FILE)/(24*60*60))) # age in days
                 
                # if file is from the first day of a year (yearly backup), skip it
                if [[ $file = *20[0-9][0-9]-01-01.tar.gz ]]; then
                  echo "file $file is a yearly backup: keeping"
             
                # if file is from the first day of a month (monthly backup) and age is less than 365 days, skip it
                elif [[ $file = *20[0-9][0-9]-[0-9][0-9]-01.tar.gz ]] && [ $AGE -lt 365 ]; then
                  echo "file $file is a monthly backup, age < 1yr: keeping"
             
                # if day of month is 08, 15 or 22 (weekly backup) and age is less than 30 days, skip it
                elif [ $FILE_DAY -eq 08 -o $FILE_DAY -eq 15 -o $FILE_DAY -eq 22 ] && [ $AGE -lt 30 ]; then
                  echo "file $file is a weekly backup, age < 30 days: keeping"
             
                # if age is less than seven days, skip it
                elif [ $AGE -lt 7 ]; then
                  echo "file $file is a daily backup, age < 7 days: keeping"
                 
                # if it hasn't matched one of the above, it should be deleted
                else
                  echo "removing file $file"
                  rm $file
                fi
              else
                echo "file $file does not match the expected pattern: skipping"
              fi
            done
             
            DAY=$(date +%d)
             
            if [[ $DAY = 01 ]]; then
              echo "encrypting a copy of today's backup to send by email"
              # encrypt today's backup file using mcrypt
              mcrypt -F -f $ENCRYPTION_KEYWORDFILE $BACKUP_DIR$NOW.tar.gz
               
              # if the encryption is successful, email the file to an external email address
              if [[ -f $BACKUP_DIR$NOW.tar.gz.nc ]]; then
                echo "Monthly backup created $NOW, encrypted using mcrypt" | mutt -s "Monthly backup" -a $BACKUP_DIR$NOW.tar.gz.nc -- $EXTERNAL_EMAIL
                echo "Email sent, removing encrypted file"
                rm $BACKUP_DIR$NOW.tar.gz.nc
                echo "Done"
              else
                echo "Something went wrong with mcrypt: the encrypted file was not found"
                exit 1
              fi
            fi
            Feathers
            samhobbs.co.uk

            Comment


              #7
              Originally posted by Feathers McGraw View Post
              Would you have to build tar yourself and remove those options (has anyone used them?)
              That would be both overkill (the options themselves are not the problem, and many of them are actually quite useful features) and a lot of work (you probably don't wish to hair-comb every command you could use for potentially exploitable options).

              There are many ways you can avoid filenames interpreted as options, one is using the '--' (end of options) in your commands, for example 'tar cf archive.tar -- *'.
              But generally you'll want to stay away from bare wildcards (just '*'), in this example you could use 'tar cf archive.tar ./*'

              Depending on the globbing options you have set for your shell, wildcard matching can also lead to unexpected results (dot-globbing or no-match, are just a few examples), but this is a bit too extensive topic to handle in a short post...you'll likely find good tutorials/guides for your shell (bash, zsh etc.) online.

              Originally posted by Feathers McGraw View Post
              Kubicle, this sounds like I may be about to learn something ... can you see anything wrong with the way I have used wildcards in this script?
              I see no bare wildcards there, on quick glance.

              Comment


                #8
                It's here:

                Code:
                FILES_LIST=( "$BACKUP_DIR"* )
                unless that's not what a bare wildcard is?
                samhobbs.co.uk

                Comment


                  #9
                  Originally posted by Feathers McGraw View Post
                  It's here:

                  Code:
                  FILES_LIST=( "$BACKUP_DIR"* )
                  unless that's not what a bare wildcard is?
                  Yeah, that's not a bare wildcard as it includes the path element ( it's not '*', it's '/media/backup/website/*' )

                  Comment


                    #10
                    Thanks!
                    samhobbs.co.uk

                    Comment


                      #11
                      Originally posted by kubicle View Post
                      Yeah, that's not a bare wildcard as it includes the path element ( it's not '*', it's '/media/backup/website/*' )
                      And, your reg expression parses for correct file names:
                      Code:
                        ...
                       # if it hasn't matched one of the above, it should be deleted
                          else
                            echo "removing file $file"
                            rm $file
                          fi
                      ...
                      "A nation that is afraid to let its people judge the truth and falsehood in an open market is a nation that is afraid of its people.”
                      – John F. Kennedy, February 26, 1962.

                      Comment


                        #12
                        Nice discussion. When one's philosophy is to treat everything as a file, it can indeed become difficult to understand where to draw the line.

                        The Reddit post in the linked article had a humorous entry:
                        ./* &
                        Very clever. Anyone care to venture a guess?

                        And the DefenseCode advisory was rather illuminating.

                        Comment

                        Working...
                        X