Semmle CTF 2: U-Boot challenge

Do you want to challenge your vulnerability hunting skills and to quickly learn Semmle QL? Your mission, should you choose to accept it, is to find all variants leading to a memcpy attacker controlled overflow. You will do this by utilizing QL, our simple, yet expressive, code query language. To capture the flag, you’ll need to write a query that finds unsafe calls to memcpy using this step by step guide.

Enter for a chance to win

When you complete the challenge, email us your final query at ctf@semmle.com for your chance to win a pair of Bose SoundLink Headphones. Semmle will select the best QL queries received before September 6th, 2019. Winners will be contacted by email.

Challenge instructions

The goal of this challenge is to find the 13 remote-code-execution vulnerabilities that our security researchers found in the U-Boot loader. The vulnerabilities can be triggered when U-Boot is configured to use the network for fetching the next stage boot resources. MITRE has issued the following CVEs for the 13 vulnerabilities: CVE-2019-14192, CVE-2019-14193, CVE-2019-14194, CVE-2019-14195, CVE-2019-14196, CVE-2019-14197, CVE-2019-14198, CVE-2019-14199, CVE-2019-14200, CVE-2019-14201, CVE-2019-14202, CVE-2019-14203, and CVE-2019-14204.

Through these vulnerabilities an attacker in the same network (or controlling a malicious NFS server) could gain code execution at the U-Boot powered device. The first two occurrences of the vulnerability were plain memcpy overflows with an attacker-controlled size coming from the network packet without any validation. The memcpy function copies n bytes from memory area src to memory area dest. This can be unsafe when the size being parsed is not appropriately validated, allowing an attacker to fully control the data and length being passed through.

U-Boot contains hundreds of calls to memcpy and libc functions that read from the network such as ntohl and ntohs. In this challenge, you will use Semmle QL to find those calls. Of course many of those calls are safe, so throughout this challenge you will refine your query to reduce the number of false positives.

Upon completion of the challenge, you will have a query that is able to find many of the vulnerabilities that allow for remote execution of arbitrary code on U-Boot powered devices.

Setup instructions

The quickest way to get started with QL is to use LGTM's query console. However, if you prefer, you can also install QL and write your queries offline. Instructions for installing QL are included at the end of this document.

Documentation links

If you get stuck, try searching our documentation and blog posts for help and ideas. Below are a few links to help you get started:

Challenge

The challenge is split into several steps, each of which contains multiple questions.

Step 0: Finding the definition of memcpy, ntohl, ntohll, and ntohs

Question 0.0: Can you work out what the above query is doing?

  • Hint: Paste it in the Query Console and run it.

Question 0.1: Modify the query to find the definition of memcpy.

Question 0.2: ntohl, ntohll, and ntohs can either be functions or macros (depending on the platform where the code is compiled).

As these snapshots for U-Boot were built on Linux, we know they are going to be macros. Write a query to find the definition of these macros.

  • Hint: The QL Query Console has an auto-completion feature. Hit Ctrl-Space after the from clause to get the list of objects you can query. Wait a second after typing myObject. to get the list of methods.

  • Hint: We can use a regular expression to write a query that searches for all three macros at once.

Step 1: Finding the calls to memcpy, ntohl, ntohll, and ntohs

Question 1.0: Find all the calls to memcpy.

  • Hint: Use the auto-completion feature on the function call variable to guess how to express the relation between a function call and a function, and how to bind them.

Question 1.1: Find all the calls to ntohl, ntohll, and ntohs.

  • Hint: calls to ntohl, ntohll, and ntohs are macro invocations, unlike memcpy which is a function call.

Question 1.2: Find the expressions that resulted in these macro invocations.

  • Hint: We need to get the expression of the macro invocation we found in 1.1

Step 2: Data flow analysis

For this step, we want to detect cases where some data read from the network will end up being used by a call to memcpy. To do this, we’ll use the Semmle QL taint tracking library, and its predicate hasFlowPath that will tell us when some data coming from a source flows to a sink. Use the boiler plate provided below to complete your taint tracking query.

Question 2.0: Write a QL class that finds all the top-level expressions associated with the macro invocations to the calls to ntohl, ntohll, and ntohs.

  • Hint: Querying this class should give you the same results as in question 1.2

Question 2.1: Create the configuration class, by defining the source and sink. The source should be calls to ntohl, ntohll, or ntohs. The sink should be the size argument of an unsafe call to memcpy.

  • Hint: The source should be an instance of the class you wrote in part 2.0.

  • Hint: The sink should be the size argument of calls to memcpy.

Step 3: Find additional vulnerabilities

Question 3.0: There are 13 known vulnerabilities in U-Boot.

The query you completed above probably found 9 of them. See if you can refine your query to find 1 or more additional vulnerabilities.

Question 3.1: Generalize your query to find other untrusted inputs (not only networking) such as ext4 fs.

Grand prize

Crack Step 3 of the challenge for your chance to win a pair of Bose SoundLink Headphones. Semmle will select the best QL queries received before August 25th 2019. Winners will be contacted by email.

Getting Help

If you find yourself stuck writing QL or on any part of the CTF and would like some help, there are a few different things you can do:

Setup instructions for running QL offline

We hope you enjoyed this challenge! If you are interested in continuing to use QL for security research, then we recommend installing QL on your own computer. This will enable you to run queries offline. We have also provided these offline instructions for posterity, because the query results on LGTM will change over time as the source code evolves. But the instructions below use a snapshot corresponding to revision d0d07ba, which is the revision for which we designed this challenge. To run QL queries offline, follow these steps:

  1. Install the Eclipse IDE.
  2. Download QL for Eclipse.
  3. Installation instructions can be found here. Download this snapshot, which corresponds to revision d0d07ba.
  4. Import the U-Boot snapshot.

You can download other snapshots for offline use from LGTM. For example, you can download a snapshot for the latest revision of U-Boot here. Every project on LGTM has a download link for downloading the latest snapshot.

Get started