Project 6 – Computer Security
Errata
You can delete all “_notes” folders.
Introduction
The goal of this project is to make you more aware of software errors that impact a program’s security. You are given two Ruby programs that implement the client and server portions of a simplified FTP server. Your job is to find and fix security-relevant defects in these programs (without breaking normal operations).
You should get started right away. You will need to familiarize yourself with the code so that you can see its weaknesses.
Getting Started
Download the following archive file p6.zip and extract its contents.
Along with files used to make direct submissions to the submit server (submit.jar, .submit, submit.rb), you will find the following project files (among others):
- FTP client – client.rb
- Buggy FTP server – ftp.rb
- a directory containing some sample user files – users
- another users directory, used by the tests (so don’t change) – users_unfutzed
- Public tests
- test0 – logging in
- test1 – directory listing
- test2 – trying to get an absent file
- test3 – getting an available file
- test4 – putting a file
- test5 – listing the public directory
- test6 – trying to put an absent file
- test7 – listing without logging in
- test8 – writing a public file and trying to overwrite it
- test9 – writeing a public file and then downloading it
- test10 – changing users and listing directory contents
- test11 – trying to get a file without authenticating
- test12 – trying to get a public file without authenticating
- test13 – one user trying to get another’s file
- makeaccts.rb changes the passwords for user accounts and tests
- test.rb test harness in the tests directory
- runtests.rb – runs all of the public tests. Warning: will clobber the users directory with users_unfutzed
Running the FTP client and server
To use FTP, you have to start the FTP server in directory it is serving files from. It will listen on a particular TCP port for connection requests. A client then connects to the server on that port, and repeatedly sends it commands. These commands including getting (downloading) files, putting (uploading) files, listing directories, etc. A full list of commands is below.
Setup
The FTP server must be run in a directory with a subdirectory users. This directory contains a file accounts, which contains the list of usernames, passwords, and home directories (each, separated by a comma). The users directory also contains a subdirectory for each listed user, per the accounts file specification. Finally, it contains a subdirectory publicthat stores publicly readable files, and may contain files written by any user. User directories, and the public directory, contain no subdirectories. See below for how to set up these directories for testing on Grace.
Starting the server
To run the FTP server, in one window you can execute the command
ruby ftp.rb
You will see on the console something like this:
Starting server on TCP port 39010
This says that the server is now waiting to receive connections on TCP port 39010. The port is randomly generated. To use a specific port, you can enter it just after specifying server, i.e., by running ruby ftp.rb 1337 you specify port 1337. Please see below for picking a suitable port when testing on Grace.
Starting the client
Once you have started the FTP server you can connect to it with a client. In another window, execute the command
ruby client.rb 39010
Here, 39010 is whatever TCP port the server is listening on. If the client is able to successfully connect, you will see the following message:
Hi I'm a friendly FTP server >
The “greater than” is the command prompt. At this prompt you can enter commands that will be sent to the server for processing. To terminate a client connection, you can enter either CTRL-D or CTRL-C at the client prompt. When you do, the program will exit, and the server will print Closed connection.
Do not change the client. All the bugs are in the server. We will overwrite any client you submit with our own, during testing. You may restrict a given user to one active session (rather than potentially multiple sessions for the same user on different socket connections)
FTP commands
The FTP client accepts the following commands at the command prompt. These are translated into messages sent to/from the server to carry them out. Below we are describing how the commands should work, but because of bugs in the client and/or server code, they may not actually work this way — you have to figure out where the bugs are and correct them. (And there may be other bugs not evident in this description; see the discussion of the security model further down.)
Command | Argument | Description | Example |
---|---|---|---|
user | username | Specifies which user’s files we are interested in. However, we are not to be granted access to those files until entering a correct password with the pass command. | user josh specifies that Josh is the username. |
pass | password | Specifies the password of the user specified with the user command. If the password is correct, then the user is logged in and is given access to the user’s files. | pass 12345 specifies that the current user’s password |
get | filepath | Specifies a file to download. The format of legal filepaths is given below. The file will be placed in the current working directory of the client program. | get info.txt downloads the info.txt file assuming it is among the current user’s files on the server. get public/note.txt downloads the public file note.txt |
put | filepath | Specifies a file to upload. The format of legal filepaths is given below. The file will always be read from the client’s current working directory. If the filepath has the public/ prefix then it is placed in the public directory on the server. Otherwise it is placed in the current user’s files at the server, assuming a user has been specified along with a correct password. | put newinfo.txt uploads the newinfo.txt file to the current user’s directory (assuming one has been specified/authenticated) whereas put public/newinfo.txt puts the same file in the public directory. |
ls | none, or public | If no argument is given, lists the current user’s files (if specified and a password has been properly entered). If the public argument is given, then all of the public files are listed. | |
exit | none | Logs out the current user (if one was logged in) |
The filepath argument of the get and put has the following format. It consists of an optional public/ prefix, followed by any combination of (upper and lowercase) letters, numbers, dashes, underscores, and periods, with the exception that . and .. (alone) are not legal filenames. The following are examples of legal filepaths:
file.txt public/12ABxx .foo..BAR public/foo_bar--baz89
These are illegal filepaths:
public/bar/baz.txt ./public/bar.doc my daughter ate; lovely ..
The first is illegal because it has a slash in bar/baz.txt, which is not permitted. The second is illegal because public/ is the only legal prefix; ./ is not allowed. The third is illegal because the filename contains illegal space characters and a semi-colon, which is also illegal. The last is illegal because double-dot, on its own, is not a legal filename (but can appear in legal filenames, per the list of allowed examples).
What to do
Your job is to make sure that the FTP client/server enforces its security policy properly under certain assumptions.
Security policy
The FTP server aims to implement a basic confidentiality and integrity policy:
- A user may only read or write his own files on the server, and on his own client machine. He may read any public files, and may upload any files to the public directory, but only so long as no existing public files are overwritten.
It may be that bugs in the server allow this policy to be violated. Such bugs may result in direct compromise, e.g., user A is able to download B’s file because of a bug in the download functionality. Or they could result in indirect compromise, e.g., user A is able to log in as if he was B, without knowing B’s password. Or user A may be able to steal user B’s password somehow, and then use that to log in. Or, user A may be able to corrupt the server in some way that a client, run by B, damages its local files.
Attack model
The attacker is able connect to the server and interact with it from his own machine. The attacker may do so without running the proper client software, i.e., it could send messages to the server in any format in an attempt to confuse the server.
The attacker is not able to snoop on, or modify, messages sent between other clients and the server. I.e., the adversary does not have access to the network or a legitimate client’s machine.
What you can/should do
The most direct way to satisfy the project is to understand the code we have provided, find the bugs present in ftp.rb, and fix them. You will know that you have succeeded when all of the semipublic tests pass (and all of the public tests still pass). The names of these tests should give you a hint as to what vulnerabilities they are exploiting. You may change any of ftp.rb you want; the only requirement is that all of the tests pass. Do not change client.rb however.
Testing on Grace
If you are testing on Grace, it’s possible that some other student will be using the same port as the one you want, in which case starting the FTP server will fail. To avoid conflicts, use a port based on your UID. In particular, you should specify the port to be your UID mod 48128 + 1024. For example, if your UID is 106624753 then you would use port 106624753 mod 48128 = 21233 + 1024 = 22257. You can compute this from irb, e.g., by doing
irb(main):002:0> 106624753 % 48128 => 21233 irb(main):003:0> 21233+1024 => 22257 irb(main):004:0>
Even with this, it’s possible that you will end up choosing the same port as someone else, or even that an outsider might manage to connect to your server. As such, the passwords you use for your accounts file should be different from everyone else’s. To help with this, you run makeaccts.rb from the main project directory, i.e., the one that p6.zip unzips into. This program will update the file users/accounts and users_unfutzed/accounts with the same accounts but new passwords. It will also modify the tests in the testsdirectory to use these passwords instead.
Submission
You only need to submit ftp.rb that you changed. Everything else should be unchanged. You can submit your project in two ways:
- Submit your basics.ml file directly to the submit server by clicking on the submit link in the column “web submission”.
Next, use the submit dialog to submit your basics.ml file directly.
Select your file using the “Browse” button, then press the “Submit project!” button. You do not need to put it in a Jar or Zip file. Some students have mentioned problems with using Internet Explorer, because submissions being extracted in directories (e.g., “C:\My Documents\330\basics.ml”) where the submit server could not find them. The problems went away when switching to the Mozilla Firefox browser.
- Submit directly by executing a Java program on a computer with Java and network access. Use the submit.jar file from the archive p6.zip. To submit, go to the directory containing your project, then either execute submit.rb or type the following command directly:
java -jar submit.jar You will be asked to enter your class account and password, then all files in the directory (and its subdirectories) will be put in a jar file and submitted to the submit server. If your submission is successful you will see the message:Successful submission # received for project 6
Academic Integrity
The Campus Senate has adopted a policy asking students to include the following statement on each assignment in every course: “I pledge on my honor that I have not given or received any unauthorized assistance on this assignment.” Consequently your program is requested to contain this pledge in a comment near the top.
Please carefully read the academic honesty section of the course syllabus. Any evidence of impermissible cooperation on projects, use of disallowed materials or resources, or unauthorized use of computer accounts, will be submitted to the Student Honor Council, which could result in an XF for the course, or suspension or expulsion from the University. Be sure you understand what you are and what you are not permitted to do in regards to academic integrity when it comes to project assignments. These policies apply to all students, and the Student Honor Council does not consider lack of knowledge of the policies to be a defense for violating them. Full information is found in the course syllabus—please review it at this time.