CSE508: Network Security, Spring 2016 Homework 3: Plugboard Proxy ------------------------------------------------------------------------------- Submission deadline: 4/8/2016 11:59pm EDT Submission through https://blackboard.stonybrook.edu In this assignment you will develop a "plugboard" proxy for adding an extra layer of protection to publicly accessible network services. Consider for example the case of an SSH server with a public IP address. No matter how securely the server has been configured and how strong keys are used, it might suffer from a zero day vulnerability that allows remote code execution even before the completion of the authentication process. This could allow attackers to compromise the server even without having proper authentication credentials. The Heartbleed OpenSSL bug is a recent example of such a serious vulnerability against SSL/TLS. The plugboard proxy you are going to develop, named 'pbproxy', adds an extra layer of encryption to connections towards TCP services. Instead of connecting directly to the service, clients connect to pbproxy (running on the same server), which then relays all traffic to the actual service. Before relaying the traffic, pbproxy *always* decrypts it using a static symmetric key. This means that if the data of any connection towards the protected server is not properly encrypted, then it will turn into garbage before reaching the protected service. Attackers who might want to exploit a zero day vulnerability in the protected service will first have to know the secret key for having a chance to successfully deliver their attack vector to the server. This of course assumes that the plugboard proxy does not suffer from any vulnerability itself. Given that its task and its code are much simpler compared to an actual service (e.g., an SSH server), its code can be audited more easily and it can be more confidently exposed as a publicly accessible service. Clients who want to access the protected server should proxy their traffic through a local instance of pbroxy, which will encrypt the traffic using the same symmetric key used by the server. In essence, pbproxy can act both as a client-side proxy and as server-side reverse proxy. Your program should conform to the following specification: pbproxy [-l port] -k keyfile destination port -l Reverse-proxy mode: listen for inbound connections on and relay them to : -k Use the symmetric key contained in (as a hexadecimal string) * The program should be written in C, use the OpenSSL library for all cryptographic operations, and run on Linux * Data should be encrypted/decrypted using AES in CTR mode * In client mode, plaintext traffic should be read from stdin * In server mode, pbrpoxy should keep listening for incoming connections after a previous session is terminated (you are not required to implement support for multiple concurrent connections, but you are welcome to do so) Going back to the SSH example, let's see how pbproxy can be used to harden an SSH server. Assume that we want to protect a publicly accessible sshd running on vuln.cs.stonybrook.edu. First, we configure sshd to listen *only* on the localhost interface, making it inaccessible from the public network. Then, we fire up a reverse pbproxy instance on the same host: pbproxy -k mykey -l 2222 localhost 22 Clients can then connect to the SSH server using the following command: ssh -o "ProxyCommand pbproxy -k mykey vuln.cs.stonybrook.edu 2222" localhost This will result in a data flow similar to the following: ssh <--stdin/stdout--> pbproxy-c <--socket 1--> pbproxy-s <--socket 2--> sshd \______________________________/ \___________________________/ client server To test your setup, you can achieve a similar data flow using netcat, by first running it on the same server as sshd as follows: nc -l -p 2222 -c 'nc localhost 22' Then connecting from the client machine as follows: ssh -o "ProxyCommand nc vuln.cs.stonybrook.edu 2222" localhost What to submit: A tarball with all required source code files, an appropriate Makefile, and a short report (.txt file is fine) with a brief description of your program. Hints: 1) Some OpenSSL functions you might find useful: AES_set_encrypt_key, AES_ctr128_encrypt (you can also use OpenSSL's more flexible EVP interface, which allows for more and stronger options, e.g., aes-256-ctr). 2) Mind your IVs! 3) For I/O multiplexing you can use either event-driven (e.g., select, poll, epoll) or multithreaded (e.g., pthread) programming.