Ruby on Rails dynamic rendering Remote Code Execution Vulnerability (CVE-2016-0752)
0x00 Overview
If your application uses a dynamic rendering path (dynamic render paths), such as rendering params [: id], using local file inclusion Sion ), remote code execution may occur. You can update Rails to the latest version or refactor your controllers to fix the vulnerability.
This article mainly introduces a flaw in the Ruby on Rails framework in specific scenarios, which allows attackers to remotely execute code.
In the Rails controllers Design, The view File is implicitly rendered based on the called method. For example, when the show method of controller is called, if the view file to be rendered is not explicitly specified in the Code, the framework will implicitly render the show.html. erb file.
However, in many cases, developers Define the rendering content based on the request format, such as text, JSON, and XML. In this case, view file is a template language file, such as ERB and HAML. There are multiple methods in the Rails framework that can be used to influence and change the view content. This article focuses on the rendering method ). The Rails document provides multiple ways to call rendering methods, including using the file: Option to explicitly specify the view file Path to be rendered.
If you have read this document, you will be confused about the function description. Let's look at a piece of code:
def show render params[:template]end
First, this code is very simple. The main function of this controller action is to specify a view template for the rendering template parameter. But how does Rails find the specified template? Search under the views directory? Search under the root directory of the application? Or another location ?; Is the value of this parameter the name of a template? Is a file name with a specific suffix? Or a complete file path? There are many questions here. We need to check the implementation details to get the answer.
0x01 details
The render mechanism of the Framework is an example of trying to accomplish too many functions in a single function, which is also the cause of remote code execution.
We assume that the expected behavior of the rendering mechanism is rendered in the app/views/user/# {params [: template]} file. This assumption seems reasonable. If the value of the template parameter is dashboard, the app/views/user/dashboard will be loaded. {ext} file, where. ext is any allowed suffix type, such. html ,. haml ,. html. erb, etc.
Assume that the template parameter value is ../admin/dashboard. What are the results of program execution? As shown in, after execution, the program throws a missing template error)
By analyzing the error message, we can know that the Framework tries to find the view file to be rendered in multiple paths, including the root directories of RAILS_ROOT/app/views, RAILS_ROOT, and the file system.
Loading and rendering files from the root directory of the file system is very dangerous. If we pass in/etc/passwd as the value of the template parameter, and can read the content of the passwd file. It will be a very serious problem.
If we can read the content of the passwd file, we can also read the source code and configuration files of the application, such as the config/initializers/secrettoken. rb file.
This problem occurs because the dynamic rendering path (dynamic render paths) is used in the application)
def show render params[:template]end
This simple code example proves that attackers can read our source code and application configuration files. Unfortunately, this is not the worst result.
As Jeff Jarmo described in his article The Anatomy of a Rails Vulnerability-CVE-2014-0130: From Directory Traversal to Shell, we can exploit this Vulnerability to get a shell. Jeff's article describes a similar vulnerability in some versions of Rails's implicit rendering mechanism, which allows directory traversal. More specifically, local file inclusion Sion ). This article focuses on explicit rendering, a vulnerability introduced by framework developers.
Before going to the detail analysis, we classify the vulnerability as file inclusion rather than directory traversal because we load, interpret, and execute the file as code (ERB. Traditionally, the Directory Traversal Vulnerability returns non-executable content, such as CSV files. Therefore, in essence, we can not only read the application's source code and other readable system files, but also execute Ruby code. Since we can execute Ruby code, we can also execute system-level commands on the web server.
In the process from file Inclusion to shell, a key technology is used, called log file tainting ). During running, Rails records the request information to the log file, including the request parameters, such as development. log. Log files are in plain text format and can contain Ruby code. Log File contamination can be achieved by sending a malicious request to a web application. The request parameters contain valid Ruby code.
In the following example, we initiate a valid request to a web application, but the URL contains a malicious URL-encoded parameter <% =>.
<% =>
By viewing the log file, we can see that the request parameters in the log are saved as hash key-value pairs and URL Decoding is performed. This is an effective Ruby code that can be executed when a file is rendered.
Therefore, we can exploit the File Inclusion Vulnerability to try to load log files and execute the contained Ruby code.
When the log file returns, we can see the hash value of the parameter. Previously, the part containing our payload has been replaced by the execution result of the ls command. By now, we have been able to execute system commands with the user permissions of web-server.
0x02 solution & Mitigation
Install a patch for a specific version of Rails
If no patch is installed, you can disable rendering of files out of the whitelist. The specific method is to define the allowed file name whitelist hash in the action to verify the user's parameters and ensure that the parameters are in the file whitelist hash. This method requires verification to be added to all the places in the application that use the dynamic rendering path.
def show template = params[:id] valid_templates = { "dashboard" => "dashboard", "profile" => "profile", "deals" => "deals" } if valid_templates.include?(template) render " #{valid_templates[template]}" else # throw exception or 404 endend
Another similar method is to verify whether a specified file exists in a specific directory.
def show template = params[:id] d = Dir["myfolder/*.erb"] if d.include?("myfolder/#{template}.erb") render "myfolder/#{template}" else # throw exception or 404 endend
In addition, we can use the static Rails analysis tool Brakeman to scan applications. The Brakeman detection report will show the controllers that use the dynamic rendering path. Based on this, we can analyze which controllers may have the risk of remote code execution.
0x03 timeline On April 9, February 1, 2015, the vulnerability was reported to the Rails Team. On April 9, February 10, 2015, the Rails Team agreed to fix the vulnerability Patch and passed the internal verification on April 9, July 2015. -- Release of Patch over 5 months from reporting date in January 25, 2016, Vulnerability No. CVE-2016-0752, -- conclusion from verification over 6 months from reporting date 0x04
The rendering mechanism of Rails is a mysterious function, which is hard to understand without in-depth exploration of implementation details. Similar to CVE-2014-0130, using a dynamic rendering path causes directory traversal and code execution. When evaluating multiple popular open-source Rails projects, I have seen many similar vulnerabilities introduced by framework developers.
If you have not read Jeff Jarmoc, I suggest you read the following. He has gone deep into the vulnerability details and risk points of CVE-2014-0130. Many of the content in this article is very similar to his article. In fact, these two are very similar vulnerabilities.
I have written the Metasploit POC module to detect and attack the remote CAPTCHA human bypass vulnerability in web applications.