Split View: x86 하드웨어 백도어라는 말의 정확한 범위 — rosenbridge를 저자가 쓴 대로 읽기
x86 하드웨어 백도어라는 말의 정확한 범위 — rosenbridge를 저자가 쓴 대로 읽기
- 들어가며 — 제목과 본문 사이의 거리
- rosenbridge가 실제로 무엇인가
- 저자가 직접 그은 네 개의 경계선
- 왜 ME나 PSP와 구분해서 이야기해야 하나
- 어떻게 찾았나 — 문서 없이 명령어 집합을 탐색하는 문제
- sandsifter 스캔이 실제로 찾아내는 것
- 방법은 일반화되지만 발견은 일반화되지 않는다
- 실무자가 여기서 가져갈 것
- 참고 자료
들어가며 — 제목과 본문 사이의 거리
xoreaxeaxeax/rosenbridge라는 GitHub 저장소가 있습니다. 설명은 한 줄입니다. "Hardware backdoors in x86 CPUs." 별이 2,500개가 넘고, 주기적으로 커뮤니티 상단에 다시 올라옵니다.
이 제목만 보고 "내 CPU에 백도어가 있다"고 결론 내리는 것이 자연스럽습니다. 그런데 같은 저장소의 README를 끝까지 읽으면 상황이 상당히 달라집니다.
이 글은 그 문서를 처음부터 끝까지 읽고 저자가 스스로 그은 경계선을 정확히 옮기는 것부터 시작합니다. 그 다음에, 이 연구에서 정작 일반화되는 것이 무엇인지 다룹니다.
먼저 날짜를 밝혀 둡니다. 이 저장소는 GitHub API 기준 2018년 8월 9일에 생성되었고 마지막 커밋은 2018년 10월 12일입니다. 2026년의 새 발표가 아니라 2018년 연구입니다. 같은 저자가 2026년 8월에 다른 저장소들을 새로 올리면서 프로필 전체가 함께 주목받은 것으로 보입니다.
rosenbridge가 실제로 무엇인가
README가 설명하는 구조는 이렇습니다.
메인 x86 코어 옆에 작은 비x86 코어가 하나 더 들어 있습니다. 이 코어는 모델 특화 레지스터의 제어 비트로 활성화되고, 그 뒤에 "launch-instruction"이라 부르는 명령어로 전환됩니다. 전환된 뒤에는 특별한 형식의 x86 명령어에 감싸인 명령들을 받아 실행하는데, 저자는 이 명령 집합을 DEIS(deeply embedded instruction set)라 부릅니다.
이 코어가 실행하는 명령은 모든 메모리 보호와 특권 검사를 우회합니다. 그래서 링 3, 즉 일반 사용자 프로그램이 링 0의 커널 데이터를 자유롭게 읽고 쓸 수 있게 됩니다.
원래대로라면 이 기능을 켜는 데 커널 권한이 필요합니다. 그런데 README는 일부 시스템에서 기본적으로 활성화된 채로 관찰되었다고 적습니다. 그 경우 권한 없는 코드가 곧바로 커널을 수정할 수 있습니다.
여기까지가 확인된 메커니즘입니다. 저장소에는 이를 뒷받침하는 도구들이 함께 있습니다. DEIS용 어셈블러, 권한 상승 개념 증명, MSR을 통해 백도어를 닫는 부팅 스크립트, 그리고 연구에 쓰인 퍼저들입니다.
저자가 직접 그은 네 개의 경계선
README에는 이 발견의 범위를 좁히는 문장이 여러 개 있습니다. 인용할 가치가 있습니다.
첫째, 영향 범위. "이 문제의 영향을 받는 것은 VIA C3 CPU뿐인 것으로 여겨진다." VIA의 C 시리즈는 산업 자동화, POS, ATM, 의료 하드웨어와 일부 소비자용 데스크톱·노트북을 대상으로 판매되었습니다.
둘째, 세대. "이 취약점의 범위는 제한적이다. C3 이후 세대의 CPU에는 더 이상 이 기능이 없다."
셋째, 의도. 면책 조항에 이렇게 적혀 있습니다. VIA 프로세서는 저전력과 임베디드 설계에서의 우수성으로 알려져 있으며, 여기서 설명한 기능은 임베디드 시장을 위한 유용한 기능으로 선의로 만들어졌고 초기 일부 세대에서 의도치 않게 활성화된 채 남은 것으로 본다는 것입니다. 그리고 "악의를 함의하지 않는다"고 명시합니다.
넷째, 도구의 한계. 확인 도구는 알파 상태이며 베어메탈에서만 실행해야 하고, "백도어가 없는 시스템을 크래시시키거나 커널 패닉을 일으키거나 멈추게 할 수 있다"고 경고합니다. 그리고 결정적으로, 이 도구들은 특정 프로세서 계열과 코어를 전제로 설계되었으므로 연구된 형태에서 조금이라도 변형된 백도어는 놓친다고 적습니다.
저자 본인은 이 작업의 성격을 이렇게 규정합니다. "점점 복잡해지는 프로세서에서 백도어가 어떻게 생겨날 수 있는지, 그리고 연구자와 최종 사용자가 그런 기능을 어떻게 식별할 수 있는지 보여 주는 사례 연구이자 사고 실험으로 공개한다."
이 네 가지를 빼고 제목만 유통시키는 것이 이 연구를 부정확하게 만드는 가장 흔한 방식입니다.
왜 ME나 PSP와 구분해서 이야기해야 하나
README에 흥미로운 비교가 있습니다. rosenbridge는 Intel Management Engine이나 AMD Platform Security Processor 같은 공개적으로 알려진 x86 보조 프로세서들과 완전히 별개이며, 알려진 어떤 보조 프로세서보다 더 깊이 임베드되어 있다는 것입니다. CPU의 모든 메모리뿐 아니라 레지스터 파일과 실행 파이프라인에까지 접근할 수 있기 때문입니다.
이 구분이 중요한 이유는 위협 모델이 다르기 때문입니다.
ME나 PSP는 별도의 프로세서입니다. 자기 펌웨어를 돌리고 시스템 메모리에 접근하지만, 메인 코어의 실행 파이프라인 안에 있지는 않습니다. 대응 방법도 그에 맞습니다. 펌웨어 버전 관리, 네트워크 접근 차단, 일부 환경에서의 비활성화 시도가 논의됩니다.
rosenbridge가 설명하는 것은 다릅니다. 실행 중인 명령어 스트림 안에서 전환되고, 같은 파이프라인에서 특권 검사를 건너뜁니다. 소프트웨어 관점에서는 명령어 하나가 갑자기 다른 의미를 갖는 것에 가깝습니다.
두 가지를 "CPU 안의 숨은 코어"로 뭉뚱그리면 대응 방법도 뭉뚱그려집니다. 실제로는 완전히 다른 층위의 문제이고, 하나에 대한 대응이 다른 하나에는 전혀 통하지 않습니다.
어떻게 찾았나 — 문서 없이 명령어 집합을 탐색하는 문제
이제 이 연구에서 실제로 일반화되는 부분입니다. 어떻게 찾았는가.
x86 명령어 집합을 밖에서 탐색하는 일은 생각보다 어렵습니다. 이유가 몇 가지 있습니다.
명령어가 가변 길이입니다. 1바이트짜리도 있고 15바이트짜리도 있습니다. 그래서 "모든 명령어를 나열하라"는 요청에 대한 정답이 없습니다. 바이트 조합 공간이 천문학적이라 무작정 전수 조사할 수도 없습니다.
문서화되지 않은 명령어는 정의상 참조할 표가 없습니다. 디스어셈블러는 매뉴얼을 근거로 만들어졌으므로, 매뉴얼에 없는 것에 대해서는 디스어셈블러도 모릅니다.
그리고 잘못된 바이트를 실행하면 프로그램이 죽거나 시스템이 멈춥니다.
저자의 도구 sandsifter가 푸는 문제가 이것입니다. README 표현으로 "프로세서의 명령어 집합을 탐색하기 위해 기계어를 체계적으로 생성하고 실행을 관찰하면서 이상 현상을 감시함으로써 x86 프로세서의 숨겨진 명령어와 하드웨어 버그를 감사"합니다.
핵심은 불일치를 찾는 것입니다. 프로세서가 실제로 어떻게 해석하는지와 참조 디스어셈블러가 어떻게 해석하는지를 비교해서, 두 답이 갈리는 지점을 모읍니다. 사람이 매뉴얼을 읽고 추측하는 것이 아니라, 기계 두 대의 의견 차이를 자동으로 수집하는 방식입니다.
sandsifter 스캔이 실제로 찾아내는 것
이 도구의 결과 설명이 현실적이라 인용할 만합니다.
기본 감사는 이렇게 실행합니다.
sudo ./sifter.py --unk --dis --len --sync --tick -- -P1 -t
README에 따르면 스캔은 프로세서의 속도와 복잡도에 따라 몇 시간에서 며칠이 걸립니다. 끝나면 요약 도구를 돌립니다.
./summarize.py data/log
그리고 여기가 중요한데, README는 이렇게 적습니다. "일반적으로 여러분의 프로세서에서 수백만 개의 문서화되지 않은 명령어가 발견될 것이지만, 이들은 대체로 소수의 그룹으로 묶인다."
수백만 개라는 숫자에 놀랄 필요가 없다는 뜻입니다. 요약 도구는 이상 현상을 묶은 뒤 세 가지 범주로 분류를 시도합니다.
- 소프트웨어 버그 — 하이퍼바이저나 디스어셈블러의 버그
- 하드웨어 버그 — CPU 자체의 버그
- 문서화되지 않은 명령어 — 프로세서에 존재하지만 제조사가 인정하지 않는 명령어
README는 자동 분류가 어려운 경우가 있어 수동 분석이 필요할 수 있다고도 명시합니다.
성과 목록도 그대로 옮깁니다. 이 도구는 "모든 주요 벤더의 비밀 프로세서 명령어, 디스어셈블러와 어셈블러와 에뮬레이터에 광범위하게 존재하는 소프트웨어 버그, 엔터프라이즈 하이퍼바이저의 결함, 그리고 x86 칩의 양성 및 보안상 중대한 하드웨어 버그"를 찾아냈다고 적혀 있습니다.
방법은 일반화되지만 발견은 일반화되지 않는다
이 두 문장을 나란히 두면 이 연구를 어떻게 다뤄야 하는지가 분명해집니다.
발견은 좁습니다. VIA C3, 2018년, 이후 세대에는 없음, 악의 없음으로 추정. 오늘 여러분의 노트북이나 서버 CPU에 이것이 있을 가능성은 사실상 없습니다. VIA C3가 들어간 산업 장비를 아직 운용하고 있다면 이야기가 다르지만, 그런 경우라면 이미 다른 이유로도 교체 대상일 것입니다.
방법은 넓습니다. "문서가 없는 인터페이스를 상대할 때, 두 개의 독립적인 해석기를 놓고 의견이 갈리는 지점을 자동으로 수집한다"는 접근은 프로세서에만 쓰이는 것이 아닙니다.
같은 구조가 이런 곳에도 적용됩니다.
- 파서 두 개가 같은 입력을 다르게 해석하는 지점 찾기(요청 밀수와 역직렬화 취약점의 원천입니다)
- 클라이언트와 서버가 같은 프로토콜 메시지를 다르게 해석하는 지점 찾기
- 컴파일러와 인터프리터가 같은 소스를 다르게 처리하는 지점 찾기
- 두 개의 다른 구현체를 같은 입력으로 돌려 결과를 비교하는 차등 퍼징 일반
최근 사례로는 PostgreSQL을 Rust로 재구현한 pgrust 프로젝트가 있습니다. 원본과 재구현을 같은 입력으로 돌려 동작이 갈리는 지점을 찾는 방식으로, 저장소 문서에 따르면 그 과정에서 원본 PostgreSQL 쪽의 버그까지 발견했다고 합니다. 참조 구현이 있다는 것은 무료 오라클이 있다는 뜻이고, 이건 퍼징에서 가장 값진 자산입니다.
실무자가 여기서 가져갈 것
정리하겠습니다.
첫째, 저장소 설명과 README 본문의 범위가 다를 수 있습니다. 보안 연구에서 제목은 발견의 범주를 말하고 본문은 발견의 범위를 말합니다. 인용할 때는 본문 쪽을 인용해야 합니다.
둘째, 연구자 본인이 붙인 단서를 지우지 마세요. rosenbridge의 면책 조항은 저자가 스스로 "악의를 함의하지 않는다"고 쓴 것입니다. 그 문장을 빼고 인용하는 것은 연구자가 하지 않은 주장을 대신 하는 일입니다.
셋째, 도구의 검출 한계를 함께 읽으세요. rosenbridge 확인 도구는 "연구된 형태에서 조금이라도 변형되면 놓친다"고 명시합니다. 이건 이 도구만의 문제가 아니라 시그니처 기반 탐지 전반의 성질입니다. 여러분이 쓰는 스캐너도 같은 한계를 갖고 있고, 대개 그렇게 명시하지 않습니다.
넷째, 완화 조치의 유효 범위를 확인하세요. README는 부팅 시점에 MSR을 조작해 백도어를 닫는 스크립트를 제공하면서, "이것을 적용해도 커널 권한을 가진 공격자는 다시 켤 수 있다"고 적습니다. 대부분의 완화는 이런 형태입니다. 특정 공격자 능력 아래에서만 유효하며, 그 능력 이상에서는 무효입니다. 어떤 위협 모델에서 유효한지 모르면 그 완화가 여러분에게 유효한지도 알 수 없습니다.
하드웨어 신뢰 문제는 진짜 문제이고, 이런 연구는 그 문제를 논의 가능한 형태로 만들어 줍니다. 그래서 더더욱 정확하게 인용할 가치가 있습니다.
참고 자료
- xoreaxeaxeax/rosenbridge — GitHub (2018년 8월 생성, 2018년 10월 마지막 커밋. 본문 인용은 전부 README에서 옮긴 것입니다)
- xoreaxeaxeax/sandsifter — the x86 processor fuzzer
- Breaking the x86 ISA — Christopher Domas 백서 (sandsifter 저장소 내)
저는 rosenbridge 확인 도구나 sandsifter 스캔을 직접 실행하지 않았습니다. 두 도구 모두 베어메탈 실행을 요구하고 시스템을 멈추게 할 수 있다고 경고하고 있습니다. 본문의 동작 설명은 전부 저장소 문서에 적힌 내용입니다.
The Exact Scope of the Phrase x86 Hardware Backdoor — Reading rosenbridge as Its Author Wrote It
- Introduction — the distance between the title and the body
- What rosenbridge actually is
- The four boundaries the author drew himself
- Why it has to be discussed separately from ME and PSP
- How it was found — the problem of exploring an instruction set with no documentation
- What a sandsifter scan actually turns up
- The method generalizes; the finding does not
- What a practitioner takes away from this
- References
Introduction — the distance between the title and the body
There is a GitHub repository called xoreaxeaxeax/rosenbridge. Its description is one line: "Hardware backdoors in x86 CPUs." It has more than 2,500 stars and periodically climbs back to the top of the community feed.
Concluding from that title alone that "my CPU has a backdoor" is natural. Yet read the README of that same repository to the end and the situation looks considerably different.
This post starts by reading that document from beginning to end and carrying over exactly the boundary the author drew for himself. After that, it turns to what actually generalizes out of this research.
Let me state the dates first. This repository was created on 9 August 2018 according to the GitHub API, and the last commit is 12 October 2018. This is not a new 2026 announcement; it is 2018 research. It appears the whole profile drew attention again when the same author put up other repositories in August 2026.
What rosenbridge actually is
The structure the README describes is this.
Alongside the main x86 core there is one more small non-x86 core. This core is enabled by a control bit in a model specific register, and after that you switch into it with an instruction called the "launch-instruction." Once switched, it takes and executes commands wrapped inside specially formatted x86 instructions, and the author calls this command set DEIS (deeply embedded instruction set).
The instructions this core executes bypass all memory protection and privilege checks. So ring 3, that is an ordinary user program, can freely read and write ring 0 kernel data.
Normally, enabling this feature requires kernel privileges. But the README writes that on some systems it was observed to be enabled by default. In that case unprivileged code can modify the kernel directly.
That much is the confirmed mechanism. The repository also carries tools that support it: an assembler for DEIS, a privilege escalation proof of concept, a boot script that closes the backdoor through an MSR, and the fuzzers used in the research.
The four boundaries the author drew himself
The README has several sentences that narrow the scope of this finding. They are worth quoting.
First, the scope of impact. "It is believed that only VIA C3 CPUs are affected by this issue." VIA's C series was sold for industrial automation, POS, ATMs, medical hardware, and some consumer desktops and laptops.
Second, generations. "The scope of this vulnerability is limited. CPUs of generations after the C3 no longer have this feature."
Third, intent. The disclaimer says this. VIA processors are known for their excellence in low-power and embedded designs, and the feature described here is regarded as having been built in good faith as a useful feature for the embedded market and left unintentionally enabled in some early generations. And it states explicitly that "no malice is implied."
Fourth, the limits of the tooling. The checking tool is in alpha, must be run only on bare metal, and warns that it "may crash, kernel panic, or hang a system that does not have the backdoor." And decisively, it writes that because these tools were designed on the assumption of a specific processor family and core, any backdoor even slightly varied from the form studied will be missed.
The author himself defines the character of this work like this: it is published as a case study and a thought experiment showing how backdoors can arise in increasingly complex processors, and how researchers and end users might identify such features.
Dropping these four things and circulating only the title is the most common way this research is made inaccurate.
Why it has to be discussed separately from ME and PSP
There is an interesting comparison in the README. rosenbridge is entirely separate from publicly known x86 coprocessors such as the Intel Management Engine or the AMD Platform Security Processor, and is more deeply embedded than any known coprocessor. That is because it can access not only all of the CPU memory but the register file and the execution pipeline as well.
This distinction matters because the threat model is different.
ME and PSP are separate processors. They run their own firmware and access system memory, but they are not inside the main core's execution pipeline. The responses match that. Firmware version management, blocking network access, and attempts at disabling it in some environments are what get discussed.
What rosenbridge describes is different. It is switched into from within the running instruction stream and skips privilege checks in the same pipeline. From a software point of view it is closer to a single instruction suddenly meaning something else.
Lump the two together as "a hidden core inside the CPU" and the responses get lumped together too. In reality they are problems at completely different layers, and a response to one does not work at all on the other.
How it was found — the problem of exploring an instruction set with no documentation
Now for the part of this research that actually generalizes. How it was found.
Exploring the x86 instruction set from the outside is harder than it sounds. There are a few reasons.
Instructions are variable length. Some are one byte, some are fifteen. So there is no correct answer to the request "enumerate every instruction." The byte combination space is astronomical, so you cannot brute-force your way through it either.
An undocumented instruction by definition has no table to consult. Disassemblers are built on the manual, so about things not in the manual the disassembler knows nothing either.
And executing the wrong bytes kills the program or hangs the system.
That is the problem the author's tool sandsifter solves. In the README wording, it "audits x86 processors for hidden instructions and hardware bugs, by systematically generating machine code to search through a processor's instruction set, and monitoring execution for anomalies."
The core is finding disagreement. It compares how the processor actually interprets something against how a reference disassembler interprets it, and collects the places where the two answers diverge. Rather than a human reading the manual and guessing, it is an automatic collection of the differences of opinion between two machines.
What a sandsifter scan actually turns up
The description of this tool's results is realistic enough to be worth quoting.
The basic audit is run like this.
sudo ./sifter.py --unk --dis --len --sync --tick -- -P1 -t
According to the README, a scan takes hours to days depending on the speed and complexity of the processor. When it finishes you run the summarizing tool.
./summarize.py data/log
And here is the important part. The README writes: "typically millions of undocumented instructions will be found on your processor, but these generally group into a small number of groups."
Which means there is no need to be alarmed by the number in the millions. The summarizing tool groups the anomalies and then attempts to classify them into three categories.
- Software bugs — bugs in a hypervisor or a disassembler
- Hardware bugs — bugs in the CPU itself
- Undocumented instructions — instructions that exist in the processor but are not acknowledged by the manufacturer
The README also states explicitly that automatic classification is sometimes difficult and manual analysis may be required.
The list of achievements gets carried over as well. The tool is said to have found "secret processor instructions from every major vendor, software bugs pervasive across disassemblers, assemblers, and emulators, flaws in enterprise hypervisors, and both benign and security-critical hardware bugs in x86 chips."
The method generalizes; the finding does not
Put those two together and how this research should be handled becomes clear.
The finding is narrow. VIA C3, 2018, absent from later generations, presumed no malice. The likelihood that your laptop or server CPU has this today is effectively nil. It is a different story if you are still operating industrial equipment containing a VIA C3, but in that case it is probably already due for replacement for other reasons anyway.
The method is wide. The approach of "when facing an interface with no documentation, put two independent interpreters side by side and automatically collect the places where they disagree" is not used only on processors.
The same structure applies in places like these.
- Finding the places where two parsers interpret the same input differently (this is the origin of request smuggling and deserialization vulnerabilities)
- Finding the places where a client and a server interpret the same protocol message differently
- Finding the places where a compiler and an interpreter handle the same source differently
- Differential fuzzing in general: running two different implementations on the same input and comparing the results
A recent example is the pgrust project, which reimplements PostgreSQL in Rust. By running the original and the reimplementation on the same input and finding where the behavior diverges, it reportedly even found bugs on the original PostgreSQL side, according to the repository documentation. Having a reference implementation means having a free oracle, and that is the most valuable asset there is in fuzzing.
What a practitioner takes away from this
Let me sum up.
First, the repository description and the body of the README can differ in scope. In security research, the title states the category of the finding and the body states the scope of the finding. When you quote, you should quote the body.
Second, do not delete the qualifications the researcher attached. The rosenbridge disclaimer is the author writing, in his own words, that "no malice is implied." Quoting it with that sentence removed means making a claim on the researcher's behalf that he did not make.
Third, read the detection limits of the tool alongside it. The rosenbridge checking tool states explicitly that it "will miss anything even slightly varied from the form studied." That is not a problem unique to this tool but a property of signature-based detection in general. The scanner you use has the same limitation, and it usually does not say so.
Fourth, check the effective scope of a mitigation. The README offers a script that manipulates an MSR at boot to close the backdoor, while noting that "even with this applied, an attacker with kernel privileges can turn it back on." Most mitigations are of this form. They are effective only under a specific attacker capability, and above that capability they are void. If you do not know which threat model a mitigation is effective in, you cannot know whether it is effective for you.
Hardware trust is a real problem, and research like this makes that problem discussable. Which is all the more reason it is worth quoting accurately.
References
- xoreaxeaxeax/rosenbridge — GitHub (created August 2018, last commit October 2018. Every quotation in this post is carried over from the README)
- xoreaxeaxeax/sandsifter — the x86 processor fuzzer
- Breaking the x86 ISA — Christopher Domas white paper, inside the sandsifter repository
I did not run the rosenbridge checking tool or a sandsifter scan myself. Both tools require bare-metal execution and warn that they can hang a system. The behavioral descriptions in this post are entirely what is written in the repository documentation.