글
← 전체 글1-day 분석

CVE-2026-20841 분석

취약점 개요

image

https://www.zerodayinitiative.com/blog/2026/2/19/cve-2026-20841-arbitrary-code-execution-in-the-windows-notepad

해당 취약점은 Windows 메모장에서 마크다운 링크 처리 기능에서 발견된 취약점이라고 한다.

공격자가 악의적인 링크를 포함한 .md 파일을 제작하고 피해자가 해당 파일을 메모장으로 열고 클릭하면 임의 코드 실행이 가능하다고 함.

일단 취약한 버전의 노트패드를 다운로드 받아주자. https://wapt.tranquil.it/store/en/details/tis-windows-notepad_11.2507.26.0-64_x64_windows_10.0.22000_PROD.wapt

root cause 및 취약점 설명

결국 근본 원인은 링크 클릭할 때 호출되는 함수에서 필터링이 부족해서이다.

image-2

ShellExecuteExW 함수를 참조해보면 2곳에서 호출됨 sub_140061970 은 링크 클릭 경로와 관련이 없어서 제외하고 sub_140164050 을 분석해보면 ZDI 보고서에서 나온 코드와 비슷한 구조를 가진 코드가 나옴

image-3

그리고 ShellExecuteExW 구조체는 다음과 같이 생김

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef struct _SHELLEXECUTEINFOW {
    DWORD     cbSize;
    ULONG     fMask;
    HWND      hwnd;
    LPCWSTR   lpVerb;
    LPCWSTR   lpFile;
    LPCWSTR   lpParameters;
    LPCWSTR   lpDirectory;
    int       nShow;
    HINSTANCE hInstApp;
    void      *lpIDList;
    LPCWSTR   lpClass;
    HKEY      hkeyClass;
    DWORD     dwHotKey;
    HANDLE    hIcon;
    HANDLE    hProcess;
} SHELLEXECUTEINFOW;

위 구조체에서 lpFile 이 실행하거나 열 대상의 경로 또는 URI 가 들어가고 lpVerb 에서 어떤 동작을 수행할지 결정됨.
그리고 저게 왜 RCE 까지 가능하냐하면 URI 종류에 따라서 다른 행동을 한다고 했는데 https:// 면 브라우저 실행, file:// 이면 로컬 또는 네트워크 파일 열기/실행, ms-appinstaller:// 이면 등록된 앱 설치 처리기 호출 등을 함 따라서 공격자가 다음과 같이 계산기 실행이나 다른 프로그램 실행으로 이어질 수 있음

1
2
3
4
5
6
7
8
9
10
*((_DWORD *)Block + 40) = 112;
*((_DWORD *)Block + 41) = 1088;
*((_QWORD *)Block + 22) = L"open";

v16 = Block + 40;
if ( *((_QWORD *)Block + 8) > 7u )
    v16 = (_QWORD *)*v16;

*((_QWORD *)Block + 23) = v16;
v18 = ShellExecuteExW((SHELLEXECUTEINFOW *)(Block + 160));

이 코드에서 L"open"이 지정되고, 클릭한 링크의 URI가 lpFile에 들어간다. 이후 ShellExecuteExW가 그 URI를 Windows에 등록된 처리기로 전달한다. 분석한 호출 경로에서는 위험한 URI 스킴을 걸러내는 검사가 부족해 임의 코드 실행으로 이어질 수 있다.

PoC

1
2
# run executable file
[프로그램 열기](file:///C:/Windows/System32/calc.exe)
  • file:// 프로토콜 사용해서 윈도우 cmd 실행

위 내용을 담은 md 파일을 ctrl + 좌클릭 하면 다음과 같이 프로그램 실행이 가능하다.

image-4

패치

그럼 이 취약점의 패치는 어떻게 되었을까?

11.2607.14.0 에서는 셸 실행 전에 URI 스킴을 먼저 확인한다.
https, http, mailto 가 허용되어 있고 file Scheme 은 파일 경로로 변환해서 별도로 처리되도록 패치되었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
auto scheme = GetSchemeName(CreateUri(clickedLink));

if (scheme == L"https" ||
    scheme == L"http"  ||
    scheme == L"mailto") {

    // 셸 실행 보조 함수에서 허용 목록을 다시 확인
    OpenAllowedLink(clickedLink);
} else if (scheme == L"file") {
    auto path = PathCreateFromUrl(clickedLink);
    HandleAsFilePath(path);  // 조건에 따라 텍스트로 열기 안내
} else {
    ShowUnsupportedLinkMessage();
}

별도로 file 링크 검사 로직이 추가되고 허용되는 Scheme 도 검사함으로써 패치되었음.

시나리오

음… 도저히 생각이 안났는데 다음 게시물을 발견함

원격 파일에 접근 가능한 점을 활용하여 공격자가 운영하는 WebDAV 또는 SMB서버에 malicious.py 를 올려놓고 해당 파일을 가리키는 file:// 스킴을 md 파일에 만들어서 클릭을 유도하고 .py 확장자에 연결된 프로그램으로 파일을 열게 유도해서 코드 실행까지 가능하다고 함.

단, 피해자 PC에 Python이 설치되어 있어야 하고, .py 파일 연결이 스크립트를 실행하도록 설정되어 있어야 함.
또한 Windows 보안 정책에 따라 실행이 차단되거나 경고가 표시될 수 있다.