Memento-RTLO File extension spoofing via U+202E  //  MITRE ATT&CK T1036.002

About

Memento-RTLO is a PowerShell tool that demonstrates file extension spoofing using the Right-to-Left Override Unicode control character (U+202E). It renames or copies executable files (.exe, .hta, .bat, .vbs, .ps1) so that their displayed extension appears benign (e.g. .pdf, .jpeg, .csv, .docx) while the underlying filesystem entry and operating-system behavior remain unchanged. The visual deception is produced entirely at the Unicode rendering layer, without modifying file content or metadata.

How the RTLO Attack Works

The Unicode Standard defines the Bidirectional Algorithm (UAX #9) to handle mixed-direction text. Code point U+202E RIGHT-TO-LEFT OVERRIDE is a zero-width format character that forces all subsequent characters to render right-to-left, regardless of their intrinsic directionality. Because it is non-printing, it is invisible in GUI contexts — Windows Explorer, Outlook, messaging apps and web browsers render the reversed characters without exposing the control character.

Filename Construction

<DisplayName> + U+202E + reverse(.<SpoofExt>) + <RealExt>

Step by step — payload.exe spoofed to appear as Annexe.jpeg:

  1. Display name: Annexe
  2. Spoof extension with leading dot: .jpeg, reversed: gepj.
  3. Append real extension: gepj..exe
  4. Insert U+202E: Annexe[U+202E]gepj..exe
  5. With extensions hidden, Explorer renders gepj. via RTLO as .jpeg, giving Annexe.jpeg

Without the leading dot: reverse('jpeg') = gepj, giving Annexejpeg with no separator. With it: reverse('.jpeg') = gepj. — the dot lands at position 0 after RTLO, producing Annexe.jpeg.

Logical:  A n n e x e [U+202E] . g e p j . . e x e
                               ^-- RTL rendering starts here

Visual (extensions hidden):  Annexe.jpeg
OS executes:                 .exe

Code Point Anatomy

PropertyValue
Code PointU+202E
NameRIGHT-TO-LEFT OVERRIDE
BlockGeneral Punctuation (U+2000 - U+206F)
CategoryCf (Format character)
Bidi ClassRLO (Right-to-Left Override)
UTF-8E2 80 AE (3 bytes)
UTF-16LE2E 20 (2 bytes, BMP)

Bidirectional Categories

CategoryNameDescription
LLeft-to-RightStandard Latin characters
RLORight-to-Left OverrideU+202E: forces all following characters RTL
RLERight-to-Left EmbeddingU+202B: opens an RTL embedding level
LROLeft-to-Right OverrideU+202D: forces all following characters LTR
PDFPop Directional FormattingU+202C: terminates the innermost embedding

Operating System Behavior

LayerBehavior
NTFSStores the exact logical byte sequence including U+202E. No sanitization at the filesystem layer.
Windows ShellExplorer's ListView (comctl32 v6) delegates filename layout to DirectWrite (IDWriteTextLayout), which applies UAX #9. GDI has no bidi logic; this is a DirectWrite-only path on Windows 10/11.
Process executionThe kernel resolves filenames by logical byte sequence. The loader reads the real extension and executes accordingly.
Extensions visibilityThe technique relies on Windows hiding known file extensions (the default setting). When extensions are shown, the real extension appears reversed in the visual name.

Usage

# Download PS> Invoke-WebRequest https://raw.githubusercontent.com/franckferman/Memento-RTLO/stable/MementoRTLO.ps1 -OutFile MementoRTLO.ps1 # Allow execution PS> Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process # List all 22 patterns PS> .\MementoRTLO.ps1 --show-list # Filter patterns by real extension PS> .\MementoRTLO.ps1 --show-list --file payload.exe # Preview output without writing (dry run) PS> .\MementoRTLO.ps1 --file payload.exe --choice 1 --dry-run # Spoof .exe as PDF (copy) PS> .\MementoRTLO.ps1 --file payload.exe --choice 1 # Rename in-place as JPEG PS> .\MementoRTLO.ps1 --file payload.exe --choice 4 --replace # Custom name: appear as cv_franck.pdf (actually .hta) PS> .\MementoRTLO.ps1 --file cv_franck.hta --name cv_franck --fake-ext pdf # Use RLI character instead of default RLO PS> .\MementoRTLO.ps1 --file payload.exe --choice 1 --bidi-char rli

Command-Line Reference

OptionRequiredDescription
--file <path>Yes*Source file (.exe / .hta / .bat / .vbs / .ps1)
--choice <N>NoPredefined pattern index from --show-list
--name <basename>NoCustom basename, bypasses predefined patterns
--fake-ext <ext>NoFake extension to display, e.g. pdf, jpg (requires --name)
--replaceNoRename in-place instead of creating a copy
--dry-runNoPreview output filename, no file written
--show-listNoList all patterns; combine with --file to filter by extension
--bidi-char <mode>Norlo (default, U+202E) / rli (U+2067) / rle (U+202B)
--helpNoPrint usage and exit

* --file optional when using --show-list without extension filter. --name and --choice are mutually exclusive.

Supported Extensions and Patterns

Real ExtIndexPredefined Patterns
.exe1-7Rapport_trimestriel.pdf, Annexe_contrat.pdf, Devis_client.pdf, Photo_reunion.jpeg, Scan_document.jpg, Logo_societe.png, Note_interne.txt
.hta8-11Info_reunion.jpg, Bilan_annuel.pdf, Fichier_partage.txt, Capture_ecran.png
.bat12-15Liste_contacts.csv, Note_reunion.txt, Instructions_setup.txt, Export_donnees.csv
.vbs16-18Script_backup.txt, Email_client.eml, Rapport_audit.pdf
.ps119-22Config_systeme.txt, Rapport_securite.pdf, Donnees_export.csv, Document_interne.docx

Terminal Demo

PS C:\lab> .\MementoRTLO.ps1 --file payload.exe --choice 1 --dry-run ==================================================== Memento-RTLO - File Extension Spoofing Tool MITRE ATT&CK T1036.002 | Author: Franck FERMAN ==================================================== Source : payload.exe Pattern : [1] Rapport_trimestriel.pdf (for .exe) Output : Rapport_trimestriel‮fdp..exe [DRY RUN] No file written. PS C:\lab> .\MementoRTLO.ps1 --file payload.exe --choice 1 Output : Rapport_trimestriel‮fdp..exe [OK] Spoofed copy created. PS C:\lab> .\MementoRTLO.ps1 --file cv_franck.hta --name cv_franck --fake-ext pdf Output : cv_franck‮fdp..hta [OK] Spoofed copy created. # In Windows Explorer (extensions hidden): Rapport_trimestriel‮fdp..exe → displays as Rapport_trimestriel.pdf cv_franck‮fdp..hta → displays as cv_franck.pdf

MITRE ATT&CK Mapping

FieldValue
TacticDefense Evasion
TechniqueT1036 - Masquerading
Sub-techniqueT1036.002 - Right-to-Left Override
PlatformsWindows, Linux, macOS
Data SourcesFile Metadata, File Creation, Process Creation

Related Techniques

IDNameRelationship
T1566.001Spearphishing AttachmentCommon delivery vector
T1204.002User Execution: Malicious FileRequires user click
T1027Obfuscated Files or InformationConceptual overlap

Detection

Scan filenames for Unicode bidirectional control characters. Key code points: U+202A-U+202E and U+2066-U+2069.

PowerShell

PS> Get-ChildItem -Recurse | Where-Object { $_.Name -match [char]0x202E } | Select-Object FullName

Python

import os BIDI = {'\u202a','\u202b','\u202c','\u202d','\u202e','\u2066','\u2067','\u2068','\u2069'} for root, dirs, files in os.walk('.'): for name in files: if any(c in name for c in BIDI): print(os.path.join(root, name))

Sigma Rule

title: RTLO Character in Filename status: experimental logsource: category: file_event product: windows detection: selection: TargetFilename|contains: "\u202E" condition: selection tags: - attack.defense_evasion - attack.t1036.002

License

GNU Affero General Public License v3.0 — full terms.