StegoToolkit

QR Code Steganography Extractor

Extract hidden payloads from steganographic QR codes. Auto-detects method across LSB, module color, and PNG metadata. Shows a QR anomaly heuristic and per-method results.

New

Drop QR code image or click to browse

PNG, JPEG, WebP, BMP — QR code images

Processed in your browser

QR scanning and extraction run in your browser tab; your QR code image is not sent to a server. Usage statistics may record which options were used, never your image. PNG format gives the best accuracy.

How to Extract Hidden Data from a QR Code (5 steps)

  1. Upload the QR code image (PNG recommended; JPG, screenshots and photos usually destroy pixel-level data)
  2. The tool scans the QR and shows its primary content
  3. Keep Auto-Detect, or choose one extraction method in Standard or Forensic mode
  4. If the payload is encrypted, enter the password on the next step
  5. Copy your hidden message or download the extracted bytes

QR Extraction Methods — Detection Guide

MethodAccuracySpeedBest For
Auto-DetectTries 3 methods in orderFastUnknown method. Tries PNG Metadata, LSB Pixel and Module Color in order; stops at the first readable text or recognised file, otherwise lists every result found and selects the best available one
PNG MetadataExactInstantPNG files made with the metadata method
LSB PixelExact on an unchanged PNGFastFiles made with the LSB method
Module ColorExact on an unchanged PNGFastFiles made with the module-colour method

What the Extractor Looks For

The Extractor reads the three layouts the QR Code Steganography Hider writes. In a PNG it looks for a PNG tEXt chunk with the keyword stego. In the pixels it reads the red low bit of consecutive pixels (LSB), and it separately collects the pixels whose red value is 1, 2, 253 or 254 (Module Color). Each layout starts with a 4-byte length, and a result is only reported when that length fits inside the image, so an ordinary QR image reports nothing.

Module Color extraction does not locate the QR matrix or sample module centres. It scans every pixel of the image in reading order and takes each pixel whose red value is 1 or 2 (dark pixel, bits 1 and 0) or 254 or 253 (light pixel, bits 1 and 0); pure 0 and 255 pixels are skipped. This works because the Hider changes only module-centre pixels and does so in module reading order, so the marked pixels come out in the order they were written. It also means any other pixel with one of those values is taken as a bit: an LSB-made image has pixels at 254, which this method would read as junk (Auto-Detect tries LSB first and stops when it reads text). At least 32 marked pixels are needed for the length, and the length must fit the number found.

If the bytes carry the Hider's Reed-Solomon wrapper or encryption, the Extractor removes the wrapper (repairing changed bytes where it can) and decrypts with your password. It then looks at the result: text, a known file type from its first bytes, other binary data, or data that looks encrypted.

For general images, the LSB Extractor and the Steganography Analyzer read other layouts and run statistical tests.

Reading the Anomaly Score

The score is a quick triage number made from the parts described in the answer to the anomaly-score question above, not a detector. It can be 0 on an image that holds a message (a longer PNG Metadata message adds no pixel change) and it can be high on an image that holds nothing (compression artefacts). Trust the extraction result first and the score second. The score is out of 70, the sum of three parts; the table Anomaly Score Parts lists them.

What Each Layout Looks Like in the File

LayoutWhere the bytes areHow the Extractor reads itFails when
PNG MetadatatEXt chunk, keyword stego, Base64 valueWalks the PNG chunks; Base64-decodes; reads the 4-byte lengthThe image was re-saved without the chunk or is not a PNG
LSB PixelRed low bit of pixels from the top-leftReads 32 bits of length, then that many bytesPixel values changed (JPEG, resize, screenshot)
Module ColorRed 1/2 on dark, 254/253 on light module centresScans every pixel in reading order for those red values (it does not locate the QR matrix); the first 32 marked pixels are the lengthFewer than 32 marked pixels, or pixel values changed

Anomaly Score Parts

Everything is computed from the uploaded image and nothing is compared with a reference. The score is the sum of three parts and cannot exceed 70; the fourth part of an older 100-point scale was reserved for the method that is not implemented.

PartCountsPoints
PNG metadataA tEXt chunk with the keyword stego20 if present, otherwise 0
Colour anomaliesPixels whose red value is 1 to 9 on a dark pixel or 246 to 254 on a light pixel0 to 25: the count divided by 2, rounded down; 25 from 50 anomalies up
LSB-plane entropyShannon entropy of the bytes built from the red low bits of all pixels0 up to 5.0 bits, 12 above 5.0, 25 above 6.5
Error-correction deviationsNot implementedAlways 0
TotalThe three parts addedAt most 70. Low: under 25. Medium: 25 to 59. High: 60 or more, which needs the PNG chunk, the full 25 from LSB entropy and a colour part of at least 15

Image Formats and Methods

PNG Metadata extraction requires the original PNG file. Pixel-based methods require the original pixel values; support for an image format does not guarantee that its pixels preserve the hidden data. This table says what to expect, from how each format stores pixels; the PNG, BMP, JPEG and lossy WebP cases were checked in a browser (JPEG and WebP at quality 0.95), the lossless WebP case was not.

Uploaded filePNG MetadataLSB PixelModule Color
The original PNG from the HiderReadReadRead
JPEGNot available: a converted file has no PNG chunkNormally lost: lossy compression changes the low bitsNormally lost: the marked values 1, 2, 253, 254 are smoothed
WebPNot availableLost when saved lossy; a lossless copy was not testedLost when saved lossy; a lossless copy was not tested
BMPNot availableKept by a lossless copy that is not resized or recolouredKept by a lossless copy that is not resized or recoloured

Examples

Input: A plain QR for https://example.com with nothing hidden (165 × 165 px).

Result: All three methods find nothing; the anomaly score is 0 of 70 (Low).

Meaning: The length read from the red low bits is larger than the image can hold, so the LSB method reports nothing.

Input: The same QR with FLAG{qr_demo} hidden by the LSB method (77 pixels changed).

Result: Auto-Detect tries PNG Metadata first (nothing), then LSB, which returns the 13 bytes as text and stops; the anomaly score is 25 (Medium).

Meaning: The 25 comes from the colour part alone: the 77 white pixels at 254 are more than 50 colour anomalies. The LSB-entropy part stays 0 because most of the low-bit plane is still the plain QR. The message itself is plain text.

Input: A message stored with a password and Reed-Solomon RS-20, then 10 of its stored bytes changed in the pixels.

Result: Extraction removes the wrapper, reports 10 bytes repaired, then decrypts with the password.

Meaning: RS-20 repairs up to 10 changed bytes in each 223-byte data block; here all 10 fell in the one block, which is exactly its limit. A block with more changed bytes than the limit cannot be guaranteed to recover, and the result then says the damage is beyond repair (in our tests this was flagged every time). The 16-byte wrapper header is not repaired. Reed-Solomon is outside the encryption, so repair happens before the AES-GCM check.

Input: The same image with a wrong password.

Result: The payload stays encrypted and a message says the password did not decrypt it.

Meaning: A wrong password and altered bytes look the same to the tool.

How the QR Extractor Works

1. Scan

The image is decoded in the browser and jsQR reads the QR's own content and version.

2. Extract

Each method reads its bytes: the tEXt chunk, the red low bits, or every pixel whose red value is 1, 2, 253 or 254 in reading order (Module Color does not locate the QR matrix), each starting with a 4-byte length that must fit the image.

3. Unwrap

A Reed-Solomon wrapper is recognised by its header and removed, repairing what it can; encrypted bytes are decrypted with your password when the AES layout is recognised.

4. Interpret

The bytes are classified as text, a known file type, other binary data or encrypted-looking data, and CTF flag shapes are highlighted.

What the results mean

ResultWhat it meansWhat to do
Readable text came outA layout matched and the bytes are text.Copy it. The method shown tells you which layout the Hider used.
A known file type came outThe first bytes match a file signature (PDF, PNG, ZIP and others).Download the bytes and open them with the matching program.
Still encryptedThe bytes have the Hider's AES layout and no password was given, or the password did not work.Enter the password on the previous step; a wrong password and changed bytes look alike.
Nothing foundNo layout produced a length that fits the image.Try each method by hand, use the original PNG, or look for other hiding schemes with the Analyzer.
Repair note from Reed-SolomonThe wrapper was found; the note says how many bytes were repaired or that damage was beyond repair.If damage was beyond repair, compare with the original file.

Limitations

  • Only this tool's three layouts are read. Other steganography tools' QR codes, data after the PNG, and puzzles that hide a second QR code are not covered.
  • LSB and Module Color results need the exact pixels of the PNG. JPEG copies, screenshots, resized or photographed images normally lose them (by design; not measured for this tool).
  • An image with transparent pixels is read as the browser draws it, which can change the low bits under partly transparent pixels. The Hider's own files are fully opaque, so the safest workflow is to use the original PNG the Hider created.
  • The anomaly score is a heuristic out of 70 and has not been checked against other detectors; a short PNG Metadata message scored 20 (Low) in our tests.
  • A wrong password and altered encrypted bytes give the same message.

Privacy

The image is decoded and analysed in your browser tab; the tool's own code does not upload it. Usage statistics may record which options were used and coarse facts such as sizes, never your image or the extracted bytes. The host keeps ordinary request logs. For encrypted payloads the password is processed with PBKDF2-HMAC-SHA-256 (100,000 iterations) to derive the AES key; unencrypted payloads do not need a password. The password is turned into a key with PBKDF2-HMAC-SHA-256 (100,000 iterations) and the salt stored in the payload, and the AES-256-GCM authentication tag then checks it. A wrong password and a damaged payload both simply report failure, so the tool cannot tell you which it was, and there is no way to recover a forgotten password. The full description, including what this scheme does not protect, is on the [QR Code Steganography Hider](/steganography/qr-code-steganography-hider) page.

Which Tool Next?

Frequently Asked Questions

How does Auto-Detect work?

Auto-Detect tries PNG Metadata, then LSB Pixel, then Module Color. It interprets each result (text, known file type, encrypted-looking, other binary) and stops at the first one that reads as text or a known file. If no method gives readable text or a known file, it has tried all three, lists every result found, and selects the best available one in the order text, file, binary, encrypted, noise (a tie keeps the order in which the methods were tried). QR error-correction codeword extraction is not implemented.

Which QR codes can this extract from?

Only data written in this tool's own layouts: a tEXt chunk with the keyword stego, a 4-byte length followed by the red low bits of consecutive pixels, or a 4-byte length followed by red values of 1, 2, 253 and 254 at module centres. A QR made by a different steganography tool, or a puzzle that hides something else in a QR (data after the image, a QR inside a QR), is not read. For those use the Steganography Analyzer or the StegSolve tool.

What is the QR Anomaly Score?

A heuristic from 0 to 70 that counts signs of this tool's methods, not a probability and not a detector. It adds three parts: a PNG-metadata part (20 when a stego chunk exists, otherwise 0), a colour part (0 to 25, from pixels whose red value is just off pure black or white) and an LSB-entropy part (0, 12 or 25, from the entropy of the red low-bit plane). A fourth part, error-correction deviations, is reserved for the method that is not implemented and is always 0. The three parts can add up to 70 at most, which is why the screen shows the score out of 70. Low is under 25, Medium 25 to 59, High 60 or more. In our tests a plain QR scored 0; the same QR with a short message scored 25 for LSB and for Module Color (both from the colour part: 77 and 136 off-white pixels, and the LSB-entropy part stayed 0), and 20 (Low) for PNG Metadata.

Why can the anomaly score be high when no payload is found?

Anything that makes red values drift off pure black and white raises the colour part: JPEG compression, resizing with smoothing, a screenshot of a scaled page. Choose the method by hand and look at the results before concluding anything is hidden.

Can I extract data from a JPEG, WebP or BMP QR code?

PNG Metadata extraction requires the original PNG file: a PNG converted to JPEG, WebP or BMP has no PNG text chunk. Pixel-based methods (LSB and Module Color) require the original pixel values, and support for an image format does not guarantee that its pixels preserve the hidden data. A lossy copy (JPEG, or WebP saved lossy) normally changes them; a lossless copy that is not resized or recoloured (for example a BMP made from the PNG) keeps them. The table Image Formats and Methods sets this out. Use the original PNG.

What happens with a wrong or missing password?

With no password, an encrypted payload is shown as encrypted. With a wrong password, the result says the password did not decrypt it and the bytes stay encrypted; the tool cannot tell a wrong password from changed bytes. With a correct one the AES-GCM tag verifies and the result says so.

What is Reed-Solomon recovery here?

If the Hider wrapped the stored bytes with Reed-Solomon, the Extractor recognises the wrapper by itself, removes it and repairs up to 5, 10 or 15 changed bytes in each 223-byte data block (levels 10, 20, 30); the limit applies per block, not to the whole payload, and a block with more changed bytes than that cannot be guaranteed to recover. The wrapper is a 16-byte header followed by the blocks, each with its parity bytes (10, 20 or 30); the header itself is not repaired. The Extractor reports how many bytes it repaired, or that the damage was beyond what it can repair. It does not help with a heavily re-compressed image.

What do CTF flags look like in results?

Text matching common flag shapes (FLAG{...}, HTB{...}, picoCTF{...}, CTF{...}) is highlighted with a copy button.

Related Tools