Analysis of the bug =================== The `do_remotetmp()` function doesn't check for possible dot-dots and slashes in the login name, so it may create files in arbitrary directories. Moreover, the `do_privtmp()` function tries to create the secret file without checkint that it doesn't already exist; the random name is also easy to brute-force. Attack plan =========== The idea is to connect a first time anf create a login file with the same name of the secret file; then, while the first connection is still active, create a new connection and select the `p` function, which will copy the flag in the login file; finally, use the first connection to read the file. To guess the random name we can use more than one connection. Attack implementation ===================== Since there are only 5 possible secret file names, we can connect 5 times, once for each possible name. If we now connect a 6th time and issue the `p` command, One of the 5 files will be overwritten with the contents of the secret file, and we will be able to read it by issuing an `r` command in each connection. Note that the `r` command only sends us the same number of bytes previously written with `w`, so ne need to write a sufficiently large number of bytes in each connection, before connecting for the 6th time. E.g., if we open 5 different terminals: ``` (term1) nc $HOST $PORT r waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ../sec.A (term2) nc $HOST $PORT r waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ../sec.B ``` ... and so on. Now we connect for the 6th time from yet another terminal: ``` (term6) nc $HOST $PORT p ``` while the 6th connection is still active (and, therefore, the secret file has not been `unlink()`ed yet), we go back to the first 5 terminals and issue an `r` command in each one of them. One of the connections will reply with the flag. Suggested fix ============= The login name accepted in `do_remotetmp()` must be sanitized to check that, at the very least, it doens't contain any slashes and, therefore, cannot be used to create files that are not directly contained in `tmp`. Even better, its characters should be checked against a whitelist (e.g., only alphanumeric characters and underscore). The `do_privtmp()` function should use one of the known methods to safely create a temporary file (e.g., `O_TMPFILE` in Linux, or `O_EXCL|O_CREAT`). If a filename is necessary, it should be much harder to brute-force.