각 애플리케이션은 VM의 nginx 리버스 프록시를 통해 접근 가능한 nginx 업스트림 풀 뒤에서 4개의 로드 밸런싱된 Docker 컨테이너로 실행됩니다. 스티키 세션은 상태 저장 애플리케이션(Juice Shop, DVWA, VAmPI, CSD Demo)이 일관되게 라우팅되도록 보장합니다. 모든 애플리케이션은 의도적으로 취약하게 설계되어 보안 테스트용으로 만들어졌습니다.
아래 모든 예제에서 <ORIGIN>을 http://<PUBLIC_IP>로 교체하십시오. Terraform을 통해 배포한 후 terraform output -raw public_ip로 IP를 확인하십시오.
경로 애플리케이션 HTTP 메서드 예상 응답 /랜딩 페이지 GET 모든 앱 링크가 포함된 200 HTML /health헬스 체크 GET 200 JSON {"status":"healthy","component":"origin-server",...} /juice-shop/Juice Shop GET 200 HTML (Angular SPA, ~75 KB) /juice-shop/rest/products/search?q=Juice Shop API GET 200 JSON {"status":"success","data":[...]} (36개 상품) /dvwa/DVWA GET /dvwa/login.php로 302 리다이렉트/dvwa/login.phpDVWA 로그인 GET 200 HTML 로그인 폼 /dvwa/setup.phpDVWA 설정 GET 200 HTML (최초 실행 데이터베이스 초기화) /vampi/VAmPI GET 200 HTML (API 문서) /vampi/users/v1VAmPI API GET 200 JSON {"users":[...]} /vampi/users/v1/registerVAmPI API POST 200 JSON {"status":"success",...} /vampi/users/v1/loginVAmPI API POST 200 JSON {"auth_token":"...","status":"success"} /httpbin/gethttpbin GET 요청 세부 정보가 포함된 200 JSON /httpbin/posthttpbin POST 게시된 데이터가 포함된 200 JSON /httpbin/headershttpbin GET 200 JSON {"headers":{...}} /httpbin/status/:codehttpbin GET 지정된 HTTP 상태 코드 반환 /whoami/whoami GET 호스트명, IP, 모든 헤더가 포함된 200 일반 텍스트 /csd-demo/CSD Demo GET 공격 패널이 있는 200 HTML 체크아웃 폼 /csd-demo/dashboardCSD 공격자 뷰 GET 유출된 데이터를 보여주는 200 HTML /csd-demo/healthCSD 헬스 GET 200 JSON {"status":"healthy","component":"csd-demo",...} /csd-demo/exfil/logCSD 유출 로그 GET 캡처된 데이터의 200 JSON 배열 /dvga/DVGA GraphiQL GET 200 HTML (GraphiQL IDE) /dvga/graphqlDVGA GraphQL API POST 200 JSON GraphQL 응답 /restaurant/RESTaurant GET 200 (문서로 리다이렉트) /restaurant/docsRESTaurant Swagger GET 200 HTML (FastAPI Swagger UI) /restaurant/openapi.jsonRESTaurant OpenAPI GET 200 JSON OpenAPI 사양 http://<PUBLIC_IP>:8888crAPI GET 200 HTML (SPA) http://<PUBLIC_IP>:8888/identity/api/auth/signupcrAPI 회원가입 POST 200 JSON http://<PUBLIC_IP>:8888/identity/api/auth/logincrAPI 로그인 POST 200 JSON {"token":"..."}
경로 /juice-shop/이미지 bkimminich/juice-shop:latest인스턴스 4개 (포트 3001-3004), hash $cookie_token을 통한 스티키, 프록시 캐시 (60초 TTL) 리소스 인스턴스당 CPU 2개 / RAM 1 GiB 프레임워크 Node.js / Angular 프로젝트 owasp.org/www-project-juice-shop
OWASP Juice Shop은 가장 현대적이고 활발히 유지 관리되는 취약한 웹 애플리케이션입니다. 실제 전자상거래 애플리케이션에서 100개 이상의 챌린지로 OWASP Top 10 전체를 다룹니다.
시나리오 카테고리 공격 벡터 SQL 인젝션 로그인 우회 웹 앱 방화벽 (WAF) 로그인 이메일 필드에 ' OR 1=1-- 입력 반사형 XSS 웹 앱 방화벽 (WAF), 클라이언트 측 방어 검색 파라미터를 통한 스크립트 인젝션 DOM 기반 XSS 클라이언트 측 방어 URL 프래그먼트의 페이로드 취약한 인증 웹 앱 방화벽 (WAF) 브루트 포스 로그인, JWT 조작 API 남용 API 보안 /api/ 엔드포인트에 대한 무단 접근민감한 데이터 노출 API 보안 인증 없이 사용자 데이터 접근 CSRF 웹 앱 방화벽 (WAF) 프로필 변경에 대한 사이트 간 요청 위조
curl -s " http://<PUBLIC_IP>/juice-shop/ " -o /dev/null -w " %{http_code} "
경로 /dvwa/이미지 커스텀 dvwa-fpm:latest (php-fpm + nginx, ghcr.io/digininja/dvwa:latest에서 빌드) 인스턴스 4개 (포트 8101-8104), hash $cookie_PHPSESSID를 통한 스티키 리소스 인스턴스당 CPU 0.5개 / RAM 256 MiB 데이터베이스 공유 MariaDB 10.11 (dvwa-db 컨테이너, CPU 1개 / 768 MiB) 프레임워크 PHP 8 / php-fpm / MariaDB 자격 증명 admin / password
DVWA는 웹 앱 방화벽 (WAF) 테스트의 업계 표준입니다. 점진적으로 입력 유효성 검사와 출력 인코딩을 추가하는 조정 가능한 보안 수준(낮음, 보통, 높음, 불가능)을 제공합니다.
시나리오 카테고리 보안 수준 SQL 인젝션 웹 앱 방화벽 (WAF) 낮음: 단순한 ' OR 1=1#, 높음: 블라인드 SQLi 커맨드 인젝션 웹 앱 방화벽 (WAF) 낮음: ; ls, 높음: 필터링된 문자 파일 인클루전 웹 앱 방화벽 (WAF) 낮음: 직접 경로 탐색, 높음: 정제됨 XSS (반사형) 웹 앱 방화벽 (WAF), 클라이언트 측 방어 낮음: 기본 <script>, 높음: 인코딩 우회 XSS (저장형) 웹 앱 방화벽 (WAF), 클라이언트 측 방어 낮음: 방명록에 영속적 스크립트 파일 업로드 웹 앱 방화벽 (WAF) 낮음: PHP 쉘 업로드, 높음: 확장자 필터링 브루트 포스 Bot 표준 방어 자동화된 로그인 시도
로그인 후 /dvwa/security.php에서 보안 수준을 설정하십시오:
낮음 — 입력 유효성 검사 없음. 모든 공격이 작동합니다. 웹 앱 방화벽 (WAF) 시그니처 시연에 적합합니다.
보통 — 기본 필터링. 일부 공격은 인코딩 또는 우회 기법이 필요합니다.
높음 — 강력한 필터링. 고급 기법만 성공합니다. 웹 앱 방화벽 (WAF) 한계를 보여주기에 적합합니다.
불가능 — 완전히 안전한 구현. 적절한 방어적 코딩을 시연합니다.
DVWA는 첫 번째 배포 후 일회성 데이터베이스 설정이 필요합니다:
http://<PUBLIC_IP>/dvwa/setup.php로 이동합니다
Create / Reset Database 를 클릭합니다
admin / password로 로그인합니다
경로 /vampi/이미지 gunicorn 엔트리포인트(4 워커)를 사용하는 erev0s/vampi:latest 인스턴스 4개 (포트 5101-5104), ip_hash를 통한 스티키 (인스턴스별 SQLite) 리소스 인스턴스당 CPU 0.5개 / RAM 512 MiB 프레임워크 Python / Flask / gunicorn 프로젝트 github.com/erev0s/VAmPI
VAmPI는 OWASP API Security Top 10 테스트를 위해 특별히 제작되었습니다. 의도적인 취약점이 있는 현실적인 REST API를 제공합니다. 각 인스턴스는 4개의 워커와 자체 SQLite 데이터베이스로 gunicorn을 실행합니다. ip_hash 스티키 세션은 동일한 클라이언트 IP에서의 등록 및 로그인이 항상 동일한 인스턴스에 연결되도록 보장합니다.
시나리오 OWASP API Top 10 방법 객체 수준 인증 취약점 (BOLA) API1 ID 조작으로 다른 사용자의 데이터 접근 취약한 인증 API2 약한 토큰 처리, 속도 제한 없음 과도한 데이터 노출 API3 API가 클라이언트에 필요한 것 이상의 데이터 반환 대량 할당 API6 예상치 못한 파라미터를 통한 관리자 필드 수정 SQL 인젝션 API8 API 파라미터를 통한 인젝션 부적절한 자산 관리 API9 문서화되지 않은 API 엔드포인트
curl -X POST " http://<PUBLIC_IP>/vampi/users/v1/register " \
-H " Content-Type: application/json " \
-d ' {"username":"test","password":"test123","email":"test@test.com"} '
curl -X POST " http://<PUBLIC_IP>/vampi/users/v1/login " \
-H " Content-Type: application/json " \
-d ' {"username":"test","password":"test123"} '
curl " http://<PUBLIC_IP>/vampi/users/v1 "
경로 /httpbin/이미지 gunicorn CMD 오버라이드(-w 4 -k gevent --timeout 30)를 사용하는 kennethreitz/httpbin:latest 인스턴스 4개 (포트 8201-8204), 라운드 로빈 (무상태) 리소스 인스턴스당 CPU 0.5개 / RAM 256 MiB 프레임워크 Python / Flask / gunicorn + gevent 프로젝트 httpbin.org
httpbin은 기본 API 데모, 요청 헤더 테스트 및 프록시 동작 확인에 유용한 간단한 HTTP 요청/응답 서비스입니다.
엔드포인트 목적 /httpbin/getGET 요청 데이터 반환 (헤더, 인자, 출처) /httpbin/postPOST 요청 데이터 반환 (본문, 폼, JSON) /httpbin/headers요청 헤더 반환 /httpbin/ip출처 IP 반환 /httpbin/user-agentUser-Agent 헤더 반환 /httpbin/status/:code지정된 HTTP 상태 코드 반환 /httpbin/delay/:secondsN초 동안 응답 지연 /httpbin/anything요청에서 전달된 모든 것 반환
# 오리진 서버가 어떤 헤더를 받는지 확인 (F5 XC 헤더 인젝션 확인에 유용)
curl -s " http://<PUBLIC_IP>/httpbin/headers " | jq .
curl -s -o /dev/null -w " %{http_code} " " http://<PUBLIC_IP>/httpbin/status/403 "
경로 /whoami/이미지 traefik/whoami:latest인스턴스 4개 (포트 8082-8085), 라운드 로빈 (무상태) 리소스 인스턴스당 CPU 0.25개 / RAM 64 MiB 프레임워크 Go 프로젝트 github.com/traefik/whoami
whoami는 Traefik의 경량 요청 에코 서버입니다. 오리진 서버가 받는 수신 HTTP 요청의 모든 세부 정보(호스트명, IP 주소, 모든 헤더, 메서드 및 URL)를 표시합니다. 이것은 F5 XC가 올바른 헤더를 주입하고 있는지 확인할 때 가장 중요한 단일 진단 도구입니다.
사용 사례 확인 사항 F5 XC 헤더 인젝션 확인 X-Forwarded-For, True-Client-IP, X-Volterra-* 헤더클라이언트 IP 가시성 확인 X-Real-IP 대 RemoteAddr웹 앱 방화벽 (WAF) 오탐 디버그 F5 XC 전후 요청 헤더 비교 Bot 방어 태깅 유효성 검사 X-Volterra-Bot-Type, X-Volterra-Bot-Verified 헤더TLS 종료 확인 X-Forwarded-Proto가 F5 XC에서 TLS 종료 시 https를 표시
# 기본 요청 -- 오리진 서버가 받는 것을 확인
curl " http://<PUBLIC_IP>/whoami/ "
# F5 XC를 통한 요청 시뮬레이션 (주입된 헤더 포함)
curl " http://<PUBLIC_IP>/whoami/ " \
-H " X-Forwarded-For: 203.0.113.50 " \
-H " True-Client-IP: 203.0.113.50 " \
-H " X-Forwarded-Proto: https "
출력 예시:
RemoteAddr: 172.17.0.1:55118
True-Client-Ip: 203.0.113.50
X-Forwarded-For: 203.0.113.50, 10.0.0.1
X-Real-Ip: 104.219.105.84
DVGA는 GraphQL 특정 취약점 테스트를 위해 특별히 제작되었습니다. 대화형 쿼리 탐색을 위한 GraphiQL IDE를 /dvga/에서 제공하고, GraphQL API 엔드포인트를 /dvga/graphql에서 제공합니다. 각 인스턴스는 자체 SQLite 데이터베이스를 사용하므로, ip_hash 스티키 세션이 일관된 상태를 보장합니다.
시나리오 카테고리 공격 벡터 GraphQL 인젝션 API 보안 문자열 보간을 통한 악성 쿼리 서비스 거부 API 보안 깊게 중첩된 쿼리, 배치 쿼리, 리소스 소진 인증 우회 API 보안 GraphQL을 통한 무단 데이터 접근 정보 노출 API 보안 스키마 세부 정보를 노출하는 인트로스펙션 쿼리 배치 공격 API 보안 단일 요청의 여러 작업
curl -sf " http://<PUBLIC_IP>/dvga/ " -o /dev/null -w " %{http_code} "
curl -s " http://<PUBLIC_IP>/dvga/graphql " \
-H " Content-Type: application/json " \
-d ' {"query":"{ __schema { types { name fields { name } } } }"} '
curl -s " http://<PUBLIC_IP>/dvga/graphql " \
-H " Content-Type: application/json " \
-d ' {"query":"{ pastes { title content } }"} '
curl -s " http://<PUBLIC_IP>/dvga/graphql " \
-H " Content-Type: application/json " \
-d ' {"query":"mutation { createPaste(title:\"test\", content:\"hello\", public:true) { paste { title } } }"} '
경로 /restaurant/이미지 theowni/Damn-Vulnerable-RESTaurant-API-Game에서 커스텀 빌드인스턴스 4개 (포트 8301-8304), 라운드 로빈 (공유 PostgreSQL) 리소스 인스턴스당 CPU 0.5개 / RAM 256 MiB 데이터베이스 공유 PostgreSQL 15.4 (restaurant-db 컨테이너, CPU 0.5개 / 512 MiB) 프레임워크 Python / FastAPI / PostgreSQL 자격 증명 admin / password (PostgreSQL)프로젝트 github.com/theowni/Damn-Vulnerable-RESTaurant-API-Game
RESTaurant는 OWASP API Security Top 10 2023을 다루는 게임화된 취약한 REST API입니다. /restaurant/docs에서 자동 Swagger UI 문서와 함께 FastAPI를 사용합니다. 4개의 인스턴스 모두 단일 PostgreSQL 데이터베이스를 공유하므로, 스티키 세션 없이 라운드 로빈 로드 밸런싱이 작동합니다.
시나리오 OWASP API Top 10 2023 방법 객체 수준 인증 취약점 (BOLA) API1 ID 조작으로 다른 사용자의 주문 접근 취약한 인증 API2 약한 토큰 처리, 자격 증명 스터핑 객체 속성 수준 인증 취약점 API3 사용자 프로필 필드에 대량 할당 무제한 리소스 소비 API4 엔드포인트에 속도 제한 없음 기능 수준 인증 취약점 (BFLA) API5 일반 사용자로 관리자 엔드포인트 접근 서버 측 요청 위조 (SSRF) API7 서버 측 URL 요청 조작 보안 설정 오류 API8 상세한 오류 메시지, 기본 자격 증명
curl -sf " http://<PUBLIC_IP>/restaurant/docs " -o /dev/null -w " %{http_code} "
curl -s " http://<PUBLIC_IP>/restaurant/openapi.json " | jq .info
# BOLA -- 다른 사용자의 주문 접근 (인증 후)
curl -s " http://<PUBLIC_IP>/restaurant/orders/1 " \
-H " Authorization: Bearer <token> "
# BFLA -- 일반 사용자로 관리자 작업 시도
curl -s -X POST " http://<PUBLIC_IP>/restaurant/admin/users " \
-H " Authorization: Bearer <user_token> " \
-H " Content-Type: application/json "
포트 8888 (전용 — 경로 접두사 없음)이미지 crapi/crapi-web, crapi/crapi-identity, crapi/crapi-community, crapi/crapi-workshop, PostgreSQL, MongoDB, MailHog인스턴스 7개 마이크로서비스 (각 단일 인스턴스) 리소스 총 CPU ~3.0개 / RAM ~2.0 GiB 프레임워크 React SPA + Java/Go/Python 마이크로서비스 프로젝트 github.com/OWASP/crAPI
crAPI는 API 보안 테스트를 위한 OWASP 플래그십 프로젝트입니다. React SPA가 API 경로를 하드코딩하고 경로 접두사 뒤에서 제공될 수 없기 때문에 전용 포트(8888)에서 7개의 마이크로서비스로 실행됩니다. NSG는 포트 8888의 인바운드 트래픽을 허용합니다.
MailHog는 crAPI가 발송하는 모든 이메일(계정 확인, 비밀번호 재설정)을 캡처합니다. 포트 18025에서 SSH 터널을 통해 MailHog에 접근합니다.
카테고리 취약점 BOLA (객체 수준 인증 취약점) 다른 사용자의 차량, 주문 및 보고서 접근 BFLA (기능 수준 인증 취약점) 관리자로 권한 상승, 제한된 엔드포인트 접근 대량 할당 API를 통해 보호된 필드(역할, 잔액) 수정 SSRF (서버 측 요청 위조) 서버 측 URL 가져오기 조작 JWT 조작 권한 상승을 위한 JWT 토큰 위조 또는 수정 NoSQL 인젝션 MongoDB 기반 엔드포인트에 쿼리 인젝션 과도한 데이터 노출 API가 민감한 사용자 데이터 반환
curl -sf " http://<PUBLIC_IP>:8888 " -o /dev/null -w " %{http_code} "
curl -s -X POST " http://<PUBLIC_IP>:8888/identity/api/auth/signup " \
-H " Content-Type: application/json " \
-d ' {"name":"Test User","email":"test@example.com","number":"1234567890","password":"Test1234!"} '
curl -s -X POST " http://<PUBLIC_IP>:8888/identity/api/auth/login " \
-H " Content-Type: application/json " \
-d ' {"email":"test@example.com","password":"Test1234!"} '
# MailHog 접근 (이메일 인증을 위한 SSH 터널 사용)
# ssh -L 18025:localhost:18025 azureuser@<PUBLIC_IP>
# 그런 다음 브라우저에서 http://localhost:18025 열기
Port 8888 -> crapi-web (React SPA + nginx)
-> crapi-identity (Java, user auth, JWT)
-> crapi-community (Go, forums, posts)
-> crapi-workshop (Python, vehicle service)
-> crapi-postgres (PostgreSQL)
-> crapi-mailhog (email capture, port 18025)
데모 사용 사례 주요 앱 보조 앱 웹 앱 방화벽 (WAF) — SQL 인젝션 DVWA Juice Shop 웹 앱 방화벽 (WAF) — XSS DVWA Juice Shop 웹 앱 방화벽 (WAF) — 커맨드 인젝션 DVWA — API 보안 — BOLA VAmPI — API 보안 — 인증 우회 VAmPI Juice Shop API 보안 — 데이터 노출 VAmPI httpbin Bot 표준 방어 — 브루트 포스 DVWA Juice Shop Bot 표준 방어 — 스크래핑 Juice Shop — 클라이언트 측 방어 — DOM XSS Juice Shop — 클라이언트 측 방어 — 저장형 XSS DVWA Juice Shop 클라이언트 측 방어 — 카드 스키머 CSD Demo — 클라이언트 측 방어 — 폼재킹 CSD Demo — 클라이언트 측 방어 — 키로거 CSD Demo — 클라이언트 측 방어 — 크립토마이너 CSD Demo — 클라이언트 측 방어 — DOM 하이재킹 CSD Demo — API 보안 — GraphQL 인젝션 DVGA — API 보안 — GraphQL DoS DVGA — API 보안 — OWASP API Top 10 2023 RESTaurant crAPI API 보안 — BFLA RESTaurant crAPI API 보안 — 대량 할당 crAPI RESTaurant API 보안 — SSRF crAPI RESTaurant API 보안 — JWT 조작 crAPI — API 보안 — NoSQL 인젝션 crAPI — 기본 연결 테스트 httpbin — 요청 진단 whoami httpbin 헤더 인젝션 확인 whoami —