The attack vectors describe in this blog post are based on two scenarios I came across earlier this year. For each of those scenarios, I will present the engines used and some malicious samples to exploit those.
If you are looking for contextualize scenario, you can look at the follow article (Popping a shell on the Oculus Developer Portal). The attack described, in the previous article, take advantage of an expose eval function on the Oculus Developer Portal.
Spring Expression Language (SpEL)
The Spring Expression Language is the syntax used by spring for configuration and code place in annotations. It support a syntax that is close to Java code but with many limitations.
Spring exressions can be invoked as follow:
ExpressionParser parser = new SpelExpressionParser(); StandardEvaluationContext testContext = new StandardEvaluationContext(TEST_PERSON); Expression exp = parser.parseExpression(dynamicValue); // name = 'Bob' String valueExtracted = exp.getValue(testContext, String.class);
Malicious input script
The main limitation when injecting inside a SpEL expression is that the code must be a "oneliner". No assignment are possible. This force us to use a sequence of telescopic methods.
The following will blindly execute a command :
The result of the expression evaluation could be displayed back to the user. If it is the case, the output can be redirected and converted to a String using the Scanner class.
(new java.util.Scanner( (T(java.lang.Runtime).getRuntime().exec("uname -a").getInputStream()),"UTF-8")) .useDelimiter("\\A").next()
To ex-filtrate data there is many options available. Here is one creating an HTTP request with data pass in a GET parameter.
ScriptEngine / Rhino
The application code using the Rhino engine will look like this :
import javax.script.ScriptEngine; ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("js"); Object result = scriptEngine.eval(dynamiceCodeHere);
Malicious input script
If you manage to control some part or all of the script evaluate, you can interact with the variable place in the context but, you can also interact fully with the JVM (by default). Rhino has many syntax additions to allow to interact with the Java API. For exemple, the following script will execute the command "calc.exe" by creating a instance of
ProcessBuilderand starting the process.
Sandboxing the Script Evaluation
Of course, not using those api can mitigate the risk instantly. If you are still convince that providing scripting interaction for your remote users is a good idea, you can use sandboxing mechanism to limit the attacks that were presented.
The SpEL evaluation can be configure to allow specific methods, constructors and fields access. It can be done by providing a MethodResolver, ConstructorResolver and PropertyAccessor to the evaluation context. See SpEL documentation for more details. As always, a white list should be build not a black list.
In the case of Rhino, the context can take a ClassShutter that allow or disallow the access to certain classes. If you need to disallow all access to the native API, you can reused the rhino-sandbox project created by cloudbees.
Remote Code with Expression Language Injection : Other examples of malicious script for SpEL Spring Expression Language (SpEL) : Reference to the language itself
Expression Language Injection by Stefano Di Paola and Arshan Dabirsiaghi : The paper doesn't cover command execution or file system access.
Sandboxing Rhino in Java : Code sample of a proper sandboxing.
Rhino Documentation : Rhino documentation for reference on writing scripts
rhino-sandbox : Github project to disallow all access to native api.