If you follow PentesterLab on Twitter, you probably saw the following tweet:

You may also have come across the following blog linked as part of the “worth-reading” articles for last week: https://chybeta.github.io/2019/03/16/Analysis-for%E3%80%90CVE-2019-5418%E3%80%91File-Content-Disclosure-on-Rails/

This article is really interesting but stops exactly when things get interesting…

How does Rails go from:

to:

When reading the code involved in the template resolver, you will come across the following code:

This code is both genius and crazy… and I won’t be surprised if it brings more vulnerabilities in the future…

The resolver uses the Ruby method Dir that relies on a glob. So you can provide a glob and use characters like *, ? … A good way to bypass any filter on /etc/passwd:

Now, the important part, the thing only a few people are talking about:

In production mode, Rails aggressively caches views and you basically need to wait for a restart of the server if you want to get another file. You may get lucky and:

The server may be redeployed daily.

The application is load-balanced and you can hit a different server.

You use the DOS (CVE-2019–5419) that got published at the same time (!stealthy)

The real issue is the most likely way to get remote command execution with this bug is to:

have the application running with the :marshal serialiser. get the file config/credentials.yml.enc for the list of encrypted credentials get the file config/master.key to be able to decrypt config/credentials.yml.enc forge your own session with the RUBY 2.X UNIVERSAL RCE DESERIALIZATION GADGET CHAIN from @bitcoinctf

Since you need to download two files (step 2 and 3) you will need to wait for the cache to get cleared…

Basically, most people trying to get this payload to work, only do it in development mode and are up for a surprise when attacking real applications!

After a bit more work with @bitcoinctf, it’s possible to use a race condition (if you are the first one exploiting the issue) to get multiple files served at the exact same time (but you only have one shot):