Document Steganography Extractor
Extract hidden payloads from DOCX, XLSX, PPTX and ODT documents. Reads the six formats this site's Hider writes. AES-256-GCM decryption, CTF flag detection and an anomaly score. Processed in your browser, not uploaded.
Drop a document here or click to browse
DOCX · XLSX · PPTX · ODT · Max 200 MB
Processed in your browser
Your document is parsed and rewritten in this browser tab using JSZip and is not sent to a server. Usage statistics may record which options were used, never your document.
How to Decode a Steganographic Office Document (4 steps)
- Upload the DOCX, XLSX, PPTX or ODT file you suspect carries hidden data
- Quick mode runs Auto-Detect; Standard lets you pick one of the six methods; Forensic adds Reed-Solomon recovery, watermark attribution and analysis tabs
- Enter the password if the payload was encrypted (leave it empty otherwise)
- Decode, then read the message, download the file or check the anomaly score
Document Detection Methods: Auto-Detect and Six Readers
| Method | What it reads | Evidence | Best For |
|---|---|---|---|
| Auto-Detect | Tries the six methods in order and returns the best result: a file, then text with a flag, then text, then encrypted data, then binary | Reads only the formats this site's Hider writes | Documents from the Hider |
| Custom XML Parts | customXml/ep_payload.xml (or any customXml part with an <ep:data> element, or the part named by the stegotoolkit relationship) | Kept by python-docx and python-pptx re-saves, dropped by openpyxl (Word and LibreOffice not tested) | Default Hider output |
| ZIP Comment | A ZIP comment that starts with EP_STEGO_V1: | Dropped by every re-save tested; 48,750 bytes at most | Small messages, CTF files |
| XML Attribute | ep:d="EP_STEGO_V1:index:chunk" attributes on paragraphs, sheets or slide ids | Kept by python-docx and python-pptx re-saves, dropped by openpyxl | Documents with many paragraphs or slides |
| Hidden Text | A run with the hidden-font property whose text starts with EP_STEGO_V1: | Kept by a python-docx re-save; DOCX only | Word documents |
| Revision Tracking | A tracked insertion (<w:ins>) whose text starts with EP_STEGO_V1: | Kept by a python-docx re-save; DOCX only | Word documents |
| ZIP Extra Field | Central-directory extra fields with the private tag 0x4550 | Dropped by every re-save tested | Files that were sent as they were |
What the Document Extractor Reads
This Extractor reads the six formats the Document Hider on this site writes: a custom XML part, a ZIP comment, ep attributes, a hidden run, a tracked insertion and ZIP central-directory extra fields. Auto-Detect tries them in that order and shows the best result: a recognised file ranks first, then text that contains a flag, then other text, then encrypted data, then binary. It does not read data hidden by other tools, and it cannot tell you that a document is clean, only that none of these six formats was found.
A candidate is accepted when it matches this tool's marker (EP_STEGO_V1: or the ep:data element or the 0x4550 tag) and format checks. These checks identify a likely payload; they do not show that its contents are intact, and they are not a checksum of the message: an unencrypted message that was changed afterwards is read as it now stands, while a changed encrypted payload fails AES-GCM authentication when you enter the password.
Finding Hidden Text in a Word Document
People search for ways to find hidden text in a Word document. In Forensic mode the Hidden Text tab lists every run that is hidden with the vanish property (the bare form and the explicit on forms w:val="1" and "true"), every run coloured white and every run with a font size under 2 pt, with its text. It reads the document XML directly, so it shows text whoever added it, not only this tool's own payload.
The Custom Parts tab lists every customXml part and custom relationship in the package, the Namespaces tab lists the XML namespaces in use, the Entropy tab shows how random each part is, and the Strings tab lists readable strings with flag patterns highlighted. None of them proves that something is hidden: an ordinary document can have custom parts and unusual namespaces.
Passwords and What You See
The Extractor decrypts only when you enter a password. A payload stored without a password is shown directly, and a password typed for it is ignored. An encrypted payload opened with no password or a wrong one is shown as the stored encrypted bytes and labelled encrypted; wrong password, damaged data and missing password give the same result, so the screen cannot say which applies.
What Auto-Detect Looks For
| Order | Method | What it looks for | How a find is confirmed |
|---|---|---|---|
| 1 | Custom XML Parts | customXml/ep_payload.xml, any customXml part with an <ep:data> element, or the part named by the stegotoolkit relationship in _rels/.rels | <ep:data> holds valid base64 |
| 2 | ZIP Comment | The ZIP comment | It starts with EP_STEGO_V1: followed by valid base64 |
| 3 | XML Attribute | ep:d attributes in word/document.xml, xl/workbook.xml or ppt/presentation.xml | The ep namespace is declared and the chunks join into valid base64 |
| 4 | Hidden Text | A run with the vanish property in word/document.xml (DOCX only) | Its text starts with EP_STEGO_V1: |
| 5 | Revision Tracking | A <w:ins> element in word/document.xml (DOCX only) | Its text starts with EP_STEGO_V1: |
| 6 | ZIP Extra Field | Central-directory extra fields | Blocks with the tag 0x4550 join into a payload |
The Anomaly Score (Measured on a Reference File)
The score adds up to six parts: custom parts and relationships (up to 25: 15 for a custom relationship plus 10 when a Custom XML payload is found), ZIP comment (15), ep attributes (20), hidden text and revisions (15: 10 for hidden text and 5 for a tracked insertion), ZIP extra field (15) and payload quality (10: a recognised file or a flag). Scores below are for the same generated 100-paragraph DOCX with a short plain-text message (no flag) hidden with each method; a clean document scores 0.
| Method used to hide the message | Score |
|---|---|
| None (clean document) | 0 |
| Custom XML Parts | 25 |
| ZIP Comment | 15 |
| XML Attribute | 20 |
| Hidden Text | 10 |
| Revision Tracking | 15 |
| ZIP Extra Field | 15 |
What You See for Each Password Situation
| Payload | Password typed | Result |
|---|---|---|
| Not encrypted | None | The message |
| Not encrypted | Any | The message (the password is ignored) |
| Encrypted | None | The stored encrypted bytes, labelled encrypted |
| Encrypted | Wrong | The same stored encrypted bytes |
| Encrypted | Right | The message, marked as decrypted |
The Forensic Mode Tabs
| Tab | What it shows | Reads data from other tools? |
|---|---|---|
| ZIP Structure | Every ZIP entry with sizes, comments and extra fields; entries carrying the 0x4550 tag are marked | Lists any ZIP |
| Custom Parts | Every customXml part and custom relationship | Yes, lists any |
| Namespaces | The XML namespaces used in each part, marked standard or unusual | Yes, lists any |
| Hidden Text | Runs that are hidden, white or under 2 pt, with their text (DOCX) | Yes, lists any |
| Entropy | How random each part is (0 to 8 bits per byte) | Yes, any part |
| Strings | Readable strings from the XML parts, flag patterns highlighted | Yes, any part |
Examples
Input: A DOCX made by the Hider with the message "Meet at the old bridge at 9pm." in Custom XML Parts, no password
Result: Auto-Detect finds customXml/ep_payload.xml, shows the 30 characters as text, and the anomaly score is 25 (custom relationship 15 plus the payload found there 10).
Meaning: The same message hidden in the ZIP comment scores 15 and in ep attributes 20. The score counts this tool's markers; it is not a measure of how well the data is hidden.
Input: The same message hidden with a password, opened with no password, then a wrong one, then the right one
Result: With no password and with a wrong one you get the same 79 stored bytes (31 plus the 48-byte wrapper), labelled encrypted. With the right password you get the 30-character message, marked as decrypted.
Meaning: The screen does not say whether the password was missing, wrong or the data damaged. A password typed for a message that was never encrypted is ignored and the message is shown.
Input: An ordinary DOCX made by python-docx that contains one run marked hidden
Result: Auto-Detect finds nothing and the score is 0, because the run does not start with EP_STEGO_V1:. The Forensic Hidden Text tab lists the run and its text.
Meaning: This is how to look at a document made by something else: the Extractor reads only its own formats, while the Forensic tabs show what is in the file.
Input: A leaked copy from a 10-recipient export, with the watermark_keys.json file loaded in Forensic mode
Result: The Extractor reads the watermark ID from the copy and names the recipient it was made for.
Meaning: This works only while the ID is still in the file. A re-save that dropped the ZIP comment or extra fields, if that is where it was hidden, removes the ID, and the key file alone cannot identify the copy.
Input: A document hidden with Revision Tracking
Result: Auto-Detect returns the correct message but names Hidden Text as the method, because the tracked insertion holds a hidden run with the same marker and the Hidden Text reader gets there first. Choosing Revision Tracking in Standard mode names it.
Meaning: The payload is the same either way; only the label of the method differs.
How the Document Extractor Works
Read the document as a ZIP
JSZip opens the file in your browser. A file that is not a ZIP package is refused with a message.
Try the readers
Auto-Detect runs the six readers in order; in Standard mode you pick one. Each looks only for this tool's marker.
Choose the best candidate
Of the candidates found, a recognised file ranks first, then text with a flag, then text, then encrypted data, then binary.
Decrypt and unwrap
If you typed a password and the stored bytes have the encrypted layout, AES-256-GCM is decrypted. The file-name frame is then removed, and Reed-Solomon is repaired first if you ticked it in Forensic mode and the data starts with its header.
Interpret
The result is classified as text, a file with a known signature, encrypted-looking data or unrecognised bytes, and flag patterns are highlighted.
Score and analyse
The anomaly score adds up the markers found. In Forensic mode the ZIP, custom part, namespace, hidden text, entropy and strings tabs read the package directly.
What the results mean
| Result | What it means | What to do |
|---|---|---|
| Message or file with the method named | A candidate carried this tool's marker. Text is shown with any flags highlighted; a recognised file is offered as a download under its original name when the Hider stored one. | Read it, or download it. |
| Encrypted bytes, labelled encrypted | The payload has the encrypted layout and no password, or the wrong one, was used. | Enter the password and decode again. |
| Unrecognised binary | A payload was found but it is neither readable text nor a known file type. | It may be a file without a signature; download it and inspect it. |
| Nothing found, score 0 | None of the six markers is in the file. | This does not prove the document is clean; use the Forensic tabs to look at it. |
| A score above 0 without a payload | The file has a custom relationship, a ZIP comment or other signs, but no readable payload (for example a comment that does not start with the marker). | Open the ZIP Structure and Custom Parts tabs. |
| Reed-Solomon recovery note | The parity was applied and the number of repaired bytes is shown. | Check the result: over the limit the repair usually fails, and a rare miscorrection is possible (a password makes AES-GCM expose it). |
Limitations
- Only the six formats the Document Hider writes are read. Data hidden by other tools, or in other places, is not found by Auto-Detect.
- DOCX, XLSX, PPTX and ODT only; the format is taken from the file extension. A document that Office encrypted with a password is refused. Files above 200 MB (50 MB on a phone) are refused.
- An unencrypted payload is checked only by its marker and length, so a changed message can be returned without a warning; encrypted payloads fail authentication instead.
- A wrong password, a missing password and damaged encrypted data give the same result, so the screen cannot say which applies.
- A re-save can remove the data before you get the file. In our tests python-docx and python-pptx re-saves kept Custom XML Parts and XML Attribute data, an openpyxl re-save kept none, and every re-save dropped the ZIP comment and extra fields. Word, LibreOffice and Google Docs were not tested.
- The anomaly score counts this tool's markers only; it is not a general steganalysis measure, and a low score does not mean a document is free of hidden data.
- The Hidden Text tab finds the hidden-font property, white text and text under 2 pt; text hidden in other ways is not found.
- Key-derivation time on phones was not measured.
Privacy
The document is read and decoded in your browser tab (a Web Worker, JSZip and the Web Crypto API) and is not uploaded. Usage statistics may record which options were used, never the document, the extracted data or the password. The hosting provider keeps ordinary request logs for page loads.
Which Tool Next?
- Document Steganography Hider — hide a message in a document with the same six methods.
- PDF Steganography Extractor — for PDF documents instead of Office files.
- Metadata Steganography Extractor — reads data hidden in document properties.
- Strings Extractor (CTF Lab) — lists readable text in any file, including a document of unknown origin.
- Text Steganography Extractor — for plain text with look-alike characters or whitespace.
Frequently Asked Questions
What documents does the Extractor read?
DOCX, XLSX, PPTX and ODT files (all ZIP packages), up to 200 MB (50 MB on a phone). The format comes from the file extension. A document that Office encrypted with a password is not a ZIP and cannot be read here.
Can it read data hidden by other tools?
No. Auto-Detect and the six readers look only for the markers this site's Hider writes (EP_STEGO_V1:, the ep namespace, tag 0x4550). A document hidden by another program is not read, and an empty result does not prove a document is clean. The Forensic tabs can still show unusual parts, hidden runs and strings from any document.
How do I find hidden text in a Word document?
Upload it, switch to Forensic mode and open the Hidden Text tab. It lists runs marked hidden (<w:vanish/>, including the explicit on forms w:val="1" and "true"), white-coloured text and text under 2 pt, whoever put them there, with the text of each. Text hidden by a custom style or placed off the page is not detected. Word's own Show/Hide option reveals ordinary hidden text too.
Is my document uploaded?
No. JSZip and the Web Crypto API process the document in your browser tab; it is not sent to a server. Usage statistics may record which options were used, never your document.
What if nothing is found?
Auto-Detect returns no payload and the anomaly score stays at 0 for a document with none of this tool's markers. Try each method on its own in Standard mode, and check the password: a payload that was written with another tool, or removed by a re-save (ZIP Comment and ZIP Extra Field are lost by any re-save), cannot be read.
Why is the output garbled?
The payload is encrypted. With no password, or a wrong one, the Extractor shows the stored encrypted bytes and labels them encrypted; it does not raise an error. Enter the password used when hiding. A password typed for a payload that was never encrypted is ignored and the message is shown normally.
Can it find CTF flags automatically?
Yes. The decoded text is scanned for FLAG{…}, HTB{…}, picoCTF{…}, CTF{…}, CHTB{…}, THM{…}, VULNHUB{…} and rootme{…}, and for any 2-8 letter upper-case prefix followed by braces. Hits are highlighted. The Strings tab in Forensic mode scans every XML part of the document the same way.
What does Reed-Solomon Recovery do?
If the Hider added Reed-Solomon parity, tick this option in Forensic mode: the Extractor repairs up to 5, 10 or 15 changed bytes per 223-byte block (RS-10, RS-20, RS-30) and then removes the parity. It cannot rebuild data that a program dropped when it saved the file. It works only on payloads hidden without a password: the Hider adds the parity before encryption, so damaged bytes of a password-protected payload fail the AES-GCM check first.
What is the anomaly score?
A number from 0 to 100 that adds up the signs of this tool's six methods in the file: custom parts and relationships (up to 25: 15 for a custom relationship plus 10 when a Custom XML payload is found), a ZIP comment (15), ep attributes (20), hidden or tracked data (15), extra fields (15) and the quality of what was recovered (10). It counts these markers only. A clean document scores 0, and a low score never means a document is free of hidden data.
How does watermark attribution work?
If a copy was made with the Hider's per-recipient export, switch to Forensic mode, upload the watermark_keys.json that came with the ZIP, and decode the leaked copy. When the copy still carries its watermark ID the Extractor names the matching recipient. The key file alone cannot identify a copy whose ID has been removed.
Related Tools
Document Steganography Hider
Hide text or a file inside a DOCX, XLSX, PPTX or ODT document with six methods (custom XML part, ZIP comment, XML attributes, hidden text, tracked changes, ZIP extra fields). Optional AES-256-GCM encryption. Processed in your browser, not uploaded.
Steganography Detector
Statistical steganalysis with three published tests — chi-square, RS analysis and Sample Pairs — fused into one score and checked against the real StegExpose on a small test set. Payload size estimate. Method fingerprint. WAV audio support. Processed in your browser, not uploaded.