COMP 3000 Lab 5 2011: Difference between revisions

From Soma-notes
Saran (talk | contribs)
No edit summary
Saran (talk | contribs)
 
(8 intermediate revisions by the same user not shown)
Line 9: Line 9:
Be sure to do the following questions in order.
Be sure to do the following questions in order.


# Run the command <tt>truncate -s 2G foo</tt>.  What is the logical size of foo, and how much space does it consume on disk?
# [0.5] Run the command <tt>truncate -s 2G foo</tt>.  What is the logical size of foo, and how much space does it consume on disk?
# Run <tt>mkfs.ext4 foo</tt>.  (Say "yes" to operating on a regular file.)  What is the logical size of foo now, and how much space does it now consume on disk?
# [0.5] Run <tt>mkfs.ext4 foo</tt>.  (Say "yes" to operating on a regular file.)  What is the logical size of foo now, and how much space does it now consume on disk?
# Run <tt>mount -o loop foo /mnt</tt>.  What does this command do?
# [0.5] Run <tt>mount -o loop foo /mnt</tt>.  What does this command do?
# Run <tt>cp /bin/ls /mnt</tt>.  What does this command do?
# [0.5] Run <tt>cp /bin/ls /mnt</tt>.  What does this command do?
# Run <tt>umount /mnt</tt>.  Can you still access /mnt/ls?  Why or why not?
# [0.5] Run <tt>umount /mnt</tt>.  Can you still access /mnt/ls?  Why or why not?
# Run <tt>dd if=/dev/zero of=foo conv=notrunc count=10 bs=512</tt>.  What does this command do?
# [0.5] Run <tt>dd if=/dev/zero of=foo conv=notrunc count=10 bs=512</tt>.  What does this command do?
# Run <tt>mount -o loop foo /mnt</tt> again.  Why did the command fail?
# [0.5] Run <tt>mount -o loop foo /mnt</tt> again.  Why did the command fail?
# What command can you run to make foo mountable again?
# [0.5] What command can you run to make foo mountable again?


==Part B==
==Part B==
# Create a simple C program to generate a file consisting of the word "Hello", one million bytes of blank space (null bytes), and then "world\n", but that consumes only a small number of blocks on disk while having a logical size of 1,000,011 bytes.
# [2] Create a simple C program to generate a file consisting of the word "Hello", one million bytes of blank space (null bytes), and then "world\n", but that consumes only a small number of blocks on disk while having a logical size of 1,000,011 bytes.
# Create a C program "mycopy.c" that takes two filenames A and B as command line arguments.  This program should copy the contents of A to B, making B a byte-for-byte copy of A.  Zero bytes in A should consume little to no space in B.  (Hint: You'll have to use the sparse file creation technique of the previous question here.)
# [2] Create a C program "mycopy.c" that takes two filenames A and B as command line arguments.  This program should copy the contents of A to B, making B a byte-for-byte copy of A.  Zero bytes in A should consume little to no space in B.  (Hint: You'll have to use the sparse file creation technique of the previous question here.)
# Describe a simple way an attacker could get root access on a system if loopback mounts were permitted for non-privileged users.
# [2] Describe a simple way an attacker could get root access on a system if loopback mounts were permitted for non-privileged users.


=Answers=
=Answers=
Line 29: Line 29:
# It links foo to an unused loop device and mounts it in /mnt.
# It links foo to an unused loop device and mounts it in /mnt.
# It copies the file located at /bin/ls to /mnt, indirectly writing it to foo.
# It copies the file located at /bin/ls to /mnt, indirectly writing it to foo.
# After unmounting, files in that file system cannot be accessed, because /mnt is not linked to foo (where /bin/ls is actually stored as a file) anymore.
# This command copies 10 blocks of 512 bytes each from /dev/zero to foo.  
# This command copies 10 blocks of 512 bytes each from /dev/zero to foo.  
# Because writing 5120 bytes of zeros to the filesystem at foo corrupted it, destroying the superblock and invalidating some checksums.
# Because writing 5120 bytes of zeros to the filesystem at foo corrupted it, destroying the superblock and invalidating some checksums.
Line 34: Line 35:


==Part B==
==Part B==
#  
# 1.c
# 2.c
# An attacker could open foo, modify an [http://lxr.linux.no/linux+v3.1/include/linux/fs.h#L748 inode] to add set setuid and setgid bits and modify the owner and group of the file to 0,0 ( i.e root,root). She would then mount foo and run this file - which would run as root - to gain root privileges. Note that this method does not require you to assume that loopback mounting is permitted on non-writable directories.


/* 1.c */
  #include <sys/types.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <sys/stat.h>
Line 52: Line 56:
  }
  }


#
/* 2.c */
 
  #include <sys/types.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <sys/stat.h>
Line 66: Line 69:
         int fdi,fdo,ret;
         int fdi,fdo,ret;
         char buf;
         char buf;
  if( (fdi = open("inputfile",O_RDONLY)) == -1)
        if( (fdi = open("inputfile",O_RDONLY)) == -1)
                 exit(1);
                 exit(1);
         if( (fdo = open("outputfile",O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
         if( (fdo = open("outputfile",O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
Line 83: Line 86:
                 if(ret == -1)
                 if(ret == -1)
                         printf("Error = %s\n",strerror(errno));
                         printf("Error = %s\n",strerror(errno));
                 else if(ret == 0) //indicated EOF
                 else if(ret == 0) //indicates EOF
                         break;
                         break;
         }
         }
Line 90: Line 93:
         return 0;
         return 0;
  }
  }
# An attacker could open foo, modify an [http://lxr.linux.no/linux+v3.1/include/linux/fs.h#L748 inode] to add set setuid and setgid bits and modify the owner and group of the file to 0,0 ( i.e root,root). She would then mount foo and run this file - which would run as root - to gain root privileges.

Latest revision as of 16:59, 21 November 2011

A few guidelines:

  • Submit your solutions for both Part A and Part B via WebCT by Sunday, November 6th at 11:30 PM.
  • Please answer using a single text file (with a .txt extension). Do not submit doc, docx, pdf, or other formats. Also, please do not submit an archive (zip, tarball, rar) of multiple text files, just upload one. (Please don't just cut and paste your work into a text box on webct.) Anything other than a single text file will receive -1 points
  • Show all your work. Short answers are not sufficient; you should list any websites or individuals you consult and should document any experiments you conducted. For any question that you could just answer without any external reference or experiment, write "(no work required)" after your answer.
  • All submitted code and commands should compile and run. Partial code fragments or explanations may not be given credit. While code may use standard C and UNIX/Linux libraries, no code should rely on external binaries.
  • The exercises in this lab require root access on a Linux system. Note that an Ubuntu Live CD should be a sufficiently powerful environment if you do not have an already installed system. Just boot the CD in the VM and select "Try Ubuntu."

Part A

Be sure to do the following questions in order.

  1. [0.5] Run the command truncate -s 2G foo. What is the logical size of foo, and how much space does it consume on disk?
  2. [0.5] Run mkfs.ext4 foo. (Say "yes" to operating on a regular file.) What is the logical size of foo now, and how much space does it now consume on disk?
  3. [0.5] Run mount -o loop foo /mnt. What does this command do?
  4. [0.5] Run cp /bin/ls /mnt. What does this command do?
  5. [0.5] Run umount /mnt. Can you still access /mnt/ls? Why or why not?
  6. [0.5] Run dd if=/dev/zero of=foo conv=notrunc count=10 bs=512. What does this command do?
  7. [0.5] Run mount -o loop foo /mnt again. Why did the command fail?
  8. [0.5] What command can you run to make foo mountable again?

Part B

  1. [2] Create a simple C program to generate a file consisting of the word "Hello", one million bytes of blank space (null bytes), and then "world\n", but that consumes only a small number of blocks on disk while having a logical size of 1,000,011 bytes.
  2. [2] Create a C program "mycopy.c" that takes two filenames A and B as command line arguments. This program should copy the contents of A to B, making B a byte-for-byte copy of A. Zero bytes in A should consume little to no space in B. (Hint: You'll have to use the sparse file creation technique of the previous question here.)
  3. [2] Describe a simple way an attacker could get root access on a system if loopback mounts were permitted for non-privileged users.

Answers

Part A

  1. Logical size is 2G. Physical size is 0.
  2. Logical size is 2G. Physical size is 65M.
  3. It links foo to an unused loop device and mounts it in /mnt.
  4. It copies the file located at /bin/ls to /mnt, indirectly writing it to foo.
  5. After unmounting, files in that file system cannot be accessed, because /mnt is not linked to foo (where /bin/ls is actually stored as a file) anymore.
  6. This command copies 10 blocks of 512 bytes each from /dev/zero to foo.
  7. Because writing 5120 bytes of zeros to the filesystem at foo corrupted it, destroying the superblock and invalidating some checksums.
  8. fsck.ext4 foo

Part B

  1. 1.c
  2. 2.c
  3. An attacker could open foo, modify an inode to add set setuid and setgid bits and modify the owner and group of the file to 0,0 ( i.e root,root). She would then mount foo and run this file - which would run as root - to gain root privileges. Note that this method does not require you to assume that loopback mounting is permitted on non-writable directories.
/* 1.c */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main()
{
       int fd = open("helloemptyworld",O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
       if(fd == -1)
               exit(1);
       write(fd,"Hello",5);
       lseek(fd,1000000,SEEK_CUR);
       write(fd,"World\n",6);
       close(fd);
       return 0;
}
/* 2.c */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main()
{
       int fdi,fdo,ret;
       char buf;
       if( (fdi = open("inputfile",O_RDONLY)) == -1)
               exit(1);
       if( (fdo = open("outputfile",O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
               exit(1);
       if(read(fdi,&buf,1) == -1)
               printf("Error = %s\n",strerror(errno));
       while(1)
       {
               if(buf == 0)
                       lseek(fdo,1,SEEK_CUR);
               else {
                       if(write(fdo,&buf,1) == -1)
                               printf("Error = %s\n",strerror(errno));
               }
               ret = read(fdi,&buf,1);
               if(ret == -1)
                       printf("Error = %s\n",strerror(errno));
               else if(ret == 0) //indicates EOF
                       break;
       }
       close(fdi);
       close(fdo);
       return 0;
}