2011-04-09

HITB 2011 Amsterdam Round Two Quals Binary

The provided binary is a ELF file designed to be run by inetd and accepts several character based commands followed by their parameters. The main loop reads a character from STDIN (in inetd a socket is duplicated into standard I/O descriptors) and based on the value picks a handler from an array of function pointers. The following commands exist:

  • 'f' - return meta data for a given file name
  • 'l' - list filenames from the home directory
  • 'q' - terminate the process
  • 's' - return symbolic link's path name
  • 'v' - verify input with a key file's data

After mapping out all the available handlers and reviewing how they work there were no obvious vulnerabilities (e.g. buffer overflow). The handler functions that expect additional input first allocate some heap-based memory to store this input and care is taken to make sure it's not overflowed. After the handler completes its work the memory is freed. However, there's a design flaw in the way allocated memory is used when the key text is verified. Specifically, the key data is read into a allocated buffer and compared to the string supplied by a user. Once this is done the memory is simply freed, which returns the memory block to the free pool still containing the key data.

As a result, we can use another handler, which allocates memory for its operation and returns the results to the user. One such command is the 's' character, which accepts a symbolic link as a parameter. Additionally, after listing the contents of the home directory using the 'l' command we find few symbolic links that can be used for the 's' command. Thus, when requesting to view a symbolic link the real path will be copied to a allocated buffer. Since the buffer will come from the free pool and the contents were not cleared then whatever data was there will also be displayed. If the resulting path is shorter in length than the data size of the "KeyFile" we can disclose part of the secret key string.

Looking at the handler for the 'v' command it was identified that a string comparison is performed only on the last 14 bytes of the key file. This tells us how much of the disclosed key file's data we need to grab. Thus, to reproduce we need to submit the 'v' command with any key, which stores the key data into a buffer, but does not clear it after the comparison. Then, submit the 's' command to display the path of the "t1" link, which is short enough to disclose more than 14 bytes of the key file. Finally, take the last 14 bytes and submit them via the 'v' command again and this time the comparison succeeds and gives us the solution key.

The solution string is (w/o quotes): "DwightIzK00l"