December 2012 Archives

Fri Dec 21 16:02:48 UTC 2012

Let Me Github That For You

This blog post serves as a wrap up of
some aspect of the presentation I gave at ZeroNights 2012.

Ruby on Rails (RoR) is atm my favorite piece of software to hunt
bugs at. After quite some time spending on looking at Rails apps I
figured that I oversaw the most easy way to attack an (Open Source)
Rails app for quite a while. Before I come to my main point we'll
have to look at both RoR sessions and authentication systems:

Ruby on Rails Sessions

RoR sessions are by default stored client-side in a cookie. In
order to be tamper resistant, this cookie is signed with an SHA-1
HMAC. When the HMAC is missing or the cookie being tampered with
RoR will refuse to use the session variables within the cookie.

So, let's look at such a cookie, as an example I'll use a Github
session cookie:

This cookie consists of a Base64 blog and the HMAC, both separated
by "--". When decoding the Base64 you'll get a marshaled Ruby
Object, namely the session hash which is accessible in the web
application via session[:some_session_var]. The decoded and
de-marshaled Github cookie looks like this:

Ruby on Rails Authentication Frameworks

Where authenticated_system is the simplest mechanism, which will
just put a field "user_id" inside the session, by this ID then
authenticated_system will pull the user with that ID out of the
database as the currently logged in user.
Both authlogic and devise/warden handle it a bit different, they
will use a certain random token which is stored within the database
in order to identify the current user.

The fun stuff ;)

When a RoR application is created the secret which goes into the
HMAC will be created along with all the other files a minimal RoR
application would need. This secret usually is a 64 byte long
random string and lives in
$railsapp/config/initializers/secret_token.rb. The simple problem
is, that most developers are simply not aware of the
confidentiality of this file, and in result they'll happly check it
into Github or other online repositories (This
guy already figured that a while ago ).

When using authenticated_system it's pretty obvious how to break
into such an application:

Observe the secret_token on Github

Create a cookie containing "user_id=>1"

???

Profit! (as in: be any user)

Well that was easy, let's look at authlogic now.

An authlogic cookie usually uses a database stored token to
identify the user. The relevant parts of the session cookie
are:

user_credentials_id - a numeric value which is used with
"User.find_by_id()"

user_credentials - a radom string which will be compared with
the database field "persistence_token" in the Users table

Due to the way the RoR "find_by_*" methods are defined the
following SQL injection a-like issue arises:

By knowing this behaviour we can now easily circumvent the
authlogic protection with the knowledge of the
"secret_token".
The following cookie would give you access to an authlogic
protected application: