What Happens When You Open a File?

Most people assume that opening a document is a passive act. You're the reader. The file is inert. Nothing happens unless you click something, enable something, or agree to something. CVE-2018-16858 proves all of that wrong.

This vulnerability in LibreOffice allows an attacker to craft a document that, the moment it is opened, silently traverses the filesystem, locates a Python script in an unexpected path, and executes it — with no warnings, no prompts, and no user interaction beyond double-clicking the file.

For my Software Exploitation assessment at the University of Chester, I built a live proof-of-concept demonstrating exactly this — crafting a malicious ODT file from scratch and watching it execute arbitrary code on a victim machine the instant it was opened.

⚠️ Educational Disclaimer

All demonstrations were conducted in a sandboxed VM environment under academic supervision. The techniques here are shared strictly for educational and defensive security purposes.

How CVE-2018-16858 Works

LibreOffice documents (ODT, ODP, ODS, etc.) are ZIP archives containing XML files. One of those XML files — content.xml — defines the document body, including hyperlinks.

The flaw lies in how LibreOffice handles hyperlink URLs that reference LibreLogo scripts. When the application processes an event-driven macro URL, it fails to properly validate the file path. An attacker can supply a directory traversal sequence — using ../ patterns — to point the macro loader at any Python file on the filesystem, outside the document's expected scope.

The critical detail: this can be bound to the document's open event. No hover required. No click. Just open the file.

<text:a xlink:type="simple"
   xlink:href="macro:///LibreLogo.Logo.run(
      ../../../../../path/to/payload.py)"
   office:macro-name="...">
  Click here
</text:a>

The traversal sequence escapes LibreOffice's expected script directory and reaches any readable Python file on disk. In a real attack, the payload could be pre-staged or fetched remotely. In my demonstration, I used a simple script that made the compromise undeniable to the audience.

Building the Malicious Document

Unlike the macro-based CVE-2019-9848, this attack requires manually crafting the document's internal XML — going under the hood of the file format itself.

  1. Edit content.xml Directly in Notepad — Unzip the ODT file, open content.xml in a text editor, and inject the malicious xlink:href pointing to the traversal path.
  2. Save the Modified XML — Save the edited file back with the injected traversal payload intact.
  3. Name the File Convincingly — Rename the document — in this demo, “malicious_file” — and repackage it as a valid ODT. The file looks completely normal.
  4. Place the Python Payload on the Target — Stage the Python script at the path referenced by the traversal sequence. In real attacks, this could already be on disk or delivered via another vector.
  5. Open the Document — Code Executes — The moment the victim opens the file in a vulnerable LibreOffice version, the payload fires automatically. No interaction needed.
content.xml open in Notepad showing malicious xlink:href
Step 1: The raw content.xml of the ODT document, open in Notepad. The malicious xlink:href containing the directory traversal path is visible at the bottom — pointing to http://test/ as the traversal entry point.
Save As dialog for the modified content.xml
Step 2: Saving the modified XML file. The document is saved as a plain text file before being repackaged into the ODT archive — preserving the injected traversal payload.
File named malicious_dontclick in Save As autocomplete
Step 3: Naming the malicious document. Autocomplete reveals previous iterations — malicious_dontclick.odt, malicious_dontclick_doc.docx — showing the iterative process of crafting and testing the exploit.
Documents folder with multiple malicious ODT variants
Step 4a: The Documents folder after testing. Multiple malicious variants visible — demo, dontclick, mal_final, malicious_file — the forensic trail of an exploit in development.
File Explorer showing malicious_file.odt selected
Step 4b: File Explorer with malicious_file.odt selected. 35.4 KB — a completely normal-looking document with a hidden payload inside.

The Moment It Fires

The Python payload in this demonstration was intentionally benign — designed to make the compromise impossible to miss without causing any actual harm. It opens Notepad via a system call and writes a message. In a real attack, this would be a reverse shell, credential harvester, or ransomware dropper.

# The Python payload — staged at the traversal target path
import os
# Opens Notepad with a custom message on the victim machine
os.system('notepad C:\path\to\message.txt')

open malicious_file.odt
Loading document... traversing path... executing macro...
YOU'VE BEEN HACKED!!!!!!!! by Kimaya

Notepad popup reading You've been HACKED by Kimaya
Execution confirmed: The moment malicious_file.odt was opened in LibreOffice, Notepad launched automatically — a process the user never invoked — displaying the proof-of-compromise message. cmd.exe is visible in the background taskbar, confirming the system call chain.
Notepad with hacked message text selected
Arbitrary write confirmed: The payload wrote arbitrary text to the filesystem and opened it — demonstrating full code execution capability. The text is selected, showing the complete message delivered by the exploit.
In a Real Attack

The Notepad popup would be replaced with a silent reverse shell, data exfiltration script, or ransomware payload. The victim would see nothing — just a document that appeared to open normally.

Why This Vulnerability Is Particularly Nasty

Zero User Interaction Required

Unlike phishing attacks that require victims to click links or enable macros, CVE-2018-16858 fires on document open. There is no security prompt to dismiss, no “enable content” button to click. The attack surface is the act of reading a document.

The Attack Vector Is Trust

Documents arrive via email, shared drives, and messaging apps constantly. They are inherently trusted artifacts — we open them to read information. This vulnerability weaponises that trust. An ODT file sent from a compromised colleague, or attached to a convincing email, is all it takes.

Directory Traversal as a Force Multiplier

The traversal component means the attacker doesn't need to smuggle the full payload inside the document. They only need to reference a Python file that already exists on the target — or stage one via a separate channel. This splits the attack and makes detection harder: the document itself may appear clean to static analysis.

Comparison: CVE-2019-9848 vs CVE-2018-16858

CVE-2019-9848 (LibreLogo) requires a mouse hover — user must interact with the document. CVE-2018-16858 requires only opening the file. In terms of attack friction, this one is strictly worse.

Mitigation

The patch landed in LibreOffice 6.0.7 and 6.1.3, released in late 2018. Any installation older than this remains vulnerable. Beyond patching, organisations should disable LibreLogo entirely if not needed, and enforce application whitelisting to prevent unexpected script execution.

✅ Mitigation Checklist

Update LibreOffice to 6.0.7+ or 6.1.3+  ·  Disable LibreLogo if unused (Tools → Options → LibreOffice Basic)  ·  Block ODT execution in untrusted mail environments  ·  Monitor for unexpected script execution processes (python.exe, cmd.exe) spawned by soffice.exe

University of Chester — Software Exploitation Assessment
Special thanks to Prof. Toyosi Oyinloye for mentorship and guidance throughout this project.
For educational purposes only  ·  All testing conducted in isolated VM environments  ·  Practice ethical hacking legally