Kubernetes 이야기

OWASP ZAP 을 Kubernetes 환경에서 사용하기 본문

Kubernetes/devops

OWASP ZAP 을 Kubernetes 환경에서 사용하기

kmaster 2022. 4. 2. 01:42
반응형

OWASP ZAP

 

OWASP ZAP는 오픈 소스 웹 애플리케이션 보안 스캐너이다. 웹 애플리케이션이 개발되어 서비스 오픈전에 보통 검사하도록 되어 있다. 웹 애플리케이션 보안 스캐너 중 가장 일반적으로 많이 사용된 오픈소스 보안 프로젝트 프로젝트 중 하나이다.

 

이러한 OWASP ZAP 도 Container 로 배포되어 있다. ( owasp/zap2docker-stable )

 

WEB 환경에서 실행

 

아래와 같이 yaml 을 실행해 보자.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: zap-deployment
  labels:
    app: zap-app
spec:
  replicas: 1
  selector:
    matchLabels:
      name: zap-application
      app: zap-app
  template:
    metadata:
      name: zap-application
      labels:
        name: zap-application
        app: zap-app
    spec:
      containers:
        - name: zaproxy
          image: owasp/zap2docker-stable
          command: ["zap-webswing.sh"]
          ports:
            - containerPort: 8080
          volumeMounts:
          - mountPath: /home/zap/.ZAP/session/
            name: session
      volumes:
      - name: session
        persistentVolumeClaim:
          claimName: zap-storage
---
apiVersion: v1
kind: Service
metadata:
  name: zaproxy
  labels:
    name: zap-service
    app: azp-app
spec:
  ports:
    - port: 8080
      targetPort: 8080
  selector:
    name: zap-application
    app: zap-app
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: zap-storage
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: "standard"
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: zap-ingress
spec:
  rules:
  - host: "zap.10.20.100.20.nip.io"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: zaproxy
            port:
              number: 8080

 

이제 배포된 ingress로 접속해 보자. 이때 http://zap.10.20.100.20.nip.io/zap 까지 입력해야 비인증 모드로 호출할 수 있다.

이제 간단히 "Automated Scan"으로 한번 실행해 보자. ( 절대 알려진 URL이나 ip를 입력하면 안된다. )

Kubernetes에 실행중인 bar-service라는 앱의 취약점을 체크해 보겠다.

 

 

"Attack" 버튼을 클릭하여 점검하면 아래와 같이 점검결과를 조회할 수 있다.

 

그럼 브라우저로 검사하는 방식이 아닌, 파이프라인에서 자동으로 검사하는 방식으로 테스트를 해보자.

 

owasp/zap2docker-stable container는 총 3개가지의 스캔 script를 제공한다.

 

1. zap-api-scan.py

로컬 파일이나 URL을 통해 OpenAPI, SOAP 또는 GraphQL에 의해 정의된 API에 대해 스캔을 수행하도록 조정한다.

지정한 정의를 가져온 다음 발견된 URL에 대해 Active Scan을 실행한다. Active Scan은 API에 맞춰져 있으므로 XSS와 같은 것을 찾는 데 신경쓰지 않는다.

또한 다음과 같은 2개의 스크립트가 포함되어 있습니다.

  - 모든 HTTP 서버 오류 응답 코드에 대한 경고 발생 
  - 일반적으로 API와 연결되지 않는 콘텐츠 유형을 반환하는 모든 URL에 대해 경고 발생

 

2. zap-full-scan.py

지정된 대상(기본적으로 시간 제한 없음)에 대해 ZAP 스파이더를 실행한 다음 선택적 ajax 스파이더 스캔을 실행한 다음 결과를 보고하기 전에 전체 활성 스캔을 실행한다.

이는 스크립트가 실제 '공격'을 수행하고 잠재적으로 장기간 실행될 수 있음을 의미한다.

기본적으로 모든 경고를 경고로 보고하지만 규칙을 FAIL 또는 IGNORE로 변경할 수 있는 구성 파일을 지정할 수 있다.

 

3. zap-baseline.py

지정된 대상에 대해 (기본적으로) 1분 동안 ZAP 스파이더를 실행한 다음 결과를 보고하기 전에 수동 스캔이 완료될 때까지 기다린다.

이는 스크립트가 실제 '공격'을 수행하지 않고 비교적 짧은 시간(최대 몇 분) 동안 실행됨을 의미한다.
기본적으로 모든 경고를 경고로 보고하지만 규칙을 FAIL 또는 IGNORE로 변경할 수 있는 구성 파일을 지정할 수 있다.
이 스크립트는 프로덕션 사이트에서도 CI/CD 환경에서 실행하는 데 이상적이다.

 

그럼 스캔방식 중 zap-baseline.py으로 앱 애플리케이션을 스캔해보자.

 

apiVersion: batch/v1
kind: Job
metadata:
  name: zap-job
spec:
  template:
    spec:
      containers:
      - name: zap
        image: owasp/zap2docker-stable
        command: ["zap-baseline.py"]
        args:
        - '-t'
        - 'http://bar-service.default:5678'
      restartPolicy: Never
  backoffLimit: 0

 

이제 스캔을 실행해 보자.

# kubectl create -f job.yaml -n test
# kubectl get job -n test
NAME      COMPLETIONS   DURATION   AGE
zap-job   0/1           14s        14s

# kubectl get pod -n test
NAME                                  READY   STATUS    RESTARTS   AGE
pod/zap-job-f24ml                     0/1     Error     0          101s

실행이 완료되면 job이 fail 상태로 보인다. 이 이유는 스캔 결과 WARN_COUNT > 0 보다 크면 exit(2) 로 실행되기 때문이다. (https://github.com/zaproxy/zaproxy/issues/5507)

    if exception_raised:
        sys.exit(3)
    elif fail_count > 0:
        sys.exit(1)
    elif (not ignore_warn) and warn_count > 0:
        sys.exit(2)
    elif pass_count > 0:
        sys.exit(0)
    else:
        sys.exit(3)

 

실행결과를 보면 아래와 같다.

# kubectl logs -f -n test zap-job-f24ml
Using the Automation Framework
Downloading add-on from: https://github.com/zaproxy/zap-extensions/releases/download/pscanrulesBeta-v28/pscanrulesBeta-beta-28.zap
Add-on downloaded to: /home/zap/.ZAP/plugin/pscanrulesBeta-beta-28.zap
Total of 3 URLs
PASS: Vulnerable JS Library [10003]
PASS: Cookie No HttpOnly Flag [10010]
PASS: Cookie Without Secure Flag [10011]
PASS: Re-examine Cache-control Directives [10015]
PASS: Cross-Domain JavaScript Source File Inclusion [10017]
PASS: Content-Type Header Missing [10019]
PASS: Anti-clickjacking Header [10020]
PASS: Information Disclosure - Debug Error Messages [10023]
PASS: Information Disclosure - Sensitive Information in URL [10024]
PASS: Information Disclosure - Sensitive Information in HTTP Referrer Header [10025]
PASS: HTTP Parameter Override [10026]
PASS: Information Disclosure - Suspicious Comments [10027]
PASS: Open Redirect [10028]
PASS: Cookie Poisoning [10029]
PASS: User Controllable Charset [10030]
PASS: User Controllable HTML Element Attribute (Potential XSS) [10031]
PASS: Viewstate [10032]
PASS: Directory Browsing [10033]
PASS: Heartbleed OpenSSL Vulnerability (Indicative) [10034]
PASS: Strict-Transport-Security Header [10035]
PASS: HTTP Server Response Header [10036]
PASS: Server Leaks Information via "X-Powered-By" HTTP Response Header Field(s) [10037]
PASS: Content Security Policy (CSP) Header Not Set [10038]
PASS: X-Backend-Server Header Information Leak [10039]
PASS: Secure Pages Include Mixed Content [10040]
PASS: HTTP to HTTPS Insecure Transition in Form Post [10041]
PASS: HTTPS to HTTP Insecure Transition in Form Post [10042]
PASS: User Controllable JavaScript Event (XSS) [10043]
PASS: Big Redirect Detected (Potential Sensitive Information Leak) [10044]
PASS: Retrieved from Cache [10050]
PASS: X-ChromeLogger-Data (XCOLD) Header Information Leak [10052]
PASS: Cookie without SameSite Attribute [10054]
PASS: CSP [10055]
PASS: X-Debug-Token Information Leak [10056]
PASS: Username Hash Found [10057]
PASS: X-AspNet-Version Response Header [10061]
PASS: PII Disclosure [10062]
PASS: Timestamp Disclosure [10096]
PASS: Hash Disclosure [10097]
PASS: Cross-Domain Misconfiguration [10098]
PASS: Weak Authentication Method [10105]
PASS: Reverse Tabnabbing [10108]
PASS: Modern Web Application [10109]
PASS: Absence of Anti-CSRF Tokens [10202]
PASS: Private IP Disclosure [2]
PASS: Session ID in URL Rewrite [3]
PASS: Script Passive Scan Rules [50001]
PASS: Stats Passive Scan Rule [50003]
PASS: Insecure JSF ViewState [90001]
PASS: Charset Mismatch [90011]
PASS: Application Error Disclosure [90022]
PASS: WSDL File Detection [90030]
PASS: Loosely Scoped Cookie [90033]
WARN-NEW: X-Content-Type-Options Header Missing [10021] x 3
        http://bar-service.default:5678 (200 OK)
        http://bar-service.default:5678/robots.txt (200 OK)
        http://bar-service.default:5678/sitemap.xml (200 OK)
FAIL-NEW: 0     FAIL-INPROG: 0  WARN-NEW: 1     WARN-INPROG: 0  INFO: 0 IGNORE: 0       PASS: 53

 

반응형

'Kubernetes > devops' 카테고리의 다른 글

Keda와 Prometheus를 이용한 Scale in/out  (0) 2022.04.28
Kubernetes의 Replica를 0으로 확장 (KEDA)  (0) 2022.04.27
code-server로 개발하기  (0) 2022.03.30
Kubernetes에서 Gitea 사용하기  (0) 2022.03.23
(docker) PMD 사용하기  (0) 2022.03.22
Comments