The purpose of this post is to explain the TORQUE vulnerability I recently created a proof of concept for. Since the proof of concept was just a simple stub, I feel the mechanics behind the exploit should be described as well.
To be completely honest, I have never used TORQUE before attempting to exploit it. I was looking for a vague CVE to proof of concept, and this one did not appear to obscure CVE-2014-0749. Since this application is open source, I was able to download and review the source code for this. I was also able to see the pull request for resolving this issue (easy mode, amirite?).
The line of code we are looking to exploit is here. Libdis defines the protocol used for network communication, and we are exploiting a weakness in its core ability to function. I’ll explain the relevant parts of this protocol. Essentially, when reading in data, this protocol parses arbitrarily large data by first reading a digit. This digit dictates how many digits will define how large the data will be. Since the buffer for storing this data is only 64 bytes on an x64 machine, any value larger than two here will eventually lead in an overflow. After it reads this first character, it then calls itself again to parse the digits for the size. After parsing n digits, it now has its count for its final call to disrsi_. In this call, we need to have it start with a digit again in order to reach the code we are exploiting.
The pull request mentioned before adds a check at the beginning of the function to check the size of data to be read in. Since the check actually happens after information is read from the socket pre-pull request, we can read in as much as 999999999 bytes (actually quite a bit less due to section restrictions). Looking at the code, this issue may not be apparent, as where is the memcpy we are supposed to be exploiting? Its in the tcp_gets at line 467.
So essentially, to exploit this, we need to send three numbers. The first is a single digit which defines the number of digits in the next number, and the second defines the size of the data we will overflow with. Then another digit to continue to hit the tcp_gets function we need to exploit. We can simply connect with a TCP socket, send “39991” then 999 A’s to cause the crash.