mirror of
https://github.com/MichaelCade/90DaysOfDevOps.git
synced 2025-01-31 01:45:03 +07:00
Translate day14-20 into korean
This commit is contained in:
parent
2d725f1510
commit
a89303d47c
279
2023/ko/days/day14.md
Normal file
279
2023/ko/days/day14.md
Normal file
@ -0,0 +1,279 @@
|
||||
# 컨테이너 이미지 스캐닝
|
||||
|
||||
컨테이너 이미지는 이미지 매니페스트, 파일 시스템 및 이미지 구성으로 구성됩니다. [1](https://opencontainers.org/about/overview/)
|
||||
|
||||
예를 들어, Java 애플리케이션용 컨테이너 이미지의 파일 시스템에는 Linux 파일 시스템, JVM 및 애플리케이션을 나타내는 JAR/WAR 파일이 있습니다.
|
||||
|
||||
컨테이너를 사용하는 경우 CI/CD 파이프라인의 중요한 부분은 이러한 컨테이너에 알려진 취약성이 있는지 스캐닝하는 프로세스여야 합니다.
|
||||
이를 통해 컨테이너 내부에 있는 취약성의 수에 대한 귀중한 정보를 얻을 수 있으며, 취약한 애플리케이션을 운영 환경에 배포하고 이러한 취약성으로 인해 해킹되는 것을 방지할 수 있습니다.
|
||||
|
||||
2021년 말 발견된 [Log4Shell](https://en.wikipedia.org/wiki/Log4Shell) 취약성을 예로 들어보겠습니다.
|
||||
너무 자세히 설명하지 않아도 응용프로그램에 이 취약성이 있다는 것은 공격자가 서버에서 임의 코드를 실행할 수 있다는 것을 의미합니다.
|
||||
이 취약성은 가장 인기 있는 Java 라이브러리 중 하나인 [Log4j](https://logging.apache.org/log4j/2.x/) 에 있기 때문에 더욱 악화되었습니다.
|
||||
꽤나 나쁘네요!
|
||||
|
||||
그렇다면 우리가 취약한지 어떻게 알 수 있을까요?
|
||||
|
||||
정답은 **Image Scanning**입니다.
|
||||
|
||||
이미지 스캐닝 프로세스는 컨테이너 내부를 살펴보고, 설치된 패키지 목록(리눅스 패키지일 수도 있지만 자바, Go, 자바스크립트 패키지 등일 수도 있음)을 가져오고, 패키지 목록을 각 패키지에 대해 알려진 취약성 데이터베이스와 교차 참조하고, 최종적으로 지정된 컨테이너 이미지에 대한 취약성 목록을 생성하는 것으로 구성됩니다.
|
||||
|
||||
컴퓨터 로컬이나 CI/CD 파이프라인에서 컨테이너 이미지를 바로 설치하고 스캔을 시작할 수 있는 오픈 소스 및 독점 이미지 스캐너가 많이 있습니다.
|
||||
가장 인기 있는 두 가지는 [Triby](https://github.com/aquasecurity/trivy) 와 [Grype](https://github.com/anchore/grype) 입니다.
|
||||
일부 독점 제품은 [Snyk](https://docs.snyk.io/products/snyk-container/snyk-cli-for-container-security) (계정 필요, Free tier 있음) 및 [VMware Carbon Black](https://carbonblack.vmware.com/resource/carbon-black-cloud-container-security-faq#overview) (계정 필요, Free tier 없음)입니다.
|
||||
|
||||
컨테이너 이미지를 스캔하는 것은 다음 중 하나를 설치하고 실행하는 것처럼 간단합니다:
|
||||
|
||||
```console
|
||||
$ grype ubuntu:latest
|
||||
✔ Vulnerability DB [updated]
|
||||
✔ Pulled image
|
||||
✔ Loaded image
|
||||
✔ Parsed image
|
||||
✔ Cataloged packages [101 packages]
|
||||
✔ Scanned image [16 vulnerabilities]
|
||||
NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY
|
||||
bash 5.1-6ubuntu1 deb CVE-2022-3715 Medium
|
||||
coreutils 8.32-4.1ubuntu1 deb CVE-2016-2781 Low
|
||||
gpgv 2.2.27-3ubuntu2.1 deb CVE-2022-3219 Low
|
||||
libc-bin 2.35-0ubuntu3.1 deb CVE-2016-20013 Negligible
|
||||
libc6 2.35-0ubuntu3.1 deb CVE-2016-20013 Negligible
|
||||
libncurses6 6.3-2 deb CVE-2022-29458 Negligible
|
||||
libncursesw6 6.3-2 deb CVE-2022-29458 Negligible
|
||||
libpcre3 2:8.39-13ubuntu0.22.04.1 deb CVE-2017-11164 Negligible
|
||||
libsystemd0 249.11-0ubuntu3.6 deb CVE-2022-3821 Medium
|
||||
libtinfo6 6.3-2 deb CVE-2022-29458 Negligible
|
||||
libudev1 249.11-0ubuntu3.6 deb CVE-2022-3821 Medium
|
||||
login 1:4.8.1-2ubuntu2 deb CVE-2013-4235 Low
|
||||
ncurses-base 6.3-2 deb CVE-2022-29458 Negligible
|
||||
ncurses-bin 6.3-2 deb CVE-2022-29458 Negligible
|
||||
passwd 1:4.8.1-2ubuntu2 deb CVE-2013-4235 Low
|
||||
zlib1g 1:1.2.11.dfsg-2ubuntu9.2 deb CVE-2022-42800 Medium
|
||||
```
|
||||
|
||||
이 명령을 사용하여 `ubuntu:latest` 컨테이너 이미지를 스캔한 결과 16개의 취약점이 있는 것으로 나타났습니다.
|
||||
|
||||
각 취약성에는 [CVSS](https://nvd.nist.gov/vuln-metrics/cvss) 점수에 따라 심각도가 있습니다.
|
||||
심각도는 '낮음'부터 '심각함'까지 다양합니다.
|
||||
|
||||
16개의 취약점은 많아 보이지만, 어느 것도 '크리티컬(Critical)'한 심각성을 가지고 있지 않습니다.
|
||||
|
||||
또한 결과 테이블의 'FIXED-IN' 열이 비어 있습니다.
|
||||
이는 해당 패키지의 최신 버전에서 이 취약성이 수정되지 않음을 의미합니다.
|
||||
|
||||
`ubuntu:latest`는 Ubuntu의 공식 컨테이너 이미지의 최신 버전이기 때문에 이는 예상됩니다.
|
||||
일반적으로 이러한 이미지는 정기적으로 업데이트되므로 이러한 이미지에 많은 취약점이 있을 것으로 예상해서는 안 됩니다.(적어도 사용 가능한 수정 사항이 있는 이미지는 아님).
|
||||
|
||||
오래된 이미지, 임의의 이미지, 대기업에서 지원하지 않는 이미지 또는 자신이 관리하지 않는 이미지의 경우에는 그렇지 않을 수 있습니다.
|
||||
|
||||
예를 들어, Docker Hub의 `springio` 조직에서 임의 이미지 2년 된 이미지를 스캔하면 훨씬 더 많은 취약점이 잠재해 있음을 알 수 있습니다:
|
||||
|
||||
```console
|
||||
$ grype springio/petclinic:latest
|
||||
✔ Vulnerability DB [no update available]
|
||||
✔ Pulled image
|
||||
✔ Loaded image
|
||||
✔ Parsed image
|
||||
✔ Cataloged packages [213 packages]
|
||||
✔ Scanned image [167 vulnerabilities]
|
||||
NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY
|
||||
bash 4.4.18-2ubuntu1.2 deb CVE-2022-3715 Medium
|
||||
bash 4.4.18-2ubuntu1.2 4.4.18-2ubuntu1.3 deb CVE-2019-18276 Low
|
||||
coreutils 8.28-1ubuntu1 deb CVE-2016-2781 Low
|
||||
dpkg 1.19.0.5ubuntu2.3 1.19.0.5ubuntu2.4 deb CVE-2022-1664 Medium
|
||||
e2fsprogs 1.44.1-1ubuntu1.3 1.44.1-1ubuntu1.4 deb CVE-2022-1304 Medium
|
||||
gcc-8-base 8.4.0-1ubuntu1~18.04 deb CVE-2020-13844 Medium
|
||||
gpgv 2.2.4-1ubuntu1.4 2.2.4-1ubuntu1.6 deb CVE-2022-34903 Medium
|
||||
gpgv 2.2.4-1ubuntu1.4 2.2.4-1ubuntu1.5 deb CVE-2019-13050 Low
|
||||
gpgv 2.2.4-1ubuntu1.4 deb CVE-2022-3219 Low
|
||||
gzip 1.6-5ubuntu1 1.6-5ubuntu1.2 deb CVE-2022-1271 Medium
|
||||
h2 1.4.200 2.0.202 java-archive GHSA-7rpj-hg47-cx62 High
|
||||
h2 1.4.200 2.0.206 java-archive GHSA-h376-j262-vhq6 Critical
|
||||
h2 1.4.200 java-archive CVE-2021-23463 Critical
|
||||
h2 1.4.200 java-archive CVE-2021-42392 Critical
|
||||
h2 1.4.200 java-archive CVE-2022-23221 Critical
|
||||
h2 1.4.200 2.1.210 java-archive GHSA-45hx-wfhj-473x Critical
|
||||
jackson-databind 2.11.4 2.12.7.1 java-archive GHSA-jjjh-jjxp-wpff High
|
||||
jackson-databind 2.11.4 2.12.7.1 java-archive GHSA-rgv9-q543-rqg4 High
|
||||
jackson-databind 2.11.4 java-archive CVE-2022-42004 High
|
||||
jackson-databind 2.11.4 java-archive CVE-2020-36518 High
|
||||
jackson-databind 2.11.4 java-archive CVE-2022-42003 High
|
||||
jackson-databind 2.11.4 2.12.6.1 java-archive GHSA-57j2-w4cx-62h2 High
|
||||
jquery 2.2.4 java-archive CVE-2019-11358 Medium
|
||||
jquery 2.2.4 java-archive CVE-2020-11022 Medium
|
||||
jquery 2.2.4 java-archive CVE-2015-9251 Medium
|
||||
jquery 2.2.4 java-archive CVE-2020-11023 Medium
|
||||
jquery 2.2.4 java-archive CVE-2007-2379 Medium
|
||||
jquery-ui 1.11.4 java-archive CVE-2021-41184 Medium
|
||||
jquery-ui 1.11.4 java-archive CVE-2016-7103 Medium
|
||||
jquery-ui 1.11.4 java-archive CVE-2021-41182 Medium
|
||||
jquery-ui 1.11.4 java-archive CVE-2021-41183 Medium
|
||||
libc-bin 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2020-29562 Low
|
||||
libc-bin 2.27-3ubuntu1.4 deb CVE-2016-20013 Negligible
|
||||
libc-bin 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2020-6096 Low
|
||||
libc-bin 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2020-27618 Low
|
||||
libc-bin 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2022-23218 Low
|
||||
libc-bin 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2016-10228 Negligible
|
||||
libc-bin 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2019-25013 Low
|
||||
libc-bin 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2021-3326 Low
|
||||
libc-bin 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2021-3999 Medium
|
||||
libc-bin 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2022-23219 Low
|
||||
libc-bin 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2021-35942 Low
|
||||
libc-bin 2.27-3ubuntu1.4 deb CVE-2009-5155 Negligible
|
||||
libc-bin 2.27-3ubuntu1.4 deb CVE-2015-8985 Negligible
|
||||
libc6 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2021-3999 Medium
|
||||
libc6 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2016-10228 Negligible
|
||||
libc6 2.27-3ubuntu1.4 deb CVE-2009-5155 Negligible
|
||||
libc6 2.27-3ubuntu1.4 deb CVE-2016-20013 Negligible
|
||||
libc6 2.27-3ubuntu1.4 deb CVE-2015-8985 Negligible
|
||||
libc6 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2021-3326 Low
|
||||
libc6 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2021-35942 Low
|
||||
libc6 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2020-27618 Low
|
||||
libc6 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2020-6096 Low
|
||||
libc6 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2020-29562 Low
|
||||
libc6 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2022-23218 Low
|
||||
libc6 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2022-23219 Low
|
||||
libc6 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2019-25013 Low
|
||||
libcom-err2 1.44.1-1ubuntu1.3 1.44.1-1ubuntu1.4 deb CVE-2022-1304 Medium
|
||||
libext2fs2 1.44.1-1ubuntu1.3 1.44.1-1ubuntu1.4 deb CVE-2022-1304 Medium
|
||||
libgcc1 1:8.4.0-1ubuntu1~18.04 deb CVE-2020-13844 Medium
|
||||
libgcrypt20 1.8.1-4ubuntu1.2 1.8.1-4ubuntu1.3 deb CVE-2021-40528 Medium
|
||||
libgcrypt20 1.8.1-4ubuntu1.2 1.8.1-4ubuntu1.3 deb CVE-2021-33560 Low
|
||||
libgmp10 2:6.1.2+dfsg-2 2:6.1.2+dfsg-2ubuntu0.1 deb CVE-2021-43618 Low
|
||||
libgnutls30 3.5.18-1ubuntu1.4 3.5.18-1ubuntu1.6 deb CVE-2021-4209 Low
|
||||
libgnutls30 3.5.18-1ubuntu1.4 deb CVE-2018-16868 Low
|
||||
libgnutls30 3.5.18-1ubuntu1.4 3.5.18-1ubuntu1.6 deb CVE-2022-2509 Medium
|
||||
libhogweed4 3.4-1ubuntu0.1 3.4.1-0ubuntu0.18.04.1 deb CVE-2021-3580 Medium
|
||||
libhogweed4 3.4-1ubuntu0.1 3.4.1-0ubuntu0.18.04.1 deb CVE-2018-16869 Low
|
||||
liblz4-1 0.0~r131-2ubuntu3 0.0~r131-2ubuntu3.1 deb CVE-2021-3520 Medium
|
||||
liblzma5 5.2.2-1.3 5.2.2-1.3ubuntu0.1 deb CVE-2022-1271 Medium
|
||||
libncurses5 6.1-1ubuntu1.18.04 deb CVE-2019-17594 Negligible
|
||||
libncurses5 6.1-1ubuntu1.18.04 deb CVE-2021-39537 Negligible
|
||||
libncurses5 6.1-1ubuntu1.18.04 deb CVE-2022-29458 Negligible
|
||||
libncurses5 6.1-1ubuntu1.18.04 deb CVE-2019-17595 Negligible
|
||||
libncursesw5 6.1-1ubuntu1.18.04 deb CVE-2019-17595 Negligible
|
||||
libncursesw5 6.1-1ubuntu1.18.04 deb CVE-2021-39537 Negligible
|
||||
libncursesw5 6.1-1ubuntu1.18.04 deb CVE-2022-29458 Negligible
|
||||
libncursesw5 6.1-1ubuntu1.18.04 deb CVE-2019-17594 Negligible
|
||||
libnettle6 3.4-1ubuntu0.1 3.4.1-0ubuntu0.18.04.1 deb CVE-2021-3580 Medium
|
||||
libnettle6 3.4-1ubuntu0.1 3.4.1-0ubuntu0.18.04.1 deb CVE-2018-16869 Low
|
||||
libpcre3 2:8.39-9 deb CVE-2017-11164 Negligible
|
||||
libpcre3 2:8.39-9 2:8.39-9ubuntu0.1 deb CVE-2020-14155 Negligible
|
||||
libpcre3 2:8.39-9 2:8.39-9ubuntu0.1 deb CVE-2019-20838 Low
|
||||
libsepol1 2.7-1 2.7-1ubuntu0.1 deb CVE-2021-36086 Low
|
||||
libsepol1 2.7-1 2.7-1ubuntu0.1 deb CVE-2021-36085 Low
|
||||
libsepol1 2.7-1 2.7-1ubuntu0.1 deb CVE-2021-36087 Low
|
||||
libsepol1 2.7-1 2.7-1ubuntu0.1 deb CVE-2021-36084 Low
|
||||
libss2 1.44.1-1ubuntu1.3 1.44.1-1ubuntu1.4 deb CVE-2022-1304 Medium
|
||||
libssl1.1 1.1.1-1ubuntu2.1~18.04.9 1.1.1-1ubuntu2.1~18.04.15 deb CVE-2022-0778 High
|
||||
libssl1.1 1.1.1-1ubuntu2.1~18.04.9 1.1.1-1ubuntu2.1~18.04.20 deb CVE-2022-2097 Medium
|
||||
libssl1.1 1.1.1-1ubuntu2.1~18.04.9 1.1.1-1ubuntu2.1~18.04.13 deb CVE-2021-3712 Medium
|
||||
libssl1.1 1.1.1-1ubuntu2.1~18.04.9 1.1.1-1ubuntu2.1~18.04.13 deb CVE-2021-3711 High
|
||||
libssl1.1 1.1.1-1ubuntu2.1~18.04.9 1.1.1-1ubuntu2.1~18.04.17 deb CVE-2022-1292 Medium
|
||||
libssl1.1 1.1.1-1ubuntu2.1~18.04.9 1.1.1-1ubuntu2.1~18.04.19 deb CVE-2022-2068 Medium
|
||||
libstdc++6 8.4.0-1ubuntu1~18.04 deb CVE-2020-13844 Medium
|
||||
libsystemd0 237-3ubuntu10.47 237-3ubuntu10.56 deb CVE-2022-2526 Medium
|
||||
libsystemd0 237-3ubuntu10.47 deb CVE-2022-3821 Medium
|
||||
libsystemd0 237-3ubuntu10.47 237-3ubuntu10.49 deb CVE-2020-13529 Low
|
||||
libsystemd0 237-3ubuntu10.47 237-3ubuntu10.49 deb CVE-2021-33910 High
|
||||
libtinfo5 6.1-1ubuntu1.18.04 deb CVE-2019-17595 Negligible
|
||||
libtinfo5 6.1-1ubuntu1.18.04 deb CVE-2021-39537 Negligible
|
||||
libtinfo5 6.1-1ubuntu1.18.04 deb CVE-2019-17594 Negligible
|
||||
libtinfo5 6.1-1ubuntu1.18.04 deb CVE-2022-29458 Negligible
|
||||
libudev1 237-3ubuntu10.47 237-3ubuntu10.49 deb CVE-2020-13529 Low
|
||||
libudev1 237-3ubuntu10.47 237-3ubuntu10.49 deb CVE-2021-33910 High
|
||||
libudev1 237-3ubuntu10.47 deb CVE-2022-3821 Medium
|
||||
libudev1 237-3ubuntu10.47 237-3ubuntu10.56 deb CVE-2022-2526 Medium
|
||||
locales 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2022-23219 Low
|
||||
locales 2.27-3ubuntu1.4 deb CVE-2016-20013 Negligible
|
||||
locales 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2021-3999 Medium
|
||||
locales 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2016-10228 Negligible
|
||||
locales 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2019-25013 Low
|
||||
locales 2.27-3ubuntu1.4 deb CVE-2009-5155 Negligible
|
||||
locales 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2021-35942 Low
|
||||
locales 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2022-23218 Low
|
||||
locales 2.27-3ubuntu1.4 deb CVE-2015-8985 Negligible
|
||||
locales 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2020-27618 Low
|
||||
locales 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2020-29562 Low
|
||||
locales 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2021-3326 Low
|
||||
locales 2.27-3ubuntu1.4 2.27-3ubuntu1.5 deb CVE-2020-6096 Low
|
||||
log4j-api 2.13.3 java-archive CVE-2021-45105 Medium
|
||||
log4j-api 2.13.3 java-archive CVE-2021-44832 Medium
|
||||
log4j-to-slf4j 2.13.3 java-archive CVE-2021-44832 Medium
|
||||
log4j-to-slf4j 2.13.3 java-archive CVE-2021-45105 Medium
|
||||
logback-core 1.2.3 1.2.9 java-archive GHSA-668q-qrv7-99fm Medium
|
||||
login 1:4.5-1ubuntu2 deb CVE-2013-4235 Low
|
||||
login 1:4.5-1ubuntu2 1:4.5-1ubuntu2.2 deb CVE-2018-7169 Low
|
||||
ncurses-base 6.1-1ubuntu1.18.04 deb CVE-2022-29458 Negligible
|
||||
ncurses-base 6.1-1ubuntu1.18.04 deb CVE-2019-17595 Negligible
|
||||
ncurses-base 6.1-1ubuntu1.18.04 deb CVE-2019-17594 Negligible
|
||||
ncurses-base 6.1-1ubuntu1.18.04 deb CVE-2021-39537 Negligible
|
||||
ncurses-bin 6.1-1ubuntu1.18.04 deb CVE-2021-39537 Negligible
|
||||
ncurses-bin 6.1-1ubuntu1.18.04 deb CVE-2022-29458 Negligible
|
||||
ncurses-bin 6.1-1ubuntu1.18.04 deb CVE-2019-17595 Negligible
|
||||
ncurses-bin 6.1-1ubuntu1.18.04 deb CVE-2019-17594 Negligible
|
||||
openssl 1.1.1-1ubuntu2.1~18.04.9 1.1.1-1ubuntu2.1~18.04.13 deb CVE-2021-3712 Medium
|
||||
openssl 1.1.1-1ubuntu2.1~18.04.9 1.1.1-1ubuntu2.1~18.04.19 deb CVE-2022-2068 Medium
|
||||
openssl 1.1.1-1ubuntu2.1~18.04.9 1.1.1-1ubuntu2.1~18.04.20 deb CVE-2022-2097 Medium
|
||||
openssl 1.1.1-1ubuntu2.1~18.04.9 1.1.1-1ubuntu2.1~18.04.13 deb CVE-2021-3711 High
|
||||
openssl 1.1.1-1ubuntu2.1~18.04.9 1.1.1-1ubuntu2.1~18.04.15 deb CVE-2022-0778 High
|
||||
openssl 1.1.1-1ubuntu2.1~18.04.9 1.1.1-1ubuntu2.1~18.04.17 deb CVE-2022-1292 Medium
|
||||
passwd 1:4.5-1ubuntu2 1:4.5-1ubuntu2.2 deb CVE-2018-7169 Low
|
||||
passwd 1:4.5-1ubuntu2 deb CVE-2013-4235 Low
|
||||
perl-base 5.26.1-6ubuntu0.5 5.26.1-6ubuntu0.6 deb CVE-2020-16156 Medium
|
||||
snakeyaml 1.27 java-archive GHSA-w37g-rhq8-7m4j Medium
|
||||
snakeyaml 1.27 1.32 java-archive GHSA-9w3m-gqgf-c4p9 Medium
|
||||
snakeyaml 1.27 1.31 java-archive GHSA-3mc7-4q67-w48m High
|
||||
snakeyaml 1.27 1.31 java-archive GHSA-c4r9-r8fh-9vj2 Medium
|
||||
snakeyaml 1.27 1.31 java-archive GHSA-hhhw-99gj-p3c3 Medium
|
||||
snakeyaml 1.27 1.31 java-archive GHSA-98wm-3w3q-mw94 Medium
|
||||
spring-core 5.3.6 java-archive CVE-2022-22950 Medium
|
||||
spring-core 5.3.6 java-archive CVE-2022-22965 Critical
|
||||
spring-core 5.3.6 java-archive CVE-2021-22096 Medium
|
||||
spring-core 5.3.6 java-archive CVE-2022-22968 Medium
|
||||
spring-core 5.3.6 java-archive CVE-2022-22970 Medium
|
||||
spring-core 5.3.6 java-archive CVE-2022-22971 Medium
|
||||
spring-core 5.3.6 java-archive CVE-2021-22118 High
|
||||
spring-core 5.3.6 java-archive CVE-2016-1000027 Critical
|
||||
spring-core 5.3.6 java-archive CVE-2021-22060 Medium
|
||||
tar 1.29b-2ubuntu0.2 1.29b-2ubuntu0.3 deb CVE-2021-20193 Low
|
||||
zlib1g 1:1.2.11.dfsg-0ubuntu2 1:1.2.11.dfsg-0ubuntu2.2 deb CVE-2022-37434 Medium
|
||||
zlib1g 1:1.2.11.dfsg-0ubuntu2 1:1.2.11.dfsg-0ubuntu2.1 deb CVE-2018-25032 Medium
|
||||
zlib1g 1:1.2.11.dfsg-0ubuntu2 deb CVE-2022-42800 Medium
|
||||
```
|
||||
|
||||
여기서 우리는 훨씬 더 많은 `중요한` 취약점을 볼 수 있을 뿐만 아니라 많은 취약점이 해당 종속성의 최신 버전에서 수정되었음을 알 수 있습니다.
|
||||
즉, 해당 종속성의 간단한 버전 업데이트만으로도 취약점을 제거하고 이미지를 더 안전하게 만들 수 있습니다.
|
||||
|
||||
물론 항상 그렇게 간단한 것은 아닙니다.
|
||||
때로는 종속성의 새 버전에 소스 코드를 변경해야 하는 API 변경 사항이 포함되거나, 종속성과 상호 작용하는 방식에 버그를 유발하는 동작 변경이 포함되거나, 수정될 때까지 피하고 싶은 버그가 발생할 수 있습니다.
|
||||
|
||||
또 한 가지 언급할 만한 점은 이러한 유형의 스캔은 _알려진_ 취약점만 탐지한다는 것입니다.
|
||||
즉, 보안 연구원이 발견하고 CVE를 지정한 취약점만 탐지합니다.
|
||||
아직 알려지지 않은 취약점이 코드/종속성에 숨어 있을 수 있습니다. (Log4Shell은 2013년부터 사용되었지만 2021년에야 발견됨)
|
||||
|
||||
요약하자면, 이미지 스캔은 만병통치약이 아닙니다.
|
||||
이미지 스캐너가 이미지에 취약점이 0개라고 알려준다고 해서 100% 안전하다는 의미는 아닙니다.
|
||||
|
||||
또한 취약점을 완화하는 것은 종속성 버전을 변경하거나 다운그레이드하는 것만큼 간단할 수도 있지만, 때로는 버전 변경을 위해 코드를 변경해야 할 수도 있기 때문에 더 까다로울 수 있습니다.
|
||||
|
||||
## CVEs
|
||||
|
||||
스캐너가 제공하는 취약점 표에서 'CVE-'로 시작하는 것을 볼 수 있습니다:
|
||||
|
||||
```text
|
||||
bash 4.4.18-2ubuntu1.2 deb CVE-2022-3715 Medium
|
||||
```
|
||||
|
||||
[CVE**](https://cve.mitre.org/)는 **C**ommon **V**ulnerability and **E**xposures.의 약자입니다.
|
||||
|
||||
취약점을 추적하고 쉽게 검색할 수 있도록 하는 시스템입니다.
|
||||
|
||||
새로운 취약점이 발견될 때마다 [CNA](https://www.cve.org/ProgramOrganization/CNAs)(CVE 번호 부여 기관)에서 CVE를 할당하고 해당 취약점이 포함된 모든 구성 요소와 연관시킵니다.
|
||||
|
||||
이 작업이 완료되면 이 정보는 취약점 데이터베이스로 전파되며 이미지 스캐너를 통해 컨테이너에 존재하는 CVE/취약점에 대해 경고하는 데 활용될 수 있습니다.
|
||||
|
||||
## 요약
|
||||
|
||||
이제 이미지 스캔이 중요한 이유와 보안을 강화하는 데 어떻게 도움이 되는지 알게 되었습니다.
|
||||
[15일차](day15.md)에서는 이미지 스캐너가 내부에서 작동하는 방식에 대해 자세히 살펴보고 SBOM과 취약성 데이터베이스 등을 살펴보겠습니다.
|
235
2023/ko/days/day15.md
Normal file
235
2023/ko/days/day15.md
Normal file
@ -0,0 +1,235 @@
|
||||
# 컨테이너 이미지 스캐닝 고급
|
||||
|
||||
## SBOM
|
||||
|
||||
**SBOM**은 **S**oftware **B**ill **O**f **M**aterials의 약자입니다.
|
||||
|
||||
이것은 소프트웨어 애플리케이션 또는 시스템을 구성하는 모든 구성 요소의 목록입니다.
|
||||
여기에는 소프트웨어를 구축하는 데 사용되는 다양한 타사 라이브러리, 프레임워크 및 기타 오픈 소스 또는 독점 구성 요소에 대한 정보가 포함됩니다.
|
||||
또한 SBOM에는 이러한 구성 요소의 버전, 라이선스 정보, 알려진 취약점 또는 보안 문제에 대한 세부 정보도 포함될 수 있습니다.
|
||||
|
||||
SBOM의 목적은 이러한 구성 요소를 나열하여 소프트웨어 사용자에게 소프트웨어 제품에 포함된 구성 요소에 대한 가시성을 제공하고 보안 또는 법적 이유로 유해할 수 있는 구성 요소를 피할 수 있도록 하는 것입니다.
|
||||
|
||||
[올해](https://www.immuniweb.com/blog/5-biggest-supply-chain-attacks-in-2022-so-far.html) 와 [작년](https://cyolo.io/blog/top-5-supply-chain-attacks-of-2021/) 지난 몇 년간 대규모 공급망 공격이 발생한 후 SBOM의 사용이 더욱 보편화되었습니다.
|
||||
|
||||
|
||||
컨테이너 이미지의 컨텍스트에서, 컨테이너 이미지에 대한 SBOM에는 다음이 포함됩니다:
|
||||
|
||||
- 컨테이너에 설치된 리눅스 패키지 및 라이브러리
|
||||
- 컨테이너에서 실행 중인 애플리케이션을 위해 설치된 언어별 패키지(예: Python 패키지, Go 패키지 등)
|
||||
|
||||
컨테이너 이미지에서 SBOM을 추출하는 데 도움이 되는 도구가 있습니다.
|
||||
|
||||
그러한 도구 중 하나는 [syft](https://github.com/anchore/syft)입니다.
|
||||
|
||||
예를 들어, syft를 사용하여 `ubuntu:latest` 컨테이너 이미지에 대한 SBOM을 생성할 수 있습니다:
|
||||
|
||||
```console
|
||||
$ syft ubuntu
|
||||
✔ Parsed image
|
||||
✔ Cataloged packages [101 packages]
|
||||
NAME VERSION TYPE
|
||||
adduser 3.118ubuntu5 deb
|
||||
apt 2.4.8 deb
|
||||
base-files 12ubuntu4.2 deb
|
||||
base-passwd 3.5.52build1 deb
|
||||
bash 5.1-6ubuntu1 deb
|
||||
bsdutils 1:2.37.2-4ubuntu3 deb
|
||||
coreutils 8.32-4.1ubuntu1 deb
|
||||
dash 0.5.11+git20210903+057cd650a4ed-3build1 deb
|
||||
debconf 1.5.79ubuntu1 deb
|
||||
debianutils 5.5-1ubuntu2 deb
|
||||
diffutils 1:3.8-0ubuntu2 deb
|
||||
dpkg 1.21.1ubuntu2.1 deb
|
||||
e2fsprogs 1.46.5-2ubuntu1.1 deb
|
||||
findutils 4.8.0-1ubuntu3 deb
|
||||
gcc-12-base 12.1.0-2ubuntu1~22.04 deb
|
||||
gpgv 2.2.27-3ubuntu2.1 deb
|
||||
grep 3.7-1build1 deb
|
||||
gzip 1.10-4ubuntu4.1 deb
|
||||
hostname 3.23ubuntu2 deb
|
||||
init-system-helpers 1.62 deb
|
||||
libacl1 2.3.1-1 deb
|
||||
libapt-pkg6.0 2.4.8 deb
|
||||
libattr1 1:2.5.1-1build1 deb
|
||||
libaudit-common 1:3.0.7-1build1 deb
|
||||
libaudit1 1:3.0.7-1build1 deb
|
||||
libblkid1 2.37.2-4ubuntu3 deb
|
||||
libbz2-1.0 1.0.8-5build1 deb
|
||||
libc-bin 2.35-0ubuntu3.1 deb
|
||||
libc6 2.35-0ubuntu3.1 deb
|
||||
libcap-ng0 0.7.9-2.2build3 deb
|
||||
libcap2 1:2.44-1build3 deb
|
||||
libcom-err2 1.46.5-2ubuntu1.1 deb
|
||||
libcrypt1 1:4.4.27-1 deb
|
||||
libdb5.3 5.3.28+dfsg1-0.8ubuntu3 deb
|
||||
libdebconfclient0 0.261ubuntu1 deb
|
||||
libext2fs2 1.46.5-2ubuntu1.1 deb
|
||||
libffi8 3.4.2-4 deb
|
||||
libgcc-s1 12.1.0-2ubuntu1~22.04 deb
|
||||
libgcrypt20 1.9.4-3ubuntu3 deb
|
||||
libgmp10 2:6.2.1+dfsg-3ubuntu1 deb
|
||||
libgnutls30 3.7.3-4ubuntu1.1 deb
|
||||
libgpg-error0 1.43-3 deb
|
||||
libgssapi-krb5-2 1.19.2-2 deb
|
||||
libhogweed6 3.7.3-1build2 deb
|
||||
libidn2-0 2.3.2-2build1 deb
|
||||
libk5crypto3 1.19.2-2 deb
|
||||
libkeyutils1 1.6.1-2ubuntu3 deb
|
||||
libkrb5-3 1.19.2-2 deb
|
||||
libkrb5support0 1.19.2-2 deb
|
||||
liblz4-1 1.9.3-2build2 deb
|
||||
liblzma5 5.2.5-2ubuntu1 deb
|
||||
libmount1 2.37.2-4ubuntu3 deb
|
||||
libncurses6 6.3-2 deb
|
||||
libncursesw6 6.3-2 deb
|
||||
libnettle8 3.7.3-1build2 deb
|
||||
libnsl2 1.3.0-2build2 deb
|
||||
libp11-kit0 0.24.0-6build1 deb
|
||||
libpam-modules 1.4.0-11ubuntu2 deb
|
||||
libpam-modules-bin 1.4.0-11ubuntu2 deb
|
||||
libpam-runtime 1.4.0-11ubuntu2 deb
|
||||
libpam0g 1.4.0-11ubuntu2 deb
|
||||
libpcre2-8-0 10.39-3ubuntu0.1 deb
|
||||
libpcre3 2:8.39-13ubuntu0.22.04.1 deb
|
||||
libprocps8 2:3.3.17-6ubuntu2 deb
|
||||
libseccomp2 2.5.3-2ubuntu2 deb
|
||||
libselinux1 3.3-1build2 deb
|
||||
libsemanage-common 3.3-1build2 deb
|
||||
libsemanage2 3.3-1build2 deb
|
||||
libsepol2 3.3-1build1 deb
|
||||
libsmartcols1 2.37.2-4ubuntu3 deb
|
||||
libss2 1.46.5-2ubuntu1.1 deb
|
||||
libssl3 3.0.2-0ubuntu1.7 deb
|
||||
libstdc++6 12.1.0-2ubuntu1~22.04 deb
|
||||
libsystemd0 249.11-0ubuntu3.6 deb
|
||||
libtasn1-6 4.18.0-4build1 deb
|
||||
libtinfo6 6.3-2 deb
|
||||
libtirpc-common 1.3.2-2ubuntu0.1 deb
|
||||
libtirpc3 1.3.2-2ubuntu0.1 deb
|
||||
libudev1 249.11-0ubuntu3.6 deb
|
||||
libunistring2 1.0-1 deb
|
||||
libuuid1 2.37.2-4ubuntu3 deb
|
||||
libxxhash0 0.8.1-1 deb
|
||||
libzstd1 1.4.8+dfsg-3build1 deb
|
||||
login 1:4.8.1-2ubuntu2 deb
|
||||
logsave 1.46.5-2ubuntu1.1 deb
|
||||
lsb-base 11.1.0ubuntu4 deb
|
||||
mawk 1.3.4.20200120-3 deb
|
||||
mount 2.37.2-4ubuntu3 deb
|
||||
ncurses-base 6.3-2 deb
|
||||
ncurses-bin 6.3-2 deb
|
||||
passwd 1:4.8.1-2ubuntu2 deb
|
||||
perl-base 5.34.0-3ubuntu1.1 deb
|
||||
procps 2:3.3.17-6ubuntu2 deb
|
||||
sed 4.8-1ubuntu2 deb
|
||||
sensible-utils 0.0.17 deb
|
||||
sysvinit-utils 3.01-1ubuntu1 deb
|
||||
tar 1.34+dfsg-1build3 deb
|
||||
ubuntu-keyring 2021.03.26 deb
|
||||
usrmerge 25ubuntu2 deb
|
||||
util-linux 2.37.2-4ubuntu3 deb
|
||||
zlib1g 1:1.2.11.dfsg-2ubuntu9.2 deb
|
||||
```
|
||||
|
||||
SBOM에는 컨테이너 이미지 내부에 설치된 패키지와 라이브러리가 포함되어 있을 뿐만 아니라,
|
||||
유형과 버전도 나열되어 있습니다.
|
||||
이제 이 목록을 취약점 데이터베이스와 상호 참조하여 컨테이너 내부에 취약점이 있는지 확인할 수 있습니다.
|
||||
|
||||
그렇다면 **취약점 데이터베이스(Vulnerability Database)**란 무엇인가요?
|
||||
|
||||
## 취약점 데이터베이스
|
||||
|
||||
취약점 데이터베이스는 소프트웨어, 하드웨어 및 기타 시스템의 알려진 취약점에 대한 정보 모음입니다.
|
||||
일반적으로 취약점의 유형, 취약점의 심각도, 취약점의 잠재적 영향과 같은 취약점의 특성에 대한 세부 정보가 포함됩니다.
|
||||
취약점 데이터베이스에는 취약점이 악용될 수 있는 방법과 해당 취약점에 대해 사용 가능한 패치 또는 수정 사항에 대한 정보도 포함될 수 있습니다.
|
||||
|
||||
일부 취약점 데이터베이스는 [vuldb.com](https://vuldb.com/), [NIST](https://nvd.nist.gov/vuln), [cvedetails.com](https://www.cvedetails.com/) 및 [Snyk 취약점 데이터베이스](https://security.snyk.io/) 등이 있습니다.
|
||||
|
||||
이들 기관은 사용자가 다운로드할 수 있는 API 또는 원시 데이터를 제공하며, SBOM의 패키지와 취약점 정보를 상호 참조할 수 있습니다.
|
||||
이렇게 하면 패키지에 주의해야 할 취약점이 있는지 확인할 수 있습니다.
|
||||
|
||||
일반적으로 이 취약점이 도입된 라이브러리 버전과 최신 버전에서 취약점이 수정되었는지 여부에 대한 정보도 찾을 수 있습니다.
|
||||
이 정보를 사용하여 취약점을 완화하기 위해 종속성을 업데이트/다운그레이드할지 여부를 결정할 수 있습니다.
|
||||
14일차](./day14.md)에서 이미 설명했듯이, 종속성 업데이트에는 동작 또는 API 변경이 수반되는 경우가 있기 때문에 종속성을 업데이트하는 것이 항상 간단한 것은 아닙니다.
|
||||
|
||||
취약점에 대한 또 다른 중요한 정보는 취약점의 **CVSS 점수**입니다.
|
||||
|
||||
## CVSS
|
||||
|
||||
## CVSS
|
||||
|
||||
**CVSS**는 **C**ommon **V**ulnerability **S**coring **S**ystem의 약자입니다.
|
||||
|
||||
이 시스템은 취약점의 주요 특성을 파악하고 그 심각성을 반영하는 수치 점수를 생성하는 방법을 제공합니다.
|
||||
그런 다음 이 수치 점수를 정성적 표현(낮음, 중간, 높음, 심각 등)으로 변환하여 조직이 취약점 관리 프로세스를 적절히 평가하고 우선순위를 정할 수 있도록 도와줍니다.
|
||||
|
||||
기본적으로 하나의 취약점이 다른 취약점보다 더 심각할 수 있습니다.
|
||||
익스플로잇이 얼마나 쉬운지, 얼마나 큰 피해를 입힐 수 있는지에 따라 취약점의 순위를 객관적으로 매길 수 있는 시스템이 필요합니다.
|
||||
|
||||
이것이 바로 CVSS가 필요한 이유입니다.
|
||||
|
||||
CVSS v3는 CVSS 점수를 계산하는 8가지 기준을 정의합니다.
|
||||
이러한 기준은 다음과 같습니다:
|
||||
|
||||
### 공격 벡터 Attack Vector
|
||||
|
||||
취약점 악용이 가능한 컨텍스트를 반영합니다.
|
||||
|
||||
가능한 값 : **Network(N)**, **Adjacent(A)**, **Local(L)**, **Physical(P)**
|
||||
|
||||
### 공격 복잡성 Attack Complexity
|
||||
|
||||
취약점을 익스플로잇하기 위해 공격자가 통제할 수 없는 조건에 대해 설명합니다.
|
||||
|
||||
가능한 값 : **Low(L)**, **High(H)**
|
||||
|
||||
### 필요한 권한 Priviledges Required
|
||||
|
||||
공격자가 취약점을 성공적으로 익스플로잇하기 전에 보유해야 하는 권한 수준을 설명합니다.
|
||||
|
||||
가능한 값 : **None(N)**, **Low(L)**, **High(H)**
|
||||
|
||||
### 사용자 상호작용 User Interaction
|
||||
|
||||
공격자 이외의 사용자가 취약한 구성 요소의 성공적인 침해에 참여하기 위한 요구 사항입니다.
|
||||
|
||||
가능한 값 : **None(N)**, **Required(R)**
|
||||
|
||||
#### 범위 Scope
|
||||
|
||||
한 소프트웨어 구성 요소의 취약점이 리소스 또는 권한에 영향을 미칠 수 있는 능력입니다.
|
||||
|
||||
가능한 값 : **Unchanged(U)**, **Changed(C)**
|
||||
|
||||
### 기밀성 Confidentiality
|
||||
|
||||
성공적으로 익스플로잇된 취약점으로 인해 소프트웨어 구성 요소가 관리하는 정보 리소스의 기밀성에 미치는 영향입니다.
|
||||
|
||||
가능한 값 : **None(N)**, **Low(L)**, **High(H)**
|
||||
|
||||
### 무결성 Integrity
|
||||
|
||||
성공적으로 익스플로잇된 취약점이 무결성에 미치는 영향입니다.
|
||||
|
||||
가능한 값 : **None(N)**, **Low(L)**, **High(H)**
|
||||
|
||||
### 가용성 Availability
|
||||
|
||||
성공적으로 익스플로잇된 취약점으로 인해 영향을 받은 구성 요소의 가용성에 미치는 영향입니다.
|
||||
|
||||
가능한 값 : **None(N)**, **Low(L)**, **High(H)**
|
||||
|
||||
이 8가지 벡터의 조합에 따라 CVSS 점수가 결정됩니다.
|
||||
0에서 10 사이입니다.
|
||||
0이 가장 낮고 10이 가장 높습니다.(가장 위험)
|
||||
[이 곳](https://www.first.org/cvss/calculator/3.0)에서 각 취약점의 점수를 계산할 수 있는 CVSS 계산기를 찾을 수 있습니다.
|
||||
|
||||
## 리소스
|
||||
|
||||
<https://www.nist.gov/itl/executive-order-improving-nations-cybersecurity>
|
||||
|
||||
<https://www.aquasec.com/cloud-native-academy/supply-chain-security/sbom/>
|
||||
|
||||
|
||||
[16일차](day16.md)에서는 "Fuzzing" 또는 Fuzz Test에 대해 살펴보겠습니다.
|
94
2023/ko/days/day16.md
Normal file
94
2023/ko/days/day16.md
Normal file
@ -0,0 +1,94 @@
|
||||
# 퍼징 Fuzzing
|
||||
|
||||
'퍼즈 테스트'라고도 하는 퍼징은 컴퓨터 프로그램에 유효하지 않거나 예상치 못한 임의의 데이터를 입력으로 제공하는 소프트웨어 테스트 기법입니다.
|
||||
퍼징의 목표는 프로그램이 충돌하거나 의도하지 않은 동작을 나타내어 프로그램의 보안 취약점 및 기타 버그를 식별하는 것입니다.
|
||||
|
||||
퍼징은 수동으로 수행하거나 테스트 라이브러리/프레임워크를 사용하여 입력을 만들어서 수행할 수 있습니다.
|
||||
|
||||
퍼징을 더 잘 이해하기 위해 다음 코드를 예로 들어보겠습니다:
|
||||
|
||||
```go
|
||||
func DontPanic(s string) {
|
||||
if len(s) == 4 {
|
||||
if s[0] == 'f' {
|
||||
if s[1] == 'u' {
|
||||
if s[2] == 'z' {
|
||||
if s[3] == 'z' {
|
||||
panic("error: wrong input")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
이것은 '문자열'을 유일한 인수로 받아들이는 Go 함수입니다.
|
||||
|
||||
함수를 살펴보면, 제공된 입력이 '퍼즈'라는 단어인 경우 한 가지 조건에서만 함수가 'panic'(예: crash)을 일으키는 것처럼 보입니다.
|
||||
|
||||
물론 이 함수는 매우 간단하며 보기만 해도 그 동작을 알 수 있습니다.
|
||||
그러나 더 복잡한 시스템에서는 이러한 실패 지점이 명확하지 않을 수 있으며, 이를 테스트하거나 단위 테스트 케이스를 작성하는 사람이 놓칠 수 있습니다.
|
||||
|
||||
이때 퍼징이 유용합니다.
|
||||
|
||||
Go 퍼징 라이브러리(Go 1.18부터 표준 언어 라이브러리의 일부)는 테스트 케이스에 대한 많은 입력을 생성한 다음 커버리지와 결과에 따라 어떤 입력이 "흥미로운지"를 결정합니다.이 함수에 대한 퍼즈 테스트를 작성하면 다음과 같은 일이 발생합니다:
|
||||
|
||||
1. 퍼징 라이브러리가 작은 문자열부터 시작하여 크기가 커지는 무작위 문자열을 제공하기 시작합니다.
|
||||
2. 라이브러리가 길이 4의 문자열을 제공하면 테스트 범위의 변경을 감지하고(`if (len(s) == 4)`가 이제 `true`가 됨) 이 길이의 입력을 계속 생성합니다.
|
||||
3. 라이브러리가 `f`로 시작하는 길이 4의 문자열을 제공하면 테스트 커버리지의 또 다른 변경 사항(`if s[0] == "f"`는 이제 `true`)을 감지하고 `f`로 시작하는 입력을 계속 생성합니다.
|
||||
4. `u`와 이중 `z`에 대해서도 같은 일이 반복됩니다.
|
||||
5. `fuzz`를 입력으로 제공하면 함수가 패닉 상태에 빠지고 테스트가 실패합니다.
|
||||
6. __퍼즈__에 성공했습니다!
|
||||
|
||||
퍼징의 또 다른 좋은 방법은 코드 충돌을 일으킨 입력을 저장하고 매번 실행하여 퍼징을 통해 발견한 원래 오류가 다시는 코드에 도입되지 않도록 하는 것입니다.
|
||||
|
||||
이 역시 퍼징 프레임워크의 특징일 수 있습니다.
|
||||
|
||||
대부분의 퍼징 라이브러리에서는 테스트하려는 특정 값을 추가할 수 있습니다.
|
||||
이렇게 하면 우리가 이미 알고 있는 "흥미로운" 값을 라이브러리에 표시하여 생성된 값을 모델링할 수 있으므로 라이브러리에도 도움이 됩니다.
|
||||
|
||||
## 퍼징만으로는 충분하지 않은 경우
|
||||
|
||||
퍼징은 유용한 기술이지만 도움이 되지 않는 상황도 있습니다.
|
||||
|
||||
예를 들어, 코드에 실패하는 입력이 너무 구체적이어서 도움이 되는 단서가 없는 경우 퍼징 라이브러리가 이를 추측하지 못할 수 있습니다.
|
||||
|
||||
이전 단락의 예제 코드를 다음과 같이 변경해 보겠습니다.
|
||||
|
||||
```go
|
||||
func DontPanic(s input) {
|
||||
if (len(s) == 4) && s[0] == 'f' && s[1] == 'u' && s[2] == 'z' && s[3] == 'z' {
|
||||
panic("error")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
또는
|
||||
|
||||
```go
|
||||
func DontPanic(s input) {
|
||||
if s == "fuzz" {
|
||||
panic("error")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
이런 경우 퍼징은 아무런 단서 없이 정확한 문자열 `퍼즈`를 생성할 가능성이 적기 때문에 도움이 되지 않습니다.
|
||||
그리고 이전 사례에서 코드 커버리지 변경을 트리거했던 입력(크기 4의 문자열, `z`로 시작하는 크기 4의 문자열 등)은 이제 코드 커버리지를 트리거하지 않습니다. (이전 예제에서는 `if` 체크가 5개인데 비해 지금은 하나만 있기 때문입니다)
|
||||
|
||||
So it's important to understand that while fuzzing is a good way to detect anomalies and corner-cases in your code it is not a silver-bullet for 100% correct code.
|
||||
|
||||
## 실제 예제
|
||||
|
||||
Go에서 퍼징을 직접 해보고 싶으시다면 [해당 주제에 대한 예제가 있는 내 리포지토리](https://github.com/asankov/go-fuzzing-101/tree/v1)를 확인하세요.
|
||||
|
||||
여기에는 이 글에서 사용한 예제와 실패를 트리거하는 퍼즈 테스트, 그리고 테스트를 직접 실행하는 방법에 대한 지침이 포함되어 있습니다.
|
||||
|
||||
## 리소스
|
||||
|
||||
- <https://en.wikipedia.org/wiki/Fuzzing>
|
||||
- [Fuzzing in Go by Valentin Deleplace, Devoxx Belgium 2022](https://www.youtube.com/watch?v=Zlf3s4EjnFU)
|
||||
- [Write applications faster and securely with Go by Cody Oss, Go Day 2022](https://www.youtube.com/watch?v=aw7lFSFGKZs)
|
||||
|
||||
[17일차](day17.md)에 뵙겠습니다.
|
247
2023/ko/days/day17.md
Normal file
247
2023/ko/days/day17.md
Normal file
@ -0,0 +1,247 @@
|
||||
# 퍼징(Fuzzing) 고급
|
||||
|
||||
어제 우리는 퍼징이 무엇인지, 그리고 퍼즈 테스트(퍼지 입력을 사용하는 단위 테스트)를 작성하는 방법을 배웠습니다.
|
||||
하지만 퍼즈 테스트는 단순한 단위 테스트 그 이상입니다.
|
||||
이 방법론을 사용하여 서버로 전송되는 요청을 퍼징하여 웹 애플리케이션을 테스트할 수 있습니다.
|
||||
|
||||
오늘은 웹 서버 퍼지 테스트에 대한 실용적인 접근 방식을 살펴보겠습니다.
|
||||
|
||||
이를 위해 다양한 도구가 도움이 될 수 있습니다.
|
||||
|
||||
[Burp Intruder](https://portswigger.net/burp/documentation/desktop/tools/intruder), [SmartBear](https://smartbear.com/) 등이 있습니다.
|
||||
하지만 유료 라이선스가 필요한 독점 도구(proprietary tools)도 있습니다.
|
||||
|
||||
|
||||
그렇기 때문에 오늘 데모에서는 `Burp Intruder`에서 영감을 받아 유사한 기능을 제공하는 Go로 작성된 간단한 오픈 소스 CLI를 사용하려고 합니다.
|
||||
이름은 [httpfuzz](https://github.com/JonCooperWorks/httpfuzz)입니다.
|
||||
|
||||
|
||||
## Getting started
|
||||
|
||||
이 도구는 아주 간단합니다.
|
||||
요청에 대한 템플릿(퍼지 데이터에 대한 placeholder를 정의), 단어 목록(퍼지 데이터)을 제공하면 `httpfuzz`가 요청을 렌더링하여 서버로 전송합니다.
|
||||
|
||||
먼저 요청에 대한 템플릿을 정의해야 합니다.
|
||||
다음 내용으로 `request.txt`라는 파일을 생성합니다.
|
||||
|
||||
```text
|
||||
POST / HTTP/1.1
|
||||
Content-Type: application/json
|
||||
User-Agent: PostmanRuntime/7.26.3
|
||||
Accept: */*
|
||||
Cache-Control: no-cache
|
||||
Host: localhost:8000
|
||||
Accept-Encoding: gzip, deflate
|
||||
Connection: close
|
||||
Content-Length: 35
|
||||
|
||||
{
|
||||
"name": "`S9`",
|
||||
}
|
||||
```
|
||||
|
||||
이것은 JSON 본문이 있는 `/` 경로에 대한 유효한 HTTP `POST` 요청입니다.
|
||||
본문의 "\`" 기호는 우리가 제공하는 데이터로 대체될 플레이스홀더를 정의합니다.
|
||||
|
||||
`httpfuzz`는 헤더, 경로, URL 매개변수를 퍼즈 처리할 수도 있습니다.
|
||||
|
||||
다음으로 요청에 넣을 입력의 단어 목록을 제공해야 합니다.
|
||||
다음 내용으로 `data.txt`라는 파일을 생성합니다:
|
||||
|
||||
```text
|
||||
SOME_NAME
|
||||
Mozilla/5.0 (Linux; Android 7.0; SM-G930VC Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/58.0.3029.83 Mobile Safari/537.36
|
||||
```
|
||||
|
||||
이 파일에서는 본문 내부에 대체될 두 개의 입력을 정의했습니다.
|
||||
실제 시나리오에서는 적절한 퍼즈 테스트를 위해 훨씬 더 많은 데이터를 여기에 넣어야 합니다.
|
||||
|
||||
이제 템플릿과 입력이 준비되었으니 도구를 실행해 보겠습니다.
|
||||
안타깝게도 이 도구는 바이너리로 배포되지 않으므로 소스에서 빌드해야 합니다.
|
||||
리포지토리를 복제하고 실행합니다.
|
||||
|
||||
```shell
|
||||
go build -o httpfuzz cmd/httpfuzz.go
|
||||
```
|
||||
(컴퓨터에 최신 버전의 Go가 설치되어 있어야 합니다.)
|
||||
|
||||
이제 바이너리를 얻었으니 실행해 보겠습니다.
|
||||
|
||||
```shell
|
||||
./httpfuzz \
|
||||
--wordlist data.txt \
|
||||
--seed-request request.txt \
|
||||
--target-header User-Agent \
|
||||
--target-param fuzz \
|
||||
--delay-ms 50 \
|
||||
--skip-cert-verify \
|
||||
--proxy-url http://localhost:8080 \
|
||||
```
|
||||
|
||||
- `httpfuzz`는 우리가 호출하는 바이너리입니다.
|
||||
- `--wordlist data.txt`는 우리가 제공한 입력이 포함된 파일입니다.
|
||||
- `--seed-request requests.txt`는 요청 템플릿입니다.
|
||||
- `--target-header User-Agent`는 `httpfuzz`가 `User-Agent` 헤더 대신에 제공된 입력을 사용하도록 지시합니다.
|
||||
- `--target-param fuzz`는 제공된 입력을 `fuzz` URL 매개변수의 값으로 사용하도록 `httpfuzz`에 지시합니다.
|
||||
- `--delay-ms 50`은 요청 사이에 50ms를 기다리도록 `httpfuzz`에 지시합니다.
|
||||
- `--skip-cert-verify`는 `httpfuzz`에게 TLS 확인을 수행하지 않도록 지시합니다.
|
||||
- `--proxy-url http://localhost:8080`는 `httpfuzz`에게 HTTP 서버의 위치를 알려줍니다.
|
||||
|
||||
2개의 입력과 3개의 위치(본문, `User-Agent` 헤더, `fuzz` 매개변수)에 배치할 수 있습니다.
|
||||
즉, `httpfuzz`는 6개의 요청을 생성하여 서버로 전송합니다.
|
||||
|
||||
실행해서 어떤 일이 일어나는지 봅시다.
|
||||
서버로 들어오는 요청을 확인할 수 있도록 모든 요청을 기록하는 간단한 웹 서버를 작성했습니다.
|
||||
|
||||
```shell
|
||||
$ ./httpfuzz \
|
||||
--wordlist data.txt \
|
||||
--seed-request request.txt \
|
||||
--target-header User-Agent \
|
||||
--target-param fuzz \
|
||||
--delay-ms 50 \
|
||||
--skip-cert-verify \
|
||||
--proxy-url http://localhost:8080 \
|
||||
|
||||
httpfuzz: httpfuzz.go:164: Sending 6 requests
|
||||
```
|
||||
|
||||
그리고 서버 로그입니다.
|
||||
|
||||
```text
|
||||
-----
|
||||
Got request to http://localhost:8000/
|
||||
User-Agent header = [SOME_NAME]
|
||||
Name = S9
|
||||
-----
|
||||
Got request to http://localhost:8000/?fuzz=SOME_NAME
|
||||
User-Agent header = [PostmanRuntime/7.26.3]
|
||||
Name = S9
|
||||
-----
|
||||
Got request to http://localhost:8000/
|
||||
User-Agent header = [PostmanRuntime/7.26.3]
|
||||
Name = SOME_NAME
|
||||
-----
|
||||
Got request to http://localhost:8000/
|
||||
User-Agent header = [Mozilla/5.0 (Linux; Android 7.0; SM-G930VC Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/58.0.3029.83 Mobile Safari/537.36]
|
||||
Name = S9
|
||||
-----
|
||||
Got request to http://localhost:8000/?fuzz=Mozilla%2F5.0+%28Linux%3B+Android+7.0%3B+SM-G930VC+Build%2FNRD90M%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.083+Mobile+Safari%2F537.36
|
||||
User-Agent header = [PostmanRuntime/7.26.3]
|
||||
Name = S9
|
||||
-----
|
||||
Got request to http://localhost:8000/
|
||||
User-Agent header = [PostmanRuntime/7.26.3]
|
||||
Name = Mozilla/5.0 (Linux; Android 7.0; SM-G930VC Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/58.0.3029.83 Mobile Safari/537.36
|
||||
```
|
||||
|
||||
6개의 HTTP 요청이 수신된 것을 확인할 수 있습니다.
|
||||
|
||||
이 중 2개는 `User-Agent` 헤더에 대한 값 파일의 값을 가지고 있고, 4개는 템플릿의 기본 헤더를 가지고 있습니다.
|
||||
|
||||
그 중 2개는 `fuzz` 쿼리 매개변수에 대한 값 파일의 값을 가지고 있고, 4개는 템플릿의 기본 헤더를 가지고 있습니다.
|
||||
|
||||
그 중 2개는 `Name` 본문 속성에 대한 값 파일에서 값을 가져오고, 4개는 템플릿의 기본 헤더를 사용합니다.
|
||||
|
||||
이 도구를 약간 개선하면 이러한 요청의 순열을 다르게 만들 수 있습니다(예: 값 파일의 값으로 `?fuzz=`와 `User-Agent`가 모두 있는 요청).
|
||||
|
||||
`httpfuzz`가 요청의 결과에 대한 정보를 제공하지 않는다는 점에 주목하세요.
|
||||
이를 파악하려면 서버에 대한 일종의 모니터링을 설정하거나 우리에게 의미 있는 방식으로 결과를 처리하는 `httpfuzz` 플러그인을 작성해야 합니다.
|
||||
그렇게 해봅시다.
|
||||
|
||||
사용자 정의 플러그인을 작성하려면 [`Listener`](https://github.com/JonCooperWorks/httpfuzz/blob/master/plugin.go#L13) 인터페이스를 구현해야합니다.
|
||||
|
||||
```go
|
||||
// Listener must be implemented by a plugin to users to hook the request - response transaction.
|
||||
// The Listen method will be run in its own goroutine, so plugins cannot block the rest of the program, however panics can take down the entire process.
|
||||
type Listener interface {
|
||||
Listen(results <-chan *Result)
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
||||
"github.com/joncooperworks/httpfuzz"
|
||||
)
|
||||
|
||||
type logResponseCodePlugin struct {
|
||||
logger *log.Logger
|
||||
}
|
||||
|
||||
func (b *logResponseCodePlugin) Listen(results <-chan *httpfuzz.Result) {
|
||||
for result := range results {
|
||||
b.logger.Printf("Got %d response from the server\n", result.Response.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
// New returns a logResponseCodePlugin plugin that simple logs the response code of the response.
|
||||
func New(logger *log.Logger) (httpfuzz.Listener, error) {
|
||||
return &logResponseCodePlugin{logger: logger}, nil
|
||||
}
|
||||
```
|
||||
|
||||
이제 플러그인을 빌드해야 합니다.
|
||||
|
||||
```shell
|
||||
go build -buildmode=plugin -o log exampleplugins/log/log.go
|
||||
```
|
||||
|
||||
그리고 `--post-request` 플래그를 통해 `httpfuzz`에 연결할 수 있습니다:
|
||||
|
||||
```shell
|
||||
$ ./httpfuzz \
|
||||
--wordlist data.txt \
|
||||
--seed-request request.txt \
|
||||
--target-header User-Agent \
|
||||
--target-param fuzz \
|
||||
--delay-ms 50 \
|
||||
--skip-cert-verify \
|
||||
--proxy-url http://localhost:8080 \
|
||||
--post-request log
|
||||
|
||||
httpfuzz: httpfuzz.go:164: Sending 6 requests
|
||||
httpfuzz: log.go:15: Got 200 response from the server
|
||||
httpfuzz: log.go:15: Got 200 response from the server
|
||||
httpfuzz: log.go:15: Got 200 response from the server
|
||||
httpfuzz: log.go:15: Got 200 response from the server
|
||||
httpfuzz: log.go:15: Got 200 response from the server
|
||||
httpfuzz: log.go:15: Got 200 response from the server
|
||||
```
|
||||
|
||||
Voila!
|
||||
Now we can at least see what the response code from the server was.
|
||||
|
||||
Of course, we can write much more sophisticated plugins that output much more data, but for the purpose of this exercise, that is enough.
|
||||
|
||||
|
||||
## 요약
|
||||
|
||||
퍼징은 단위 테스트를 훨씬 뛰어넘는 매우 강력한 테스트 기법입니다.
|
||||
|
||||
퍼징은 유효한 HTTP 요청의 일부를 서버의 취약점이나 결함을 노출할 수 있는 데이터로 대체하여 HTTP 서버를 테스트하는 데 매우 유용할 수 있습니다.
|
||||
|
||||
웹 애플리케이션 퍼지 테스트에 도움이 되는 무료 및 유료 도구가 많이 있습니다.
|
||||
|
||||
## 리소스
|
||||
|
||||
[OWASP: Fuzzing](https://owasp.org/www-community/Fuzzing)
|
||||
|
||||
[OWASP: Fuzz Vectors](https://owasp.org/www-project-web-security-testing-guide/v41/6-Appendix/C-Fuzz_Vectors)
|
||||
|
||||
[Hacking HTTP with HTTPfuzz](https://medium.com/swlh/hacking-http-with-httpfuzz-67cfd061b616)
|
||||
|
||||
[Fuzzing the Stack for Fun and Profit at DefCamp 2019](https://www.youtube.com/watch?v=qCMfrbpuCBk&list=PLnwq8gv9MEKiUOgrM7wble1YRsrqRzHKq&index=33)
|
||||
|
||||
[HTTP Fuzzing Scan with SmartBear](https://support.smartbear.com/readyapi/docs/security/scans/types/fuzzing-http.html)
|
||||
|
||||
[Fuzzing Session: Finding Bugs and Vulnerabilities Automatically](https://youtu.be/DSJePjhBN5E)
|
||||
|
||||
[Fuzzing the CNCF Landscape](https://youtu.be/zIyIZxAZLzo)
|
||||
|
||||
[18일차](day18.md)에 뵙겠습니다.
|
40
2023/ko/days/day18.md
Normal file
40
2023/ko/days/day18.md
Normal file
@ -0,0 +1,40 @@
|
||||
# DAST (동적 애플리케이션 보안 테스트)
|
||||
DAST(Dynamic Application Security Testing)는 외부 소스로부터의 공격을 시뮬레이션하여 애플리케이션의 보안을 평가하는 데 사용되는 기술입니다.
|
||||
아이디어는 가능한 한 많은 블랙박스 침투 테스트를 자동화하는 것입니다.
|
||||
실제 사람의 시간을 절약하고 다른 보안 도구(예: IAST)로의 트래픽을 생성하는 데 추가로 사용할 수 있습니다.
|
||||
|
||||
그럼에도 불구하고 조직이 애플리케이션을 프로덕션 환경에 배포하기 전에 개발 프로세스 초기에 잠재적인 취약점을 발견할 수 있도록 도와주기 때문에 SSDLC의 필수 구성 요소입니다. DAST 테스트를 수행함으로써 조직은 보안 사고를 예방하고 공격자에 의해 데이터와 자산이 손상되지 않도록 보호할 수 있습니다.
|
||||
|
||||
## 도구
|
||||
|
||||
DAST를 수행하는 데 사용할 수 있는 다양한 오픈 소스 도구가 있습니다. ZAP, Burp Suite, Arachni 등이 있습니다.
|
||||
|
||||
이러한 도구는 SQL 인젝션, 크로스 사이트 스크립팅 및 기타 일반적인 취약점 등 애플리케이션에 대한 다양한 유형의 공격을 시뮬레이션할 수 있습니다.
|
||||
|
||||
예를 들어 애플리케이션이 SQL 인젝션에 취약한 경우, DAST 툴은 애플리케이션에 `OR 1=1 --`과 같은 악성 SQL 쿼리를 전송하고 응답을 평가하여 취약한지 여부를 확인할 수 있습니다. 애플리케이션이 취약한 경우 데이터베이스의 모든 레코드를 반환하여 SQL 인젝션 공격이 성공했음을 나타낼 수 있습니다.
|
||||
|
||||
일부 테스트는 상당히 침략적일 수 있으며(예: 'DROP TABLE' 또는 이와 유사한 것을 포함할 수 있음), 적어도 데이터베이스에 많은 양의 테스트 데이터를 넣거나 심지어 앱에 DOS를 가할 수도 있습니다.
|
||||
|
||||
> __DAST 도구는 프로덕션 환경에서 절대 실행해서는 안 됩니다!!!__
|
||||
|
||||
모든 도구에는 애플리케이션에 대한 인증 가능성이 있으며 이로 인해 프로덕션 자격 증명이 손상될 수 있습니다. 또한 테스트 환경에 대해 인증된 스캔을 실행할 때는 적절한 역할을 사용해야 합니다(물론 RBAC 모델이 존재하는 경우 애플리케이션에 대해). 예를 들어, DAST는 다른 사용자를 삭제하거나 수정할 수 있는 역할을 사용하면 전체 환경을 사용할 수 없게 될 수 있으므로 사용하지 않아야 합니다.
|
||||
다른 테스트 방법론과 마찬가지로 범위를 분석해야 하므로 불필요한 대상을 검사하지 않습니다.
|
||||
|
||||
## 사용법
|
||||
일반적인 오류는 실제 애플리케이션이 아닌 보상 보안 제어 (compensating security control, 예: WAF)를 스캔하는 것입니다.
|
||||
|
||||
DAST는 본질적으로 애플리케이션 보안 테스트 도구이며 보안 완화가 아닌 실제 애플리케이션에 대해 사용해야 합니다. 상당히 표준화된 공격을 사용하기 때문에 외부 제어가 공격 트래픽을 차단할 수 있으며, 이러한 방식으로 잠재적으로 악용될 수 있는 플로우를 커버할 수 있습니다.(정의에 따라 공격자는 결국 이러한 조치를 우회할 수 있음)
|
||||
|
||||
실제 스캔은 매우 느리기 때문에 때때로 DevOps 파이프라인 외부에서 실행해야 합니다. 야간이나 주말에 실행하는 것이 좋은 예입니다. 일부 간단한 도구(zap / arachny 등)를 파이프라인에 사용할 수 있지만 스캔의 특성으로 인해 전체 개발 프로세스의 속도가 느려질 수 있습니다.
|
||||
|
||||
DAST 테스트가 완료되면 결과를 분석하여 발견된 취약점을 식별합니다. 그런 다음 조직은 취약점을 해결하고 애플리케이션의 전반적인 보안을 개선하기 위해 적절한 수정 조치를 취할 수 있습니다. 여기에는 기본 코드 수정, 입력 유효성 검사 및 필터링과 같은 추가 보안 제어 구현 또는 두 가지 모두 포함될 수 있습니다.
|
||||
|
||||
결론적으로, 애플리케이션의 보안을 보장하기 위해서는 SSDLC에서 DAST를 사용하는 것이 필수적입니다. 개발 프로세스 초기에 DAST 테스트를 수행하고 취약점을 식별함으로써 조직은 보안 사고를 예방하고 잠재적인 위협으로부터 자산을 보호할 수 있습니다. ZAP, Burp Suite, Arachni와 같은 오픈 소스 도구를 사용하여 DAST 테스트를 수행하고 조직의 전반적인 보안 태세를 개선할 수 있습니다.
|
||||
DevSecOps 파이프라인의 다른 모든 도구와 마찬가지로 DAST가 유일한 스캐너가 되어서는 안 되며, 다른 모든 도구와 마찬가지로 모의 침투 테스트와 모범 개발 관행을 대체할 수 없습니다.
|
||||
|
||||
## 유용한 링크와 오픈소스 도구가 몇 가지
|
||||
- https://github.com/zaproxy/zaproxy
|
||||
- https://www.arachni-scanner.com/
|
||||
- https://owasp.org/www-project-devsecops-guideline/latest/02b-Dynamic-Application-Security-Testing
|
||||
|
||||
[19일차](day19.md)에 뵙겠습니다.
|
48
2023/ko/days/day19.md
Normal file
48
2023/ko/days/day19.md
Normal file
@ -0,0 +1,48 @@
|
||||
# IAST (Interactive Application Security Testing)
|
||||
|
||||
IAST는 웹 애플리케이션의 취약점을 식별하고 개발자가 이를 수정할 수 있도록 설계된 보안 테스트 도구의 일종입니다. 이 도구는 애플리케이션의 런타임 환경에 작은 에이전트를 삽입하고 실시간으로 동작을 모니터링하는 방식으로 작동합니다. 따라서 IAST 도구는 정적 분석이나 모의 공격에 의존하지 않고 취약점이 발생할 때 이를 식별할 수 있습니다.
|
||||
|
||||
instrumentation
|
||||
|
||||
IAST는 소프트웨어 계측(software instrumentation) 또는 계측기를 사용하여 애플리케이션이 실행되는 동안 모니터링하고 애플리케이션이 수행하는 작업과 성능에 대한 정보를 수집하는 방식으로 작동합니다. IAST 솔루션은 실행 중인 애플리케이션에 에이전트와 센서를 배포하고 수동 테스트, 자동 테스트 또는 이 둘의 조합으로 시작된 모든 애플리케이션 상호 작용을 지속적으로 분석하여 실시간으로 취약성을 식별함으로써 애플리케이션을 계측합니다.
|
||||
IAST 에이전트는 애플리케이션 내부에서 실행되며 알려진 공격 패턴을 모니터링합니다. 애플리케이션의 일부이므로 서로 다른 구성 요소 간의 트래픽을 모니터링할 수 있습니다. (클래식 MVC 배포 및 마이크로서비스 배포 간)
|
||||
|
||||
## IAST의 전제조건
|
||||
|
||||
- 애플리케이션을 계측해야 합니다. (Agent를 주입해야 함.
|
||||
- 수동 또는 자동 테스트를 통해 트래픽을 생성해야 합니다. 또 다른 가능한 접근 방식은 DAST 도구를 사용하는 것입니다. (예를 들어 OWASP ZAP을 사용할 수 있음)
|
||||
|
||||
|
||||
## 장점
|
||||
|
||||
IAST 도구의 주요 장점 중 하나는 취약점과 취약점 수정 방법에 대한 상세하고 정확한 정보를 제공할 수 있다는 것입니다. 개발자가 수동으로 취약점을 검색하거나 테스트 환경에서 취약점을 재현할 필요가 없으므로 많은 시간과 노력을 절약할 수 있습니다.
|
||||
|
||||
또한 IAST 도구는 사용자 상호 작용이 필요하거나 특정 조건에서 트리거되는 취약점 등 다른 테스트 방법으로는 놓칠 수 있는 취약점을 식별할 수 있습니다.
|
||||
|
||||
테스트 시간은 사용되는 테스트에 따라 다르며(IAST는 독립형 시스템이 아니므로), 더 빠른 테스트(자동화된 테스트)를 CI/CD 파이프라인에 포함할 수 있습니다. 다양한 종류의 취약점을 탐지하는 데 사용할 수 있으며 도구의 특성상('실제 트래픽만' 찾기 때문에) 다른 테스트 유형에 비해 위양성/위음성 결과가 상대적으로 뒤처집니다.
|
||||
IAST는 일반적인 테스트 도구와 실시간 보호(이 경우 RAST라고 함)의 두 가지 방식으로 사용할 수 있습니다. 두 가지 모두 동일한 원칙에 따라 작동하며 함께 사용할 수 있습니다.
|
||||
|
||||
## 몇 가지 단점
|
||||
- 비교적 새로운 기술이기 때문에 보안 팀과 도구 빌더(오픈 소스 또는 상용) 모두에 대한 지식과 경험이 많지 않습니다.
|
||||
- 이 솔루션은 단독으로 사용할 수 없으며 누군가(또는 무언가)가 트래픽 패턴을 생성해야 합니다. 테스트 중에 가능한 모든 엔드포인트를 쿼리하는 것이 중요합니다.
|
||||
- 결과는 트래픽을 기반으로 합니다. 앱/사이트의 일부에 대한 트래픽이 없는 경우 테스트가 이루어지지 않으므로 결과가 생성되지 않습니다.
|
||||
- 앱에 대한 계측이 필요하기 때문에 특히 소스 스캔 도구(SAST 또는 SCA)에 비해 상당히 복잡할 수 있습니다.
|
||||
|
||||
각각 고유한 특징과 기능을 갖춘 여러 가지 IAST 도구를 사용할 수 있습니다.
|
||||
|
||||
## IAST 도구의 일반적인 기능
|
||||
|
||||
- 실시간 모니터링: IAST 도구는 애플리케이션의 동작을 실시간으로 모니터링하여 취약점이 발생할 때 이를 식별할 수 있습니다.
|
||||
- 취약점 식별: IAST 도구는 인젝션 공격, 크로스 사이트 스크립팅(XSS), 크로스 사이트 요청 위조(CSRF)를 포함한 광범위한 취약점을 식별할 수 있습니다.
|
||||
- 수정 지침: IAST 도구는 코드 스니펫 및 보안 코딩 관행에 대한 권장 사항을 포함하여 식별된 취약점을 수정하는 방법에 대한 자세한 정보를 제공하는 경우가 많습니다.
|
||||
- 다른 도구와의 통합: IAST 도구는 정적 코드 분석 또는 침투 테스트 도구와 같은 다른 보안 테스트 도구와 통합하여 애플리케이션의 보안에 대한 보다 포괄적인 보기를 제공할 수 있습니다.
|
||||
|
||||
IAST 도구는 실시간으로 취약점을 식별하고 수정하여 시간과 노력을 절약할 수 있으므로 개발자의 툴킷에 추가할 수 있는 유용한 도구가 될 수 있습니다. 개발자로서 IAST 도구 사용에 관심이 있다면 다양한 옵션을 사용할 수 있으므로 여러 도구를 조사하고 비교하여 자신의 필요에 가장 적합한 도구를 찾는 것이 중요합니다.
|
||||
|
||||
## 도구 예시
|
||||
|
||||
시중에는 오픈 소스 도구가 거의 없습니다. 상용 도구를 예로 들 수 있습니다: Contrast Community Edition(CE) - 앱 1개와 최대 5명의 사용자를 위한 모든 기능을 갖춘 버전(일부 엔터프라이즈 기능은 비활성화됨). Contrast CE는 Java 및 .NET만 지원합니다.
|
||||
|
||||
여기에서 찾을 수 있습니다. https://www.contrastsecurity.com/contrast-community-edition
|
||||
|
||||
[20일차](day20.md)에 뵙겠습니다.
|
155
2023/ko/days/day20.md
Normal file
155
2023/ko/days/day20.md
Normal file
@ -0,0 +1,155 @@
|
||||
# IAST와 DAST의 결합 - 실습 시간
|
||||
|
||||
IAST와 DAST가 무엇인지 배웠다면 이제 실제 애플리케이션에서 이 프로세스를 사용하여 취약점을 찾아보는 실습을 해보겠습니다.
|
||||
|
||||
**참고: 오픈 소스 IAST 구현이 없으므로 상용 솔루션을 사용해야 합니다.
|
||||
무료 티어가 있으므로 비용을 지불하지 않고도 실습을 따라갈 수 있으니 걱정하지 마세요.
|
||||
|
||||
|
||||
|
||||
여기에는 테스트하고 활용할 취약한 Java 애플리케이션, 손쉬운 설정을 위한 Docker 및 Docker Compose, IAST 솔루션용 [Contrast Community Edition](https://www.contrastsecurity.com/contrast-community-edition?utm_campaign=ContrastCommunityEdition&utm_source=GitHub&utm_medium=WebGoatLab)이 포함되어 있습니다.
|
||||
|
||||
## 전제조건
|
||||
|
||||
- [Docker](https://www.docker.com/products/docker-desktop/)
|
||||
- [Docker Compose](https://docs.docker.com/compose/)
|
||||
- Contrast CE 계정. [이 곳](https://www.contrastsecurity.com/contrast-community-edition?utm_campaign=ContrastCommunityEdition&utm_source=GitHub&utm_medium=WebGoatLab)에서 무료로 회원가입하세요.
|
||||
|
||||
**참고** : 이 글과 90일간의 데브옵스 프로그램의 작성자는 Contrast Security와 어떤 식으로든 관련이 있거나 관련이 있습니다.
|
||||
오픈 소스 솔루션이 없고, 이 솔루션에는 결제나 신용카드 제공이 필요 없는 무료 티어가 있기 때문에 이 상용 솔루션을 사용하고 있습니다.
|
||||
|
||||
1. 오픈 소스 IAST 구현이 없기 때문에 일부 무료 라이선스가 있는 상용 소스를 사용합니다. 이를 위해 2 개의 구성 요소가 필요합니다:
|
||||
IAST 솔루션 - <https://github.com/rstatsinger/contrast-java-webgoat-docker>. Mac 또는 Linux 환경에 설치된 docker 및 docker-compose가 필요합니다(이 실습은 Mint에서 테스트되었습니다). README를 따라 Contrast에서 계정을 생성하세요.
|
||||
|
||||
## Getting started
|
||||
|
||||
|
||||
시작하려면 [리포지토리](https://github.com/rstatsinger/contrast-java-webgoat-docker)를 복제합니다.
|
||||
|
||||
Contrast Security에서 자격 증명을 받습니다.
|
||||
오른쪽 상단의 `Organization Settings` -> `Agent`에서 당신의 이름을 클릭합니다.
|
||||
그리고 `Agent Username`, `Agent Service Key` and `API Key`를 가져옵니다.
|
||||
새로 복제된 리포지토리의 `.env.template` 파일에서 이 값으로 바꿉니다.
|
||||
|
||||
**참고:** 이 값은 비밀입니다.
|
||||
Git에 커밋하지 마세요.
|
||||
실수로 이 값을 커밋하지 않도록 `.env.template`을 `.gitignore` 아래에 두는 것이 가장 좋습니다.
|
||||
|
||||
|
||||
## 취약한 애플리케이션 실행하기
|
||||
|
||||
취약한 애플리케이션을 실행합니다.
|
||||
|
||||
```sh
|
||||
./run.sh
|
||||
```
|
||||
|
||||
또는
|
||||
|
||||
```sh
|
||||
docker compose up
|
||||
```
|
||||
|
||||
준비가 완료되면 <http://localhost:8080/WebGoat>에서 애플리케이션 UI에 액세스할 수 있습니다.
|
||||
|
||||
## 피해 입히기
|
||||
|
||||
이제 취약한 애플리케이션이 생겼으니 이를 익스플로잇해 보겠습니다.
|
||||
|
||||
1. [여기](https://www.zaproxy.org/download/)에서 ZAP 프록시를 설치합니다.
|
||||
|
||||
가장 쉬운 방법은 DAST 스캐너를 이용하는 것입니다.
|
||||
이러한 스캐너 중 하나는 [ZAP Proxy](https://www.zaproxy.org/)입니다.
|
||||
무료 오픈소스 웹 앱 스캐너입니다.
|
||||
|
||||
2. [여기](https://github.com/Grunny/zap-cli)에서 `zap-cli`를 설치합니다.
|
||||
|
||||
다음으로 `zap-cli`를 설치합니다.
|
||||
`zap-cli`는 ZAP Proxy를 위한 오픈소스 CLI입니다.
|
||||
|
||||
3. ZAP 프록시 실행
|
||||
|
||||
설치된 위치에서 ZAP 프록시를 실행합니다.
|
||||
Linux Mint에서는 기본적으로 `/opt/zaproxy`에 있습니다.
|
||||
MacOS에서는 `Applications`에 있습니다.
|
||||
|
||||
4. `ZAP_API_KEY` 및 `ZAP_PORT`에 대한 환경 변수를 설정합니다.
|
||||
|
||||
ZAP 프록시에서 이 값을 가져옵니다.
|
||||
`Options...` -> `API`로 이동하여 API 키를 가져옵니다.
|
||||
|
||||
`Options...` -> `Network` -> `Local Servers/Proxies`로 이동하여 포트를 설정하고 가져옵니다.
|
||||
|
||||
5. `zap-cli`로 몇 가지 명령을 실행합니다.
|
||||
|
||||
예시:
|
||||
|
||||
```sh
|
||||
zap-cli quick-scan -s all --ajax-spider -r http://127.0.0.1:8080/WebGoat/login.mvc
|
||||
```
|
||||
|
||||
또는 [리포지토리](https://github.com/rstatsinger/contrast-java-webgoat-docker/blob/master/Lab-WebGoat.pdf)에 있는 지침에 따라 취약한 애플리케이션을 손상시킬 수 있습니다.
|
||||
|
||||
6. Constrast에서 결과 관찰
|
||||
|
||||
어느 쪽이든, Contrast에서 애플리케이션의 **Vulnerabilities** 탭으로 이동하면, Contrast가 취약점을 감지한 것을 확인할 수 있을 것입니다.
|
||||
조치를 취하라는 경고가 표시됩니다.
|
||||
|
||||
## 보너스: 이미지 스캐닝
|
||||
|
||||
애플리케이션의 동작을 관찰하여 공격을 탐지하는 데 IAST 솔루션이 어떻게 도움이 되었는지 살펴보았습니다.
|
||||
이러한 공격을 애초에 막을 수 있었는지 살펴봅시다.
|
||||
|
||||
이 데모에 사용한 취약한 애플리케이션은 컨테이너로 된 패키지였습니다.
|
||||
[14일차](day14.md)와 [15일차](day15.md)에서 배운 `grype` 스캐너를 통해 이 컨테이너를 스캔하고 결과를 확인해 보겠습니다.
|
||||
|
||||
```sh
|
||||
$ grype contrast-java-webgoat-docker-webgoat
|
||||
✔ Vulnerability DB [no update available]
|
||||
✔ Loaded image
|
||||
✔ Parsed image
|
||||
✔ Cataloged packages [316 packages]
|
||||
✔ Scanned image [374 vulnerabilities]
|
||||
NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY
|
||||
apt 1.8.2.3 deb CVE-2011-3374 Negligible
|
||||
axis 1.4 java-archive GHSA-55w9-c3g2-4rrh Medium
|
||||
axis 1.4 java-archive GHSA-96jq-75wh-2658 Medium
|
||||
bash 5.0-4 deb CVE-2019-18276 Negligible
|
||||
bash 5.0-4 (won't fix) deb CVE-2022-3715 High
|
||||
bsdutils 1:2.33.1-0.1 deb CVE-2022-0563 Negligible
|
||||
bsdutils 1:2.33.1-0.1 (won't fix) deb CVE-2021-37600 Low
|
||||
commons-beanutils 1.8.3 java-archive CVE-2014-0114 High
|
||||
commons-beanutils 1.8.3 java-archive CVE-2019-10086 High
|
||||
commons-beanutils 1.8.3 1.9.2 java-archive GHSA-p66x-2cv9-qq3v High
|
||||
commons-beanutils 1.8.3 1.9.4 java-archive GHSA-6phf-73q6-gh87 High
|
||||
commons-collections 3.2.1 java-archive CVE-2015-6420 High
|
||||
commons-collections 3.2.1 3.2.2 java-archive GHSA-6hgm-866r-3cjv High
|
||||
commons-collections 3.2.1 3.2.2 java-archive GHSA-fjq5-5j5f-mvxh Critical
|
||||
commons-fileupload 1.3.1 java-archive CVE-2016-1000031 Critical
|
||||
commons-fileupload 1.3.1 java-archive CVE-2016-3092 High
|
||||
commons-fileupload 1.3.1 1.3.2 java-archive GHSA-fvm3-cfvj-gxqq High
|
||||
commons-fileupload 1.3.1 1.3.3 java-archive GHSA-7x9j-7223-rg5m Critical
|
||||
commons-io 2.4 java-archive CVE-2021-29425 Medium
|
||||
commons-io 2.4 2.7 java-archive GHSA-gwrp-pvrq-jmwv Medium
|
||||
coreutils 8.30-3 deb CVE-2017-18018 Negligible
|
||||
coreutils 8.30-3 (won't fix) deb CVE-2016-2781 Low
|
||||
curl 7.64.0-4+deb10u3 deb CVE-2021-22922 Negligible
|
||||
curl 7.64.0-4+deb10u3 deb CVE-2021-22923 Negligible
|
||||
<truncated>
|
||||
```
|
||||
|
||||
보시다시피 이 이미지는 취약점으로 가득 차 있습니다.
|
||||
|
||||
각 취약점을 자세히 살펴보면 RCE(원격 코드 실행), SQL 인젝션, XML 외부 엔티티 취약점 등과 같은 취약점이 있음을 알 수 있습니다.
|
||||
|
||||
## 주간 요약
|
||||
|
||||
IAST와 DAST는 애플리케이션의 동작을 모니터링하여 애플리케이션의 취약점을 찾는 데 도움이 되는 중요한 방법입니다.
|
||||
이 작업은 애플리케이션이 이미 배포된 후에 수행됩니다.
|
||||
|
||||
컨테이너 이미지 스캔은 컨테이너 내부에 있는 라이브러리를 기반으로 애플리케이션의 취약점을 찾는 데 도움이 될 수 있습니다.
|
||||
|
||||
이미지 스캔과 IAST/DAST는 상호 배타적이지 않습니다.
|
||||
둘 다 보안 SDLC에서 각자의 역할을 하며 공격자보다 먼저 다양한 문제를 발견하는 데 도움이 될 수 있습니다.
|
||||
|
||||
[21일차](day21.md)에 뵙겠습니다.
|
Loading…
Reference in New Issue
Block a user