CVE-2022-24125 및 CVE-2022-24126에 대한 문서 및 개념 증명 코드
2022/08/25에 다크 소울 III의 새로운 게임 업데이트 1.15.1이 출시되었으며, 온라인 서비스가 복구되었습니다. 이 업데이트는 CVE-2022-24125 및 CVE-2022-24126을 수정했으며, 게임 P2P 네트워킹에 존재하는 다양한 기타 잠재적 보안 취약점(OOB 읽기/쓰기)도 함께 수정되었습니다. 또한, 다른 플레이어의 세이브를 손상시킬 수 있는 알려진 모든 익스플로잇이 수정되었습니다. 온라인 멀티플레이에서 자주 마주칠 수 있는 많은 사소한 치트(예: "저주 칼")도 패치되었습니다.
이 저장소는 FROM SOFTWARE 게임에 영향을 미치는 가장 최근 RCE 익스플로잇인 CVE-2022-24126에 대한 개념 증명 코드와 문서를 포함하고 있습니다. 이론적으로는 다른 게임에도 가능하지만, 제 연구가 수행된 게임인 다크 소울 III에 초점을 맞추고 있습니다. 현재로서는 다크 소울 III에 대한 개념 증명 코드만 존재하며, 취약점이 존재하는 것으로 확인된 게임은 다음과 같습니다:
취약한 코드는 세키로에도 존재하지만(크레딧: LukeYui), 이를 트리거할 방법은 없습니다. 데몬즈 소울에서의 존재 여부는 확인되지 않았지만 가능성이 매우 높습니다. 비공개 네트워크 테스트는 이 취약점의 영향을 받았지만, 출시 버전의 엘든 링은 그렇지 않습니다. 사실, 다크 소울 III에 존재했던 방대한 목록의 네트워크 크래시, 경계를 벗어난 읽기/쓰기, 그리고 플레이어가 동료의 게임 데이터를 수정할 수 있는 익스플로잇이 엘든 링에서는 패치되었습니다. 이 목록을 정리해준 LukeYui와 신속하게 대응한 FROM SOFTWARE에 감사드립니다! 엘든 링은 해커가 입힐 수 있는 피해 범위 측면에서 FROM SOFTWARE 타이틀 중 가장 안전하다고 단언할 수 있어 기쁩니다.
대중의 믿음과 달리, 이것은 P2P 네트워킹 익스플로잇이 아닙니다. 매치메이킹 서버와 관련이 있으므로 훨씬 더 심각합니다. 다른 매치메이킹 서버 취약점(CVE-2022-24125)으로 인해 멀티플레이 활동에 참여하지 않아도 취약해질 수 있기 때문입니다.
서버 종료 전 몇 달 동안 평균 동시 플레이어 수가 약 20,000명인 게임 특성상, 특히 엘든 링에도 존재할 가능성이 있으므로 즉시 수정이 필요한 문제임이 분명했습니다. FROM SOFTWARE가 제가 개념 증명 영상과 상세한 익스플로잇 문서(이 리드미의 상당 부분이 기반함)를 포함한 초기 보고 후 40일 이상 조치를 취하지 않았기 때문에, 개발자들이 해결하도록 주의를 끌기 위해 익스플로잇의 존재를 무해한 방식으로 공개적으로 시연하기로 결정했고, 효과가 있었습니다.
이 3개의 가젯에 대한 자세한 내용은 여기를 참조하십시오. 다른 게임에서 이 가상 호출 방법이 실현 가능한 접근 방식이 아닌 경우, 임의 코드 리디렉션을 사용하여 보다 전통적인 ROP 익스플로잇을 설정할 수도 있습니다.
개념 증명 코드를 실행하려면 먼저 연결할 서버가 필요합니다. 공식 서버는 익스플로잇으로 인해 비활성화되었지만, ds3os를 사용하여 개인 서버를 설정할 수 있습니다. ds3os는 소매 서버 동작을 최대한 가깝게 모방하도록 설계되었지만, 이 익스플로잇을 수정하기 위해 이미 보안 패치가 이 프로젝트에 배포되었습니다. 그러나 BuildConfig.h에서 SEND_MESSAGE_TO_PLAYERS_SANITY_CHECKS 및 NRSSR_SANITY_CHECKS 상수를 false로 설정하여 프로젝트를 직접 빌드함으로써 테스트 환경을 설정할 수 있습니다. 이는 안전하지 않은 소매 서버 동작을 모방합니다. ds3os에서 제공하는 지침에 따라 게임을 시작하고 서버에 연결하십시오.
이 작업이 완료되고 게임이 서버에 연결되면 PoC 코드를 빌드하고 Injector.exe 실행 파일을 시작합니다. 이 실행 파일은 다크 소울 III 프로세스에 익스플로잇 코드가 포함된 DLL을 주입합니다. 이 DLL은 FRPG 메시지를 서버로 보내는 게임 함수를 사용하여 자신의 클라이언트에 익스플로잇을 전달합니다.
함수 140ca5010은 항목 크기를 확인하지만, 140ca4fa0은 가변 크기 항목용이며 크기 필드에 대한 정합성 검사를 수행하지 않습니다(버그 #1). 위에서 설명한 임의 코드 리디렉션 익스플로잇을 달성하려면 이를 14F3B0으로 설정해야 합니다. 이로 인해 약 1.3MiB의 경계를 벗어난 읽기가 발생하지만 메모리 페이지는 액세스 위반을 피할 수 있을 만큼 커야 합니다.
140ca56b0이 함수는 이전 함수에 의해 nrssr_data를 인수로 호출됩니다. 스택에 DLMemoryInputStream 객체를 생성한 다음 NRSSR 파서에 인수로 전달합니다.
141955f50: ParseNRSessionSeachResultNRSessionSearchResult 파서입니다. NRSSR 서명 및 버전 번호를 확인하고(14196a0f0), 속성 목록(14196a260), 호스트 이름(14195603a) 및 추가 정보를 파싱합니다(rce.h 참조).
14195603a위 함수에서 호스트 이름을 안전하지 않게 복사하는 루프입니다(버그 #2). 버퍼 오버플로 중에 무슨 일이 일어나는지 추적하는 데 도움이 되는 몇 가지 주소는 다음과 같습니다:
14F128DLMemoryInputStream 스택 주소: 14F3A0DLMemoryInputStream vtable 포인터: 1439e8b30DLInputStreamReader에서 사용하는 DLMemoryInputStream의 가상 함수 오프셋: 0x181439e8b48MOV RCX,qword ptr [RCX + 0x8]
MOV RAX,qword ptr [RCX]
JMP qword ptr [RAX + 0x40]
덮어쓴 메모리 스트림 vftable로 인한 첫 번째 코드 리디렉션 후 도달하는 곳입니다. 여기서 가상 호출 리디렉션 체인이 시작됩니다.
다크 소울 III Ver. 1.15 기준. 최대 이론적 페이로드 크기는 스택 레이아웃에 따라 달라지므로 게임 및 버전에 따라 다릅니다. ↩