JRuby, RMI, and Turd Burritos
I’m pretty sure if I add up the “side projects” or the “can you look at this for a minute” time it is something close to 8x of my actual billing time. Not that I mind helping friends out. A fellow asked for some help on an application and these always tend to be a lot of fun.
Leviathan had been contracted to look at an old as in “your mom” application build on infrastructure dating all the way back to before there were keyboards and code was hammered out with chisels on stone tables. This particular application designer decided that the simplest route was to create a set of RMI request and bundle them into a Desktop client. A Java desktop client.
For those of you playing at home RMI is Remote Method Invocation. Think of it like shouting across the internet and telling a server to do something.
Java in all of its write once run anywhere glory has this funny way of being easily decompiled into source code. Thus once you distribute the client to a customer they basically can look at the internal guts of the application a lot easier than one would look at an application compiled in C or C++. Not that C/C++ can’t be decompiled Java just makes it trivial to do.
Now my coworker has the client, the source code, and a valid account on the server in question. The world is basically his oyster, right? Well as it turns out some oysters don’t like being opened.
Queue: The enterprise turd burrito. Turd Burrito or ETB for short. If you have a turd that you want your enterprise infrastructure to swallow than you just keep wrapping it in beans, rice and salsa until the IT guys that payed $9.50 don’t realize “it’s not meat”.
To make RMI easier to use and more firewall friendly many J2EE providers wrapped RMI in multiple transport layers. Most notably HTTP, SSL, and some special sauce we’ll call “Voodoo magic” This makes the IT guy happy. “I only have to open one port”, the security guy shrug, and the developer only marginally less happy. They have to make sure all of their objects really cleanly Serialize (get turned into one long string), but they were going to have to do that anyways.
So just to make sure you’ve got all of the above in your head.
Client
-> Takes an object
-> Makes it serialize
-> Calls a method
-> RMI voodoo magic happens
-> Unknown Magic
-> HTTP
-> SSL
-> Turd burrito is flung across the internet at whatever server is supposed to eat it.
The way RMI is built it is supposed to make everything past “calls a method” look like magic. You aren’t supposed to know where or how your method is being called or passed. This could be on the box next to your feet or calling a method on the Mars Rover. As a developer you’re just supposed to call a function and get a value back. This is great if you are a J2EE developer that wants to take out that hottie from accounting. Bad if want the control required to tinker with the thing.
Proxying the RMI methods was not something I was willing to do. I wasn’t peeling that many layers of beans and rice, then only to deal with serialization issues. I had the turd sitting right in front of me with the source and methods quietly mocking me. What I needed was a ETB eating machine.
Enter JRuby.
JRuby is the bastard child of a ruby interpreter written in Java and is my new very bestest friend. JRuby is the kind of friend that drools on you occasionally, has a gimp eye, but LOVES to chew up turd burritos. As a note Matasano wrote about using RMI via JRuby a while back.
Now what used to look a task of proxying.
Client
-> Takes an object
-> Makes it serialize
-> Calls a method
-> RMI
-> Unknown Magic
-> Http
-> SSL
Becomes one line of code.
com.XXXX.XXX.ui.net.Request.new(com.XXXX.XXX.ui.user.gadgets, cd, com.XXXX.XXX.ui.Function.DOSOMETHING, new Object[] { com.XXXX.XX.Thing.new(1) }).send();
Instead of unwrapping and rewrapping my ETB. I can inject my own chili peppers hoping the server can’t handle the heat and pukes.
Thus like magic my drooling friend JRuby has given me all the control of a hacker, but the comfort and “going home at 5pm on the dot” developers view. Now if I can just find someone to take out in accounting…
So the lesson to be learned is.
1. Less is often more.
2. JRuby rocks my socks even if it does drool a bit.
3. Don’t trust your users.
4. Yes someone will take the time to
Decompile the application. -> Find the right remote request -> Hook in with JRuby -> Make fake objects -> Send them off to the server -> Profit!
The new version of DJ Java Decompiler – 3.11 is ready.Version 3.11.11.95 adds annotation support, new search tool “Search for files inside compressed archives” (JAR, ZIP, WAR, EAR, APK), Imports Viewer and Methods Viewer with sorting capabilities.The price is just 19.98 US$. Also, you can get it for free.
LikeLike