Link Search Menu Expand Document

The goal of this assignment component is to prepare you with some basic hacking experience via a series of hands-on capture-the-flag exercises.

NOTE: This is still an experimental platform so we do expect bugs in the system. If you encounter one, please do not hesitate to email the instructor directly with the error report.

Details

Capture The Flags, or CTFs, are a kind of computer security competition.

The competition revolves around a set of challenges which are purposely designed and provided to you as training materials. Each challenge is designed so that when you solves it, a small piece of text or “flag” is revealed. The flag is then submitted to a website or scoring engine in exchange for points.

There will be three labs in this component, targeting the three types of attacks we are going to cover in this course:

  • memory corruptions
  • data races
  • logic bugs.

However, unlike traditional CTF challenges where the program is buggy and your job is to find and exploit the bug to retrieve the flag, in this CTF assignment, you are the one who should provide the tricky / buggy programs.

Interacting with the platform

The submission website is hosted on one of the Ugster machines at University of Waterloo. The full URL is http://ugster71a.student.cs.uwaterloo.ca:8000/.

However, if you click the link above, you will likely only see this error

{
  "error": "invalid request"
}

This is because the submission platform has only limited exposure to the public. Specifically, you can only interact with the platform via GET and POST HTTP requests.

$ curl http://ugster71a.student.cs.uwaterloo.ca:8000/<username>/<question>
  ### GET http://ugster71a.student.cs.uwaterloo.ca:8000/<username>/<question>

$ curl -d @<path-to-test.c> http://ugster71a.student.cs.uwaterloo.ca:8000/<username>/<question>
  ### POST http://ugster71a.student.cs.uwaterloo.ca:8000/<username>/<question> <data>
  ### NOTE the @ symbol, it is needed for a file upload

In the command line:

  • <username> is your UWaterloo username, all in lowercase.
  • <question> is the challenge number. For example, q1 stands challenge 1.
  • <path-to-test.c> is a local filesystem path containing the C source code to submit.

The GET request is used to retrieve your submission status on that question and the POST request is to actually make a submission. curl is an excellent utility for this purpose.

Following are two examples for further illustration:

Example: retrieve the current solving status for a challenge

To retrieve the result for challenge 1, assuming username test, you will do

curl http://ugster71a.student.cs.uwaterloo.ca:8000/test/q1

This will lead to an output that is similar to the following

{
  "passed": true,
  "unsupported": [],
  "unexpected": false,
  "timeout": false,
  "fatal": false
}

It means that you have submitted at least one passing case but none of the more interesting cases.

Example: make a submission

To make a submission for challenge 1 (regardless of which part), assuming test, you can do

curl -d @source.c http://ugster71a.student.cs.uwaterloo.ca:8000/test/q1

The filename does not matter, as long as it points to a valid C file. Ugster will take in the submission, analyze it, and reply with a JSON.

If the submission is a friendly one, the output is:

{
  "result": "passed"
}

On the other hand, if the submission touches on an unsupported feature, the output is:

{
  "result": "unsupported operation",
  "reason": "<... redacted ...>"
}

Challenges

Challenge 1: (released Oct 18) - Ramp-up with Tricky C Programs

This challenge intends to familiarize you with the submission system as well as the C language (if you are not familiar with it yet).

A lot of features in the C programming language can create troubles for analyzers, especially static analyzers. In this challenge, you have the access to a static analysis tool, Ugster — named after the platform that hosts it — which compiles and analyze C code.

Ugster is very picky about the C programs it is willing to take. One specific area to focus in this challenge is global variables. Your task is three fold:

  • Part 1 – create a C source code file with friendly global variables that passes Ugster. This is mostly to get you familiar with the system. You need to make at least one friendly submission to get 2 points for this part. However, multiple submission will not gain additional points.
  • Part 2 – create a C source code file with tricky global variable declarations / definitions that exploits some unsupported feature in Ugster. If Ugster detects the use of an unsupported feature, it will complain about the category of this features. You will get 2 points for each unique category discovered.
  • Part 3 – create a C source code file that triggers more fundamental issues in Ugster, usually in the form of 1) unexpected errors, 2) timeout, or 3) fatal exceptions. You will get 4 points if you manage to discover a case that lead Ugster to run into these error categories.

NOTE: your C code must be valid code, i.e., it must compile under a modern compiler without standard libc headers, i.e., with flag -nostdinc and -nostdlib on GCC or Clang and with the C17 standard (-std=c17).

Challenge 2: (released Nov 1) - Fixedpoint Optimization

Compiler optimization is key to ensure the performance of a program and might also helps with static analysis (simpler programs are easier to analyze anyway).

But what is less known is that traditional compiler optimization (as seen in -O0, -O1, -O2, -O3 etc) never aims at producing an optimal binary. Instead, it is a best-effort scheme that balances compilation time and optimality. Therefore, if you take a piece of code that is already -O2 optimized and run it through -O2 again, the code might be further optimized.

Our static analysis system, Ugster, relies on a novel concept called fixedpoint optimization. The idea extremely simple, it keeps sending the -O2-optimized code back to the compiler until the output code does not change anymore (i.e., reaching a fixedpoint).

Your task is two fold:

  • Part 1 – create a C source code file that reaches optimized state with 1 round of -O2 optimization. You wil get 2 points for this part. However, multiple submission will not gain additional points.
  • Part 2 – create a C source code file that reaches optimized state with N (N > 1) round of -O2 optimization. You wil get (2 ^ N) points for the maximum of N you discovered (i.e., 4 points for N=2, 8 points for N=3, etc). Again, multiple submission will not gain additional points.
  • Part 3 – create a C source code file that triggers more fundamental issues in Ugster, usually in the form of 1) unexpected errors, 2) timeout, or 3) fatal exceptions. You will get 4 points if you manage to discover a case that lead Ugster to run into these error categories.

NOTE 1: unlike challenge 1, using unsupported features will NOT be awarded any points. So try to program within the support features that you are aware of.

NOTE 2: your C code must be valid code, i.e., it must compile under a modern compiler without standard libc headers, i.e., with flag -nostdinc and -nostdlib on GCC or Clang and with the C17 standard (-std=c17).

Grading

Grading of the CTF assignment is 100% based on the score from the CTF submission site. Each challenge has its own scoring mechanism, which is detailed in the corresponding description. The maximum score for each challenge is 10 points. You can definitely receive more than 10 points but the score will be capped at 10.