메모리 보호는 흔히 CPU의 최상위 특권 계층이 지키는 것으로 여겨진다. SEV, SGX, TDX, TrustZone 같은 격리 기술부터 AMD의 보안 프로세서(PSP)나 시스템 관리 모드(SMM)의 SMRAM까지, 운영체제는 물론 링-0조차 들여다볼 수 없는 영역이 있다. 보안 연구자 크리스토퍼 도마스(@xoreaxeaxeax)가 공개한 skitter-creek-bath-salts는 이 전제를 밑바닥에서부터 뒤집는다. 그는 이런 보호 장치들이 모두 '물리 주소'를 기준으로 세워졌을 뿐, 그 물리 주소가 실제 DRAM 칩의 어느 셀에 떨어지는지를 결정하는 마지막 변환 단계는 아무도 지키지 않는다는 점을 파고든다.
물리 주소는 사실 제안일 뿐이다
코드가 포인터 *p를 역참조할 때, 그 주소는 곧장 DRAM에 닿지 않는다. 가상 주소가 물리 주소로, 다시 메모리 컨트롤러(MCT/DCT) 단계에서 실제 DRAM 좌표로 재작성되는 긴 파이프라인을 거친다. 채널·랭크·뱅크 인터리브, 스위즐, 칩셀렉트 정규화 같은 변환이 이 최하단에서 일어난다. 도마스가 주목한 지점이 바로 여기다. DRAM 컨트롤러의 변환 레지스터를 건드리면 물리 주소가 매핑되는 DRAM 좌표 자체가 바뀐다. 그의 표현대로 '&x가 더 이상 &x가 아닌' 상태가 된다. CPU·펌웨어·칩셋이 세운 모든 방벽은 이 컨트롤러보다 위에 있고 물리 주소만 감시하므로, 좌표를 뒤섞으면 방벽은 아무것도 눈치채지 못한다.
실제 조작은 놀랄 만큼 단순하다. DCT의 뱅크 스위즐 모드 같은 비트 하나를 뒤집는 xor dword 한 줄이면 메모리 전체가 재배선된다. 진짜 어려운 부분은 시스템 메모리가 발밑에서 통째로 뒤섞이는 와중에도 플랫폼을 살려두는 일이다. 해법은 '빠르게, 그리고 DRAM을 건드리지 않는 것'이다. 보조 코어(AP)를 멈추고 TLB를 예열하고 캐시를 데운 뒤 인터럽트를 끄고, 대상만 플러시한 다음 매핑을 뒤집어 보호 영역에서 데이터를 읽고 곧바로 원상 복구한다. 짧은 순간에 좌표를 스파게티처럼 헝클었다가 흔적 없이 되돌리는 셈이다.
뒤섞인 메모리를 z3로 해독하다
문제는 재배선 후 컨트롤러가 어떤 새 변환을 쓰는지 데이터시트에 충분히 적혀 있지 않다는 점이다. 뒤섞기만 해서는 무엇이 어디로 갔는지 알 수 없다. 다행히 DRAM 컨트롤러의 주소 변환은 GF(2) 위의 선형 사상이라, 선형대수로 복원할 수 있다. 방법은 이렇다. 정상 상태에서 뒤섞인 상태로 전환해 0xdeadc0de 같은 표식 값을 임의 주소에 심고, 다시 정상 상태로 돌아와 그 값이 어디서 다시 떠오르는지 메모리를 훑는다. 이렇게 얻은 (원래 주소, 별칭 주소) 쌍 여러 개를 z3 SMT 솔버에 넣으면 두 관점을 잇는 변환 행렬이 풀린다. 이 행렬은 일종의 로제타석으로, 정상 관점의 어떤 보호 주소든 뒤섞인 관점에서 같은 DRAM 셀에 닿는 별칭으로 바꿔준다. 별칭은 정상 관점을 위해 세워진 어떤 잠금장치도 거치지 않는다.
무엇이 열리는가
이 별칭 지도를 손에 쥐면 접근 대상은 사실상 제한이 없다. fTPM은 PSP 자체 ARM 코어 위에서, 가시 메모리 상단 너머의 DRAM 카브아웃에서 돌아간다. 도마스는 OS가 볼 수 있는 물리 주소를 그 영역에 별칭으로 겹쳐 PSP의 RSA 모듈러 지수 연산 엔진을 통째로 끄집어낸다. SMM 핸들러도 마찬가지다. MSR 0xc0010111에서 SMBASE를 읽어 +0x8000의 진입 벡터를 별칭으로 훑으면, 칩셋이 읽지 못하게 잠갔다는 링-2 코드가 그대로 디스어셈블러로 흘러든다. 'SMRAM 잠금'이 컨트롤러 앞에서는 정중한 권고에 그친다는 뜻이다. 코어가 C6 절전 상태로 들어갈 때 저장되는 전체 x86 아키텍처 상태, 그리고 +0x1800에 보관돼 깨어날 때 다시 적재되는 마이크로코드 패치 사본까지 노출된다. dram_poke는 읽기를 넘어 이 사본에 쓰기까지 가능하다.
실무자 관점에서 두 가지 한계를 분명히 해둘 필요가 있다. 첫째, 공개된 익스플로잇은 AMD Family 16h 한 세대에 묶여 있다. 이 세대가 DRAM 컨트롤러의 변환 레지스터를 문서화했고 그것이 잠기지 않는다는 사실까지 보여준 마지막 세대이기 때문이다. 17h 이후는 이 정보를 아예 데이터시트에서 뺐다. 둘째, 공격에는 컨트롤러 레지스터에 직접 쓸 수 있는 수준의 접근이 전제된다. 즉 원격 임의 코드 실행 같은 손쉬운 시나리오가 아니라, 이미 상당한 권한을 가진 공격자가 그 위 계층의 격리를 무력화하는 특권 상승 성격에 가깝다.
그럼에도 이 연구가 던지는 함의는 특정 칩을 넘어선다. 채널·랭크·뱅크 인터리브와 스위즐은 AMD뿐 아니라 인텔, ARM, RISC-V, 모바일부터 서버·임베디드까지 현대 메모리 컨트롤러가 공통으로 수행하는 구조다. 그 위에 SEV, SGX, TDX, TrustZone, CCA, pKVM, ME, T-SEG 같은 신뢰 실행 환경이 층층이 쌓여 있지만, 결국 모두 같은 형태의 *p 파이프라인 최하단에 의지한다. 보호된 비밀은 여전히 같은 DRAM 커패시터 안에 그대로 있고, 잠금장치는 '정상 관점'만을 상정해 만들어졌다는 것이 이 연구의 핵심 지적이다. 도마스 자신도 이번 공개가 '시작하는 방법을 보여줄 뿐'이라고 선을 긋는다. 신뢰의 뿌리를 컨트롤러 위 계층에만 두는 설계가 얼마나 취약할 수 있는지, 하드웨어 보안을 다루는 이들이 다시 짚어볼 만한 대목이다.
TTJ 코딩클래스 정규반
월급 외 수입,
코딩으로 만들 수 있습니다
17가지 수익 모델을 직접 실습하고, 1,300만원 상당의 자동화 도구와 소스코드를 받아가세요.
"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"
실제 수강생 후기- 비전공자도 6개월이면 첫 수익
- 20년 경력 개발자 직강
- 자동화 프로그램 + 소스코드 제공