
CVE-2018-16858 exploit implementation
This post will cover how to use a simple program flaw to open a backdoor in the system that runs that program.
The flaw in question is defined in CVE-2018-16858 belonging to the LibreOffice office suite. This flaw, in a specially crafted file, achieves directory traversal, allowing the execution of Python code. Such execution is linked or triggered by the user's action on the document, and takes place without any warning to the user about macro execution.
This document is divided into five parts. The first part will explain the flaw itself, how to unpack an OpenDocument, how to modify its structure so it executes the desired local script, and how to repack the document for execution and testing.
The second part will cover how to use local execution to launch any command on the system where the document is opened, and we will generate a backdoor that allows remote command execution.
The third part will automate the process to generate documents that create backdoors with direct or reverse communication, specifying the IP address and port to connect to.
The fourth part will deal with integrating the flaw into the metasploit system so that, using msfconsole, documents compatible with metasploit's exploitation method can be generated. This will allow choosing any payload defined in the metasploit suite as the code to execute.
The fifth and final part will show how to integrate into an antivirus system the detection process that identifies LibreOffice files infected through the previous procedure. The detection format of the ClamAV antivirus will be used, allowing a better understanding of the detection process that antivirus software uses and thus facilitating our protection against threats of this type.
All the process will be carried out for Debian-based Linux systems, but what is explained here can be extrapolated to other systems, as it is described in detail. Both the flaw and the proof-of-concept from the original CVE were made for the Windows version of LibreOffice, so you can always refer to that source to use what is described in this document analogously for Windows versions.
LibreOffice (and, for genetic reasons, Apache OpenOffice) has a flaw in versions prior to its latest version (6.1.5) that allows the execution of Python code located anywhere on the computer without the user being warned about macro execution.
To see the flaw in action, we can generate a new document in the text editor where we will write something, select it, and create a hyperlink. To create a hyperlink in the text, select the Insert menu and within it the Hyperlink option (it can also be achieved by selecting the text and then using the key combination Ctrl+K).
The following dialog will appear:

To define a hyperlink, we must insert a URL and click Apply. Apart from the URL option at the bottom of the dialog box, where you can read Further Settings, we will have a button with the Play icon that will also allow us to link events to certain actions. That is where we define that we want to execute Python code as an action.
When clicking that button, a new dialog will open:

In it we can select between three basic events and the script to be used. As the event we will select Mouse Over Object and as the script, within the scripts of the LibreOffice Macros family, we will select Python Samples. Within that option there is only one default script called TableSample, which we will select.
Once this is done, if we move the mouse over the text we have turned into a hyperlink, we will see that a window opens with a document containing a table. This means we have linked the mouse over event to the Python script. What we intend is to replace this action with another one of our own.
To do this, we will save the document we have created and exit LibreOffice to execute a series of commands in the console.
The ODT document format is nothing more than a zip with a series of files inside it (the Microsoft Office DOCX format is very similar). Therefore, the first thing we will do is decompress the file with a zip decompressor.
In our case we will use the command line tool called unzip, so we will simply execute the following command:
user@host:~/Documents/prueba$ unzip ~/Documents/blog/exploitlibreoffice/doc/CV.odt
With this we will see the files that actually make up an OpenDocument type file. The most relevant for us will be the mimetype file, the content.xml file, and the styles.xml file.
The mimetype file must be the first to appear in the list of files in the zip, so when we repack the files we must force our packager to do so, otherwise the file will not be interpreted as an OpenDocument.
The content.xml file contains the text of the document we have written, where we have text mixed with certain tags that specify how the text should be displayed.
For example, in the following line:
<text:p text:style-name="_5f_ECV_5f_SectionDetails">Indicar lista de documentos adjuntos a su CV. Ejemplos:</text:p>
You can see an example of a text paragraph written with a specific style defined by the text:style-name attribute. The text paragraph is between the opening tag text:p and the closing tag </text:p>.
The script associated with the hyperlink we created can also be seen quite simply. If we search the content.xml text for the word python or the name of the python script we loaded, in our case TableSample.py, we can easily find the line where we need to change the content:
<script:event-listener script:language="ooo:script" script:event-name="dom:mouseover" xlink:href="vnd.sun.star.script:pythonSamples|TableSample.py$createTable?language=Python&location=share" xlink:type="simple"/>
In this line is the path of the python script that will be executed when we put the mouse over the hyperlink called TableSample.py and the function that will be executed from the python code, in this case createTable.
The inherent problem with LibreOffice is that when reading documents, the value of the python code to be loaded is not properly sanitized. The program does not sanitize the ../ characters from the file path, so you can access any file on the system where the document is opened. Furthermore, if that file is a python code file, we can execute any function defined in that file.
As a first proof of concept, we will make it so that when hovering over the hyperlink, the calculator is executed, in our case the galculator program opens the calculator. We need to generate a python program that allows executing a command inside a function, in the style LibreOffice expects. To do this, we will generate the following code in the path /tmp/prueba.py:
import os;
def ejecuta():
os.system("galculator");
With this small code we will achieve our purpose. Now we just need to add both the python file /tmp/prueba.py and the function name ejecuta in the call made in the odt file. So the line that made the python call would look like this:
<script:event-listener script:language="ooo:script" script:event-name="dom:mouseover" xlink:href="vnd.sun.star.script:pythonSamples|../../../../../../../../../../../tmp/prueba.py$ejecuta?language=Python&location=share" xlink:type="simple"/>
As you can see, what we have done is add a large number of ../ to ensure we climb up to the root of our filesystem. And from there we add the specific path to our python file (prueba.py). After the $ we have added the word ejecuta, which is the function that loads the calculator.