skip to content
Back to GitHub.com
Home Bounties Research Advisories CodeQL Wall of Fame Get Involved Events

GitHub Security Lab Eko2020 CodeQL CTF: Use After Free





CodeQL CTF

Hi! Thank you for your interest in trying the Ekoparty 2020 CodeQL CTF. We hope that you give it a try. Feel free to submit any answer you come up with! We would love to see your CodeQL queries and we have lots of GitHub swag to hand out! The winner will get a $150 coupon to use in the GitHub swag shop, and the 2nd and 3rd positions will get a $75 coupon.

The challenge is to write a CodeQL query that finds a particular kind of use-after-free vulnerability (details below). A well known open source codebase contained an instance of this vulnerability a few years ago. The bug has since been fixed, but we have built a CodeQL database for the vulnerable version of the code. We’re keeping the identity of the codebase secret, because we will use it to judge which query is the best, and you will use a smaller codebase to test your query. Your challenge is to write a query that finds the bug, with as few false positive results as possible. To enter, you just need to send us your query by 2020-09-25, 18:00 ART.

What is CodeQL?

CodeQL is GitHub’s semantic code analysis engine that lets you query code as though it were data. CodeQL extracts all aspects of your code into a relational DB and provides you with an expressive and object-oriented language to run optimized queries on this DB.

Because you have access to the AST, but also to semantic information, and also to the Control Flow Graph, you can write very powerful queries including global taint tracking of data flowing through function calls across different files of your codebase.

Security researchers use CodeQL to find all variants of a vulnerability, and eradicate it forever.

Use-after-free bug class

Below is a simplified version of the bug:

free(s->x);

…

use(s->x);

In other words, the code frees the field of a struct, but does not zero the field. As a result, the struct now contains a dangling pointer, which creates the risk of a use-after-free. A safer coding practice is to always immediately zero the field after freeing it, like this:

free(s->x);

s->x = 0;

We have written a small test program with several examples of this bug: Test program

You can download a CodeQL database for the test program:

The complete instructions to choose a CodeQL database are here

How to enter

Write one or more CodeQL queries that detect the bugs in the example program above. To submit, create and use a secret GitHub gist with your CodeQL queries in it. Your gist can be a plain text, markdown, html... if you need to write explanatory text, as long as the code snippets are easily readable. When you are ready to submit, just email your gist to us at ctf@github.com, with the title “Ekoparty 2020 CodeQL CTF”, by 2020-09-25, 18:00 ART. Please include your name and contact information in the email.

Detecting calls to free

Please use the following predicate to detect calls to the free() function:

// Holds if `arg` is the argument of a call to `free`: `free(arg)`
predicate freed_expr(Expr arg) {
  exists(FunctionCall free |
    free.getTarget().getName() = "free" and
    arg = free.getAnArgument()
  )
}

The reason is that our checking and scoring procedure needs to modify this freed_expr predicate in your code, and adapt it to our test codebase.

Official rules

Read the official contest rules.