CMSC 330, Fall 2016
Organization of Programming Languages
Project 6 - Computer Security
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 StartedDownload 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):
Running the FTP client and serverTo 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.
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 public that 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.rbYou will see on the console something like this:
Starting server on TCP port 39010This 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 clientOnce you have started the FTP server you can connect to it with a client. In another window, execute the command
ruby client.rb 39010Here, 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 commandsThe 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.)
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--baz89These 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 doYour job is to make sure that the FTP client/server enforces its security policy properly under certain assumptions.
The FTP server aims to implement a basic confidentiality and integrity policy:
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 tests directory to use these passwords instead.
SubmissionYou only need to submit ftp.rb that you changed. Everything else should be unchanged. You can submit your project in two ways:
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.