Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2020-1349 — MIME 헤더 파싱 버그를 사용하여 힙 오버플로 및 vftable 덮어쓰기를 통한 EIP 제어를 달성하는 Outlook 2019 제로클릭 취약점 CVE-2020-1349용 익스플로잇. | Kitploit
도구/GitHubGitHub/0neb1n/cve-2020-1349
Vulnerability AnalysisExploitationShellcodeEmail SecurityBinary Exploitation
GitHub0neb1n/cve-2020-1349

CVE-2020-1349

MIME 헤더 파싱 버그를 사용하여 힙 오버플로 및 vftable 덮어쓰기를 통한 EIP 제어를 달성하는 Outlook 2019 제로클릭 취약점 CVE-2020-1349용 익스플로잇.

저장소 보기
114516년 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2020-1349

해당 취약점은 한글 Windows 10 1909 x64, 코드페이지 949에 설치된 Outlook 2019 (16.0.12624.20424)에서 발생합니다.

TLDR;

ex_screen

이 취약점을 이용해 ASLR을 우회하지는 못했지만, 부팅 시 고정되는 시스템 라이브러리의 주소를 사용하여 계산기를 띄우는 Outlook 2019 32비트 익스플로잇을 작성했습니다. 또한 이 취약점은 제로 클릭 취약점입니다. "outlook.com" 계정 이외의 메일 서비스 계정이 IMAP을 사용하여 Outlook 2019와 연결되어 있으면 메일 수신만으로 트리거됩니다.

첫 번째 버그

root@kitploit:~
                v26 = IsDBCSLeadByte(*v13);
                v12 = 0;
                if ( v26 )
                {
                  LODWORD(v5) = v5 - 1;
                  *v11++ = *v13++;
                  --v8;
                }
                LODWORD(v5) = v5 - 1;
                *v11++ = *v13++;
                --v8;
                goto LABEL_51;

[OUTLMIME!CloseAllSockets+0x50804 의사 코드]

크래시가 발생하며 취약점이 존재하는 부분은 위와 같습니다. 파싱된 To 헤더 또는 From 헤더의 문자열이 멀티바이트일 때, 파싱할 남은 문자열을 카운트하는 변수가 2만큼 감소하고, 변수가 1일 때 2만큼 감소하면서 정수 언더플로우가 발생합니다.

두 번째 버그

root@kitploit:~
          if ( v23 != '=' )
          {
            if ( v23 == 34 )
              v15 = 6;
            goto LABEL_48;
          }
          v15 = 1;
        }
        if ( v15 )
          goto LABEL_40;

[OUTLMIME!CloseAllSockets+0x50804 의사 코드]

root@kitploit:~
LABEL_40:
                v24 = v13[v14];
                if ( v24 )
                {
                  if ( v5 == v14 )
                    goto LABEL_52;
                  if ( v8 != v14 )
                  {
                    v25 = IsDBCSLeadByte(v24);
                    v12 = 0;
                    if ( v25 )
                      ++v14;
                    ++v14;
                  }
                }
                goto LABEL_51;
              }

[OUTLMIME!CloseAllSockets+0x50804 의사 코드]

root@kitploit:~
LABEL_51:
        if ( v5 <= v14 )
          goto EXIT_0;
      }

[OUTLMIME!CloseAllSockets+0x50804 의사 코드]

root@kitploit:~
if ( v15 )
        {
          if ( v15 == 1 )
          {
            v15 = 2;
            v21 = v13[v14];
            v22 = v14 + 1;
            if ( v21 != '?' )
              v22 = v14;
            if ( v21 != '?' )
              v15 = v12;
            v14 = v22;
          }

[OUTLMIME!CloseAllSockets+0x50804 의사 코드]

root@kitploit:~
else if ( v15 > 1 )
          {
            if ( v15 <= 3 )
            {
              v18 = v13[v14];
              v19 = v14 + 1;
              if ( v18 != '?' )
                v19 = v14;
              v14 = v19;
              v20 = v15 + 1;
              if ( v18 != '?' )
                v20 = v15;
              v15 = v20;
            }

[OUTLMIME!CloseAllSockets+0x50804 의사 코드]

root@kitploit:~
if ( v15 == 4 )
              {
                if ( v13[v14] == '?' )
                  v15 = 5;
LABEL_40:
                v24 = v13[v14];
                if ( v24 )
                {
                  if ( v5 == v14 )
                    goto LABEL_52;
                  if ( v8 != v14 )
                  {
                    v25 = IsDBCSLeadByte(v24);
                    v12 = 0;
                    if ( v25 )
                      ++v14;
                    ++v14;
                  }
                }
                goto LABEL_51;
              }

[OUTLMIME!CloseAllSockets+0x50804 의사 코드]

root@kitploit:~
if ( v15 == 5 )
              {
                v16 = v14;
                v17 = v14 + 1;
                v30 = v13[v16];
                if ( v30 == '=' )
                {
                  *v11++ = 34;
                  --v8;
                }
                memcpy(v11, v13, v17);
                v13 += v17;
                v11 += v17;
                LODWORD(v5) = v5 - v17;
                v8 -= v17;
                if ( v30 == '=' )
                {
                  *v11++ = 34;
                  --v8;
                }
                v12 = 0;
                v14 = 0;
                v15 = 0;
                goto LABEL_51;
              }

[OUTLMIME!CloseAllSockets+0x50804 의사 코드]

root@kitploit:~
else
        {
          v23 = v13[v14];
          if ( v23 != '=' )
          {
            if ( v23 == '"' )
              v15 = 6;
            goto LABEL_48;
          }
          v15 = 1;
        }
        if ( v15 )
          goto LABEL_40;

[OUTLMIME!CloseAllSockets+0x50804 의사 코드]

root@kitploit:~
LABEL_48:
                v26 = IsDBCSLeadByte(*v13);
                v12 = 0;
                if ( v26 )
                {
                  LODWORD(v5) = v5 - 1;
                  *v11++ = *v13++;
                  --v8;
                }
                LODWORD(v5) = v5 - 1;
                *v11++ = *v13++;
                --v8;
                goto LABEL_51;

[OUTLMIME!CloseAllSockets+0x50804 의사 코드]

그러나 위 버그를 이용해 힙 오버플로우를 트리거할 때, 다시 루프를 빠져나오는 조건을 만족시킬 수 없어 원하는 만큼 부분 덮어쓰기를 수행할 수 없었습니다. 따라서 루프를 빠져나오는 특정 조건을 만족하는 입력을 찾아야 했습니다. 위와 같은 이유로 주변 코드 부분을 엄격하게 감사한 결과, 루프를 빠져나올 수 있는 입력값을 찾는 대신 특수 문자열을 처리할 때 인덱스 증가나 쓰기 없이 무한 루프에 빠지는 버그를 발견했습니다.

EIP 제어

ex_screen

힙 스프레이와 힙 펑수이를 수행한 후, 위 버그를 이용해 무한 루프에 걸리지 않은 다른 스레드에서 실행 중인 객체의 vftable을 덮어씀으로써 EIP 하이재킹에 성공했습니다.

도구 다운로드