Telerik RadAsyncUpload Arbitrary File Upload

The Issue
AsyncUploadHandler in Telerik's RadAsyncUpload feature is configured with a hard coded (default) encryption key. This key is used to encrypt upload variables which are sent to the user, and subsequently used in file upload requests by the user to the server. If this key is not changed from it's default value of "PrivateKeyForEncryptionOfRadAsyncUploadConfiguration", a malicious actor can capture the file upload request to /Telerik.Web.Ui.WebResource.axd and decrypt parameter 'rauPostData'. Once decrypted, the file upload location can be modified and re-encrypted, resulting in arbitrary file upload to any location on the server which the web server user has permissions to write to.
Tl;Dr - Default key allows decryption of parameter, which enables a malicious actor to change the file upload location.

Link to exploit script:
Affected Versions
Works on all versions prior to Telerik UI version 2017.2.621, release in June. As stated in the introduction, the encryption key must still utilize the default setting.
How to Exploit
Process Summary (Using automated payload generator code in appendix):
  1. Capture file upload request (used BurpSuite)
  2. Copy encrypted content block in rauPostData into a file (portion before the ampersand)
  3. Decrypt, modify the upload file path, and re-encrypt using the C# payload generator code (included in appendix)
  4. Paste encrypted output back into rauPostData parameter
  5. Change the file content of your upload request to be a web shell (or malicious code)
  6. Set your file name and malicious extension in the UploadID parameter
  7. Forward along the new request and your web shell (or malicious page) should be uploaded!
Step 1
Initiate an upload request to the web application with any random, supported file. During this process, a call will be made to The request will contain a form titled 'rauPostData' with encrypted content. Capture this request in BurpSuite.

Step 2
The encrypted text in RauPostData is actually in two parts separated by an ampersand. The first portion contains our upload file path, max content length, time, and allowed file extensions. The second portion contains information about the version of Telerik.Web.UI and the PublicKeyToken. We are only interested in the first potion. Copy the block of encrypted text up to the first ampersand and place it in a text file on your workstation:

Step 3.a
The decryption code is written in C# which lets us use Microsoft's cryptography library. This code was pulled from the original C# code used by Telerik during encryption and decryption (as discovered by GitHub user straightblastat end). Compile it (I did so on Windows using CSC) and execute the program. You will be prompted for a file name, enter the path/file created in step 2:

Step 3.b
Once entered, the program will pass the encrypted rauPostData text through two iterations of decryption. The first decryption will reveal a block of parameters in a key/pair format. One of these parameters is TempTargetFolder, which is remains encrypted. The program parses this value out and decodes it one more time to obtain the current file upload path. Starting in 2017, Telerik included an HMAC appended to the end of the TempTargetFolder value. The program attempts to detect if an HMAC is appended. If detected, it will determine where the encrypted file path stops and HMAC starts, and then parse out the two values.
At the end of decryption and dealing with the HMAC, the program will spit out the exact upload file path being used by the web server. It will then prompt you to enter a new file path where you would like your malicious file to be uploaded. The goal is to get a malicious file uploaded to the web root, so that we can visit the page and cause it to execute. As seen in the below figure, the current file path is "C:\Program Files (x86)\Telerik\UI for ASP.NET AJAX R1 2017\Live Demos\App_Data\RadUploadTemp". One would assume then that the web root may be "C:\Program Files (x86)\Telerik\UI for ASP.NET AJAX R1 2017\Live Demos". Therefore, we enter this as our file path.
Step 4
The file path input in step 4 will then be re-encrypted, have the HMAC appended (if necessary), set as the TempTargetValue, and then re-encrypt the entire parameter block, producing a payload to be placed into BurpSuite. Simply copy the final output encrypted content back into rauPostData in your intercepted upload request. Remember to leave all encrypted content after the ampersand exactly how it was. We did not copy this content in step 2, and therefore it should not be modified here.
Step 5
In your captured file upload request within BurpSuite, scroll down to the "file" form section. This section should be set to the content of your malicious file. Here, I used the Laudnum ASPX web shell located at (

Step 6
At the bottom of your intercepted file upload request in BurpSuite, the form name "metadata" contains parameter "UploadID". Modify this to be the name of your file, along with the malicious extension. For example, using the laudanum shell, you could upload the file as "shell.aspx".

Step 7
Forward your modified file upload request to the server. If this works, you will receive an HTTP 200 OK response message with a JSON parameter of 'fileInfo' and upload details. While 'fileInfo' will display the original name of your file upload and not what it was set to in UploadID, that does not matter. To test if everything worked, simply navigate to the website root directory plus the name of your malicious file and see if your web page is there (i.e.
Payload Generation Code
This code handles decryption, path modification, and re-encryption for Telerik versions both with and without an HMAC appended to the encrypted file path. It is written in C#. I compiled it using the CSC tool on Windows 8.1.
Credit where credit is due
I did not personally discover this vulnerability, but have simply modified the encryption/decryption process and procedure to be streamlined and work for multiple revisions (some do not use an HMAC). My first introduction to this issue (and the only post I have seen on it thus far) came from GitHub user StraightBlast, located at Props to you, man. Thanks for digging into the source code and finding this!