Bitdefender has found a Stored XSS vulnerability in PayPal that could allow attackers to upload maliciously crafted files to perform attacks on PayPal customers.
The vulnerability can be weaponized to deliver malicious content or files to users, allowing a wide range of attacks that could be even more dangerous.
PayPal has fixed the vulnerability following Bitdefender’s responsible disclosure, rendering potential attacks exploiting the issue ineffective.
The problem lies in the way PayPal processes and encrypts URLs that pull uploaded files. Our proof-of-concept using an HTML-formatted XML file, uploading it via the “Create an Invoice” section. Because the “id” parameter for each uploaded file takes the value of a cipher text encoded in base64 and uses the CBC (cipher block chaining) ciphering mode, the attack involved changing a series of bytes from each cipher block in order to force the PayPal server to execute the malicious payload.
Whenever a file is uploaded via the “Create an Invoice” form, the resulting URL has the following formatting:
The “id” parameter seemed to take as value a cipher text encoded in base64. The first test involved including a file name with various lengths to see if it is reflected in the cipher text and if it is a block cipher mode. After this was found to be true, the next step involved using a large file name, to figure out what cipher mode was used.
Realizing that CBC mode could be used the cipher, we then altered the value of the “id” parameter by changing the third byte from the first cipher block and then we sent it to PayPal’s server. The following response was received:
Since we received “cyntent” instead of “content”, we realized each block was 16 bytes in size.
We then took the value of “id” – which was a base64 – and first made a URL decode. This was because “/” in a URL can be confused with “other folder in” and “+” can be confused with “space”. We then decoded from base64 and hex it, so we could use a script that converts that hex back to a base64 and send it back to the server.
Following a couple of these tests, we could extract the decrypted value of the entire cipher text. Here’s an example of how the decrypted cipher text looked like:
Because the server would accept text until it found the “~” separator, we confirmed that it will return the error or file as an attachment back to us. Further tests revealed that if there was no “~” separator in the text, the browser will display the reply, instead of prompting to download it as an attachment. This was because the PayPal server fetched User Agent information and detected that our Firefox Content-Disposition parameter – responsible for displaying content – was not set.
This was the premise for creating a Stored XSS attack. Here’s the actual step-by-step process that led to a successful Stored XSS attack:
1. Make an XML file that has an HTML content, but respect XML structure;
2. Upload it to the server;
3. Copy the link to that file;
4. Change the second byte from the encryption to produce an error;
5. Now we have the full path to the Stored XSS;
6. Now we have to make a second upload, but this time we have to bypass a restriction by modifying some bytes from the ciphertext;
We can’t use ‘/’ in file name and we have to choose another character. For example we will choose character ‘.’.
7. Upload a new file and as file name insert this:
8. Divided into blocks of 16 will look like this:
9. We used blocks ‘aaaaaaaaaaaaaaaa’, ‘bbbbbbbbbbbbbbbb’ and ‘cccccccccccccccc’ to change bytes from the next blocks, turning ‘.’ into ‘/’, making it output the following blocks.
The 3 blocks where we changed some bytes won’t look like they were before and instead of ‘aaaaaaaaaaaaaaaa’ we will have something like:
10. In the image above we used a script that act as a proxy and return to us the response from PayPal.
11. Now we just have to copy the link and use it for further attacks. The resulting webpage with our proof-of-concept looked like this:
Other attacks could allow for “reflected file download,” by making PayPal output files that look like “~test.bat”. By downloading and executing these files attackers could trick users into installing malware or other types of threats.
The Stored XSS attack works only on Mozilla Firefox, because when the User Agent contained the word “Firefox,” the reply form did not set any Content Disposition parameter.
Although this type of attack was not reported in the wild, it could have allowed hackers to manipulate PayPal URLs and trick users into downloading malicious files or visit fraudulent websites.
Note: This article is based on technical information provided courtesy of Ionut Cernica, Bitdefender Researcher.