Can analyzing javascript files lead to remote code execution?

Asem Eleraky
8 min readMay 8, 2022

--

In today’s blog, I’m going to show you how analyzing javascript files can lead to access unrestricted endpoints and to understand how the application deals with it. I’m also gonna show you how I bypassed 2 file upload endpoints to get RCE in an ASP.NET application.

First of all, This was a private program, so I will refer to it with target.com.

Finding the endpoint:

After a few hours of playing around with the application, I found a subdomain that gives me a message “Taking a Short Break” which means it’s a good sign to start fuzzing directories.

I started fuzzing directories till I found some endpoints which return the error code 403 Forbidden page, except /tools endpoint, it gives me a login page, and I thought it was for admins only, let’s see:

I tried to sign in with default credentials but it wasn’t successful.
Usually, when I find a login panel that I can’t login to, I take a look at the javascript files as there may be credentials leaks, API keys, hidden endpoints, etc.

The vast majority of web applications obfuscate the javascript files, so it’s gonna be a waste of time to understand how and what these files do at all, but you can take advantage of the search feature in our browsers to search for some goodies!
I try searching for api, secret, token , admin , etc, also I try to search for Ajax and XML requestes.

And I found some endpoints that confirm that this login panel is for admins.

I checked all of these endpoints, and all gave me an empty response, except for this one /path/to/assetmain.aspx , it returns a white page and some imported CSS and javascript files, let’s dig more into these files, especially since the names of these files indicate something related to uploading.

Analyze first file (xproupload.js):

Starting with xproupload.js, I found this mess.

I decided to use an online javascript beautifier to make it easy for me to analyze it.

This file was +550 lines of code, so I will focus only on the important objects and functions.

I analyzed this file until I reached a function that deals with a backend upload function, starting from line 465, object “o” was declared and prepared to be the request body of an initiated Ajax request in line 473, and contains the following elements (parameters):

  • folder → The directory that I will upload to.
  • thefile → the parameter that will have our file name and its content.
  • currentFilter → just an empty string, also from later analyses, there is no need for it.

Also in lines 472 and 473, new parameters were added:

  • getRS → the returned value from getAKrs function, we still didn’t know what is it, also there are no functions in this file with the same name, so I will search in other javascript files later.
  • akap → in javascript, the value !0 means “true”.

The upload request destination was declared in line 488, to _uploadHander, and this variable was mentioned in line 377 as you can see below

Also, you may notice that in line 379, there are some upload rules, one of them was the allowed file extensions.

Analyze second file (xprofile.js):

This file has many functions, so I’ll focus only on the important objects and functions as well.

The same upload rules were declared here as well, in addition to new handlers properties added, and they were called from different endpoints

  • _fileHandler filemgn.ashx
  • _rsHandler fileUtility.ashx

In line 13, there is the getAKrs function that I was looking for, it returns the results of an Ajax post request to _rsHandler (fileUtility.ashx) file, the only parameter needed to send the request is called “fx” and its value is “setFileRS”.

I tried to send this request with the burp suite, and the result was a random string per request, my guess is that this code may validate every request sent to the server, the same as a dynamic CSRF token, we will see.

Now all required parameters and their values for uploading a file are here, let’s upload a text file to test if I have permissions to upload a file or I should be logged as admin, I also changed the encoding of the request body to multipart/form-data; so the server prepares to receive a file.

Nice, it worked! also, the response gives me the directory where my file was uploaded and it is under /assets directory, let’s check it out!

Sounds good, now we need to bypass the application’s extension whitelist to upload a shell, keep in your mind this is an ASP.NET application.

I tried to bypass it with all known methods, like double extension, null byte, and so on, but it didn’t work, also tried with all possible configuration and executable extensions that work with ASP.NET and Microsoft server applications like exe, bat, config, etc, but no luck.

Back to xprofile.js file, exploring, maybe there are other functions that can leverage this upload.

The number of Ajax requests used in this file took my attention, I noticed that there are some of them sent to treat with some kind of a file manager, there are functions like getFiles, deleteFile, createFolder and more, one of these functions is called renameFile!, and renaming files is absolutely what I need!

By reviewing this function, it’s an Ajax request sent to the _fileHandler (filemgn.ashx) and it needs 4 parameters:

  • fn → and it takes the “rename_file string value.
  • getRS → the returned value from getAKrs function.
  • akap → as mentioned above, it is just a “true” value.
  • param → takes the value of the “t” variable, which was declared as an array in line 131, and was assigned with three values in line 132.

I don’t know what is the param parameter used for? so I started fuzzing it.

A few minutes later, and since the parameter param was meant to be sent as an array of 3 elements, I finally found that:

  • The 1st param[] was the directory that contained the file we want to rename.
  • The 2nd was for the new name.
  • The 3rd was for the current file name.

I tried with another text file, so I uploaded slider.txt and changed the name to slider_melo.txt

Nice!, I also tried to change the file extension to a NOT allowed one, like aspx, and it works as well, so let’s upload a malicious file!

I used cmd.aspx but changed it to cmd.txt and uploaded it, then changed its name to testshell.aspx, then I navigated to the file.

My baby uploaded successfully, and I can now run commands on the system!

Report Timeline:

25 Mar: Submitted.
28 Mar: Triaged.
29 Mar: Bounty Rewarded.

Digging More:

I got interested to know what’s behind this code, especially the filtration implemented on the file extension. Hence, as we have the privilege to write commands on the server, I started to read this part of the code inside the fileUtility.aspx file.

Note that you MUST ask for permission before exploiting further any bug you find, especially when it comes to accessing internal data, and of course, It was communicated and agreed upon by the program team in my case.

Back to what I found, the application converts the file extension to lowercase and then filters all executable files, and I realized it can not be exploitable without finding the rename function, but in the same file, I found something related to uploading a zip file that took my attention!

As you can see in line 126, it checks for two main things:

  • If the last 4 characters on the filename are “.zip
  • The value of the extract request parameter.

If both are true, it will unzip the file in the same directory we uploaded!

Will extract it without any filtration?
- YES! Let’s go!

I used the same shell file, but this time I add it in a Zip archive and create a simple python script to upload it and add the extract parameter with a true value

Now let’s check it on the browser

Look at my second baby shell uploaded successfully!

I wanted to submit a new report, but they closed the server, anyway, I hope you enjoyed reading and I will be pleased if you have any feedback!

--

--

Asem Eleraky

Penetration Tester, CTF Challenges Developer & Player, Bug Hunter | AKA Melotover