Breaking lazybot out of clojail
Seeing lazybot’s libs
While in #clojure Tim McCormack answered a question by showing lazybot
somnium.congomongo in that list intrigued me. lazybot
uses clojail to restrict some actions, yet I had seen people use
namespaced functions like
clojure.set/map-invert. After some
exploring it was possible to gain access to lazybot’s database, and
even send messages as lazybot with
irclj. These were reported
No direct shell access
I was curious if there were holes beyond the application layer to shell access.
Lazybot uses clojail and the java security policy to prevent bad things. This exception comes from the java policy and says that file access is turned off, which is used by shell access.
clojail.jvm allowed shell access
clojail.jvm contains a function that allows running
code with escalated privileges.
Boom. At this point I’d found a way to get to a shell and run code.
It was also possible to use the
directly in order to do privilege escalation.
Fixed as of:
Now they output one of the following:
Clojure -> Java -> Clojure
Once the direct access of
clojail.jvm/jvm-sandbox was blocked,
it was time to see if there were other ways to get to it. Fortunately,
resolve was blocked:
However, using java interop there were still ways to retrieve the var though
Fixed as of:
There were a few other varations of this that were fixed with the 1.0.0 and 1.0.1 releases.
Clojure -> Java -> Clojure (again)
Clojure functions are compiled into classes that are loaded by the
jvm. It is possible to instantiate and
.invoke them directly. This provided another
technique to break access.
Fixed as of:
Update your clojail
clojail.jvm is sandbox related, the sandboxes that come
with clojail will block it. The underlieing techniques of calling it
through java interop would have worked for gaining access to the
application layer code as well. If you are running a service using
clojail, make sure to update to the latest version with these fixes.
Also, it is important to blacklist any namespaces in the application
that users should not have access to, such as ones with database
A note from Anthony Grimes
After reading a preview of this, Anthony wanted to add a bit at the end.
Nelson did some excellent work here hunting down issues with clojail. He found some issues that resulted in me changing fundamental aspects of clojail. You’ll notice that we’re now past 1.0.0, and there are huge breaking changes. I rewrote the entire ‘tester’ implementation. With Nelson’s motivation, we were also able to make clojail immensely faster. It will never run code quite as fast as it would run outside of the sandbox, but clojail now runs code that used to time out in 15 seconds in less than 200 millseconds. I think that’s a pretty huge improvement!
I personally want to thank Nelson for spending his time finding these things that I and Alan had missed while writing clojail. His contributions will make everything that uses clojail much safer. Make sure that if you use clojail, you always use the latest version. Always report any bugs/holes you find as quickly as possible so that they can get closed. More importantly, while I appreciate Nelson hunting down these holes, there is an appropriate way to go about it (and he, of course, did). If you plan to go hole hunting, here are a couple of things to remember:
- Report the issues. It’s okay to hunt them for fun, but if you don’t report them, you’re leaving it open for other people’s real-world applications to get damaged.
- It is best for you to use a local copy of clojail for trying things out. Don’t abuse websites and public applications (irc bots) without alerting the author first. You may accidentally break something.
- You can use lazybot for testing stuff out, but please do so while I am around. Don’t try to bring the bot down without asking me first. The bot is in a number of channels that you’ve probably never heard of doing various good deeds and those people may or may not be able to survive without their dose of lazybot. ;)
Safe evaluation for all!