Abusing rubygems for fun and profit

29 May 2016 12:18 | ruby | security

RubyGems is a nice system, very easy to use and also easy to abuse.  Anyone can push
a gem straight into the global namespace, even if the gem has the same name as a core
library.

This can be trivially abused to break into systems of anyone who isn't very careful
what gems they use (and let's be honest, that's probably a lot of developers :).

Ruby gems can include executable scripts which get installed into /usr/local/bin/.
On Ubuntu, Centos and probably most other linux distros, /usr/local/bin takes precedence
over /bin, /usr/bin, /sbin etc.  This means we can drop a fake "ls" script into
/usr/local/bin/ which will get executed every time the user types ls.

A PoC for this can be found here: https://github.com/m4rkw/rubygems-poc

Once installed the fake ls binary takes precedence and can then silently run whatever
malicious code you like (eg a connect-back shell to a remote system) before passing
the args onto the real ls.

The PoC just prints a silly message.

    $ ls<br/>
    bin  file-4.3.2.gem  file.gemspec  lib  LICENSE  README<br/>
    $ sudo gem install file-4.3.2.gem<br/>
    Successfully installed file-4.3.2<br/>
    Parsing documentation for file-4.3.2<br/>
    Installing ri documentation for file-4.3.2<br/>
    Done installing documentation for file after 0 seconds<br/>
    1 gem installed<br/>
    $ ls<br/>
    /============\<br/>
    | LOL HAXXED |<br/>
    \============/<br/>
    bin  file-4.3.2.gem  file.gemspec  lib  LICENSE  README<br/>
    $

At the time of writing the "file" gem name isn't taken so anyone could push a gem
straight into rubygems that would be installed whenever anyone types "gem install file".
This could easily catch someone out if they don't realise that the File class is built-in
rather than provided by a gem.

Another vector would be creating a small gem that actually does something useful and
just wait for people to install it.  I wrote a simple Transmission API library and got
hundreds of downloads.


Conclusions
===========

Since there's very little inherent security it seems the onus is on developers to be
careful what gems they install.  However since most gems don't need to install executables
it would probably be sensible for the rubygems maintainers to make the "gem" command
explicitly warn users if they're installing an executable.