
프로세서 설계가 점점 더 복잡해지면서 하드웨어 리소스 간의 의도하지 않은 상호작용을 공격자들이 악용할 기회도 증가했습니다. 그 중 하나의 미묘하면서도 강력한 공격은 **마이크로아키텍처적 서비스 거부(DoS)**입니다. 이 공격은 소프트웨어의 격리 보장에는 위배되지 않으면서 한 프로세스가 하드웨어 수준에서 다른 프로세스의 성능을 저해하는 방식으로 이루어집니다. 이러한 공격은 시스템을 충돌시키거나 서비스를 완전히 멈추지 않고 대신 데이터 처리 속도를 느리게 하고, 사이클을 탈취하거나 최신 CPU 내부 깊은 곳에서 동작을 통해 서비스 품질(QoS)을 저하시킵니다.
이 포괄적인 블로그 게시물에서는 마이크로아키텍처적 DoS의 이론, 실행 및 방어에 대해 탐구할 것입니다. 기본 원칙에서 시작하여 방어 상호작용 및 현실 세계의 탐지 스크립트와 같은 고급 주제로 점진적으로 나아갈 것입니다.
마이크로아키텍처는 컴퓨터의 명령어 집합 아키텍처(ISA)를 하드웨어에서 구현한 것입니다. 아키텍처는 (x86 또는 ARM과 같이) 가시적 행동 계약을 정의하는 반면, 마이크로아키텍처는 실제로 "어떻게" 실행되는지 결정하며 파이프라인, 레지스터, 캐시, 실행 유닛 등으로 리소스를 분리합니다.
주요 마이크로아키텍처 구성 요소는 다음과 같습니다:
이러한 리소스는 효율성을 위해 프로세스나 스레드 간에 종종 공유됩니다.
동시 멀티스레딩(SMT)—Intel CPU에서는 하이퍼 스레딩이라고 불립니다—는 단일 물리적 코어에서 여러 하드웨어 스레드를 실행할 수 있게 합니다. 예를 들어, 쿼드코어/8스레드 CPU는 각각의 코어가 두 개의 하드웨어 스레드를 가집니다.
주요 사실: 스레드는 중요한 리소스를 공유합니다: 캐시, 파이프라인 단계, 실행 유닛 등.
마이크로아키텍처적 서비스 거부(DoS) 공격은 하나의 (악성 또는 버그가 있는) 스레드가 피해자 스레드와 (종종 동일 SMT 코어나 캐시를 공유하는) 함께 위치하여 불균형 하드웨어 자원을 소모하며 공동 실행 프로세스를 굶주리게 하거나 느리게 함으로써 발생합니다.
마이크로아키텍처적 DoS는 성능을 목표로 하는 비전통적인 서비스 거부 공격입니다. 주요 위협 모델은 피해자와 동일한 하드웨어에서 함께 위치한 강력한 공격자를 포함합니다.
이 기초 연구는 Intel SMT 프로세서에서 악성 스레드가 리소스를 독점함으로써 피해자 스레드를 5배 이상 느리게 할 수 있음을 보여주었습니다.
실험 설정: 한 스레드는 no-op 또는 가벼운 루프를 실행했습니다; 공격자 스레드는 캐시 라인을 계속 제거하거나 특정 ALU를 사용하는 일정을 수행하는 코드 실행.
결과: 소프트웨어 수준에서의 보안 격리가 하드웨어 리소스 고갈로 인해 무효화되었습니다.
클라우드 제공업체는 가상 머신(VM) 또는 컨테이너를 통해 단일 CPU에 여러 고객을 배치합니다. 리소스 경쟁은 불가피하지만 SMT에서는 문제가 확장됩니다:
마이크로아키텍처적 서비스 거부를 능동적으로 탐지하는 것은 쉽지 않습니다. 증상은 일반적인 리소스 경쟁과 비슷해 보입니다. 하지만 성능 카운터 모니터링과 워크로드 지문 인식을 결합하여 가능성 있는 공격을 신호할 수 있습니다.
현대 CPU는 다양한 이벤트에 대한 하드웨어 성능 카운터를 제공합니다:
이들은 Linux에서 perf와 같은 명령 줄 도구로 검사할 수 있습니다.
perf stat -e L1-dcache-load-misses sleep 10
다음은 주어진 프로세스(PID)에 대해 여러 카운터를 모니터링하는 Bash 스크립트입니다:
#!/bin/bash
if [ -z "$1" ]; then
echo "사용법: $0 <pid>"
exit 1
fi
PID=$1
echo "리소스 경쟁을 모니터링 중... PID $PID."
echo "시간,L1-dcache-load-misses,LLC-load-misses,branch-misses"
while true; do
PERFDATA=$(perf stat -p $PID -e L1-dcache-load-misses,LLC-load-misses,branch-misses --interval-print 1000 2>&1 | grep -E "L1|LLC|branch")
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
L1=$(echo "$PERFDATA" | grep 'L1-dcache-load-misses' | awk '{print $1}')
LLC=$(echo "$PERFDATA" | grep 'LLC-load-misses' | awk '{print $1}')
BRANCH=$(echo "$PERFDATA" | grep 'branch-misses' | awk '{print $1}')
echo "$TIMESTAMP,$L1,$LLC,$BRANCH"
sleep 1
done
사용법:
monitor.sh로 저장합니다.bash monitor.sh <pid_of_victim_process>다음은 Python을 사용하여 프로세스를 자동화하고 의심스러운 이벤트에 대한 경고를 생성합니다:
import subprocess
import re
import time
PID = 12345 # 대체할 프로세스 ID
pattern = re.compile(
r"(?P<count>\d+).*\s+(?P<event>L1-dcache-load-misses|LLC-load-misses|branch-misses)"
)
def read_perf(pid):
cmd = [
"perf", "stat", "-p", str(pid),
"-e", "L1-dcache-load-misses,LLC-load-misses,branch-misses",
"sleep", "1"
]
result = subprocess.run(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
metrics = {}
for line in result.stderr.split('\n'):
match = pattern.search(line)
if match:
metrics[match.group('event')] = int(match.group('count').replace(',', ''))
return metrics
def detect_anomaly(prev_metrics, curr_metrics, threshold=2.0):
for event in prev_metrics:
ratio = curr_metrics[event] / (prev_metrics[event] + 1)
if ratio > threshold:
print(f"ALERT: {event} spiked by {ratio:.1f}x")
prev = read_perf(PID)
while True:
time.sleep(1)
curr = read_perf(PID)
detect_anomaly(prev, curr)
prev = curr
참고: perf가 설치되어 있어야 하며 루트 권한이 필요합니다.
리소스 분할:
QoS 및 공정 스케줄링:
SMT 비활성화:
스케줄러 인식:
공동 테넌트 격리 정책:
탐지 시 종료하거나 이동:
최근 연구에 따르면:
현대의 하드웨어 보안 메커니즘은 때때로 서로 간섭할 수 있습니다. 예를 들어, Meltdown/Spectre의 완화는 버퍼 동작을 변경하여 새로운 DoS 경로를 열 수 있습니다. _보안 통합 지원_은 특정 클래스의 공격에 대한 방어책을 추가할 때 다른 곳에서 더 미묘한 마이크로아키텍처적 위험을 생성하지 않는 것을 의미합니다.
마이크로아키텍처적 서비스 거부는 고성능 및 멀티 테넌트 환경에서 점점 우려스러운 문제로 부상하고 있습니다. 이러한 공격에서 스케줄링 공정성을 확보하고 보호하기 위해 하드웨어, 운영 체제 및 클라우드 제공업체의 인식, 모니터링 및 공동 노력이 필요합니다. CPU가 더욱 발전함에 따라 생태계는 이러한 위협을 추적, 탐지 및 방어해야 하며 방어 상호작용의 함정을 피하기 위해 구성 보안을 지원해야 합니다.
위 내용을 귀하의 기술 블로그에 *전체* 게시하여 최대한의 SEO 효과를 누릴 수 있습니다.
이 콘텐츠가 유용하다고 생각하셨다면, 저희의 포괄적인 47주 엘리트 교육 프로그램으로 무엇을 달성할 수 있을지 상상해 보세요. Unit 8200 기술로 경력을 변화시킨 1,200명 이상의 학생들과 함께하세요.