• 主页
所有文章 友链 关于我

  • 主页

Adobe Reader CVE-2021-21017简要分析

2021-09-30

对cve-2021-21017的简要分析

cve-2021-21017是Adobe Reader在2021年2月份爆出的一个远程代码执行漏洞,网上也有其相关的poc,本文就自己的个人理解对其进行简要的分析,具体的漏洞利用代码可以在参考链接中找到

漏洞分析

该漏洞是在处理拼接url字符串的时候出现的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// Acrobat Reader DC version: 20.9.20063 IA32.api
LPSTR __cdecl sub_25819241(LPSTR base_url, LPCSTR relative_url)
{
int v2; // eax
LPCSTR v3; // edx
CHAR *v4; // ecx
CHAR v5; // al
CHAR v6; // bl
int pExceptionObject; // [esp+10h] [ebp-4h] BYREF

if ( !base_url || !relative_url )
{
(*(void (__thiscall **)(_DWORD, int))(dword_2582409C + 4))(*(_DWORD *)(dword_2582409C + 4), 1073741827);
pExceptionObject = 0;
CxxThrowException(&pExceptionObject, (_ThrowInfo *)&_TI1H);
}
if ( *base_url == (CHAR)'\xFE' && base_url[1] == (CHAR)'\xFF' )
{
v2 = strlen_unicode(base_url);
v3 = relative_url + 2;
v4 = &base_url[v2];
do
{
do
{
v5 = *v3; // v3 指向 relative_url
v3 += 2;
*v4 = v5;
v4 += 2;
v6 = *(v3 - 1);
*(v4 - 1) = v6;
}
while ( v5 );
}
while ( v6 ); // v5和v6要同时为\x00才会结束
}
else
{
lstrcatA(base_url, relative_url);
}
return base_url;
}

当用户在PDF文档中通过app.launchURL,document.submitForm或app.media.createPlayer传入URL的时候,如果定义了base_url,程序会对用户传入的url和base_url进行拼接;当base_url看起来是一个UTF-16BE字符串,则在执行拼接的时候,用户传入的url也会被当作UTF-16BE字符串进行处理,尽管它实际上是一个ANSI字符串。

程序在执行拼接的过程如下:

  • 对base_url和relative_url的长度进行计算,假设A=len(base_url),B=len(relative_url),这里relative_url指用户传入的url字符串
  • 计算拼接后的url的长度C = A+B+1,并分配内存
  • 对base_url和relative_url进行check,检查其是否合法
  • 通过上面的函数对他们进行拼接

问题出在最后一步,当relative_url被当作UTF-16BE字符串进行处理的时候,函数需要检测到\x00\x00才认为该字符串结束了,而relative_url原本是ANSI字符串,末尾就只有一个\x00,如果relative_url后续的内存中还有内容,就会继续进行处理,第二步分配的长度为C的内存就会不够用,导致堆溢出。

漏洞利用

在前面的漏洞分析中,我们有了堆溢出的能力,而且是字符串拼接导致的堆溢出,所以溢出的内容是我们可控的,这意味着我们可以修改相邻的js对象,这里给出一种利用思路:

  • 在pdf文档中设置base_url,长度记为A

  • 利用大小为C-0X10(ArrayBuffer的头部有0x10个字节)的ArrayBuffer对象进行堆喷射

  • 利用大小为B的字符串对象进行堆喷射

  • 触发漏洞,堆溢出修改相邻的ArrayBuffer的byte_length

  • 利用上一步的ArrayBuffer把高地址的相邻的另一个ArrayBuffer的size改为0xffffffff,这样我们就有了任意地址读写的能力了

这里有两个注意点:第3步中的字符串长度要满足B = C - A -1,加一减一好像都行,以具体调试为准;第4步中要注意的是传入的relative_url的长度要与第3步的字符串长度相同,这样才能使得relative_url后续的内存是我们堆喷射使用的字符串

漏洞利用稳定性的提高

一开始写出来的漏洞利用脚本成功率才30%-40%左右,后续在不断的尝试中改进,最后达到了60%-70%左右

这里是改进的几个点:

  • 堆喷射的大小的选择

这个很影响成功率,需要调试来确定,要选择Adobe Reader DC运行的时候不会申请到的大小

  • 扩大内存搜索范围

在内存中靠magic number 0xf0e0d0c0来搜索堆地址的时候,可以适当的扩大内存的搜索范围,以便能找到

  • 在修改ArrayBuffer的byte_length的时候,要验证清楚是否是一个真正的ArrayBuffer

这里我靠的是在每个ArrayBuffer的开头设置好两个magic number,个数看个人,能确定是一个以分配的ArrayBuffer就行

闲谈

Adobe Reader DC以前也爆出过类似的和这个一模一样的漏洞,就是触发方式不一样,只能说Adobe Reader DC这个漏洞修的也不是很完美,总是修了一个而忘记了另一个

而且这个漏洞当时没修好,直接可以绕过,一直到9月14号的更新中才被修补

参考链接

  • https://github.com/ZeusBox/CVE-2021-21017
  • https://blog.exodusintel.com/2021/10/04/analysis-of-a-heap-buffer-overflow-vulnerability-in-adobe-acrobat-reader-dc-2/
  • https://conference.hitb.org/hitblockdown/materials/WHITEPAPER%20-%20Pwning%20Adobe%20Reader%20Multiple%20Times%20with%20Malformed%20Strings%20-%20Ke%20Liu.pdf
  • https://conference.hitb.org/hitblockdown/materials/D1%20-%20Pwning%20Adobe%20Reader%20Multiple%20Times%20with%20Malformed%20Strings%20-%20Ke%20Liu.pdf

扫一扫,分享到微信

微信分享二维码
Chromium 编译相关
Adobe Reader DC调试记录
  1. 1. 漏洞分析
  2. 2. 漏洞利用
  3. 3. 漏洞利用稳定性的提高
  4. 4. 闲谈
  5. 5. 参考链接
© 2022 ruan
Hexo Theme Yilia by Litten
  • 所有文章
  • 友链
  • 关于我

tag:

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 好舍友
beginner