Exiftool

exiftool reads, writes, and strips the metadata buried in a file: camera model and GPS in a JPEG, author and software in a PDF, ID3 in an MP3, and hundreds of other tags across image, document, audio, and video formats. It turns a file you already have into context: who made it, with what, when, and sometimes where. Reach for it first on any CTF forensics or stego artifact, on a downloaded document during OSINT, or when you need to scrub metadata before publishing.

Mental model: exiftool [options] [-TAG operations] FILE - no flag reads, -TAG=value writes, -TAG= deletes.

New to file metadata? Core concepts
  • Tag: one named field like Author or GPSLatitude; no flag reads it, -TAG=value writes, -TAG= deletes
  • Group: where a tag lives - EXIF (cameras), IPTC/XMP (publishing), PDF, ID3 (audio); -G1 shows it, and the same field can appear in several groups at once
  • Short name vs description: -s prints the exact tag name you must use to write; the default label is just a pretty description
  • Composite tag: a convenience value derived from others (GPSPosition, ImageSize); read-only, so write the underlying GPSLatitude/GPSLongitude instead
  • Unknown / duplicate tags: hidden by default; -u decodes unknown ones and -a keeps duplicates, where CTF authors stash a flag
  • Embedded preview: a thumbnail stored inside the file, often the un-edited original after someone cropped or painted over the full image
  • FILE_original: the automatic backup exiftool saves on any write, unless -overwrite_original discards it
When to reach for exiftool (and when not)

Reach for it to read the metadata on a CTF forensics or stego artifact, surface GPS/author/software during OSINT, scrub identifying fields before publishing, batch a folder into a catalog, or fix and shift wrong capture timestamps.

Reach for something else when the payload is hidden inside the pixels or appended past the file’s real end (steghide or binwalk carve it out), you only need a fast type guess (file) or the printable strings exiftool’s parsers skip (strings), or you want purpose-built multi-format sanitization (mat2) or a lighter EXIF/IPTC/XMP reader (exiv2).

Install, update, verify#

sudo apt install -y libimage-exiftool-perl           # Debian / Ubuntu / Kali
sudo dnf install -y perl-Image-ExifTool              # Fedora / RHEL
brew install exiftool                                # macOS
sudo apt install --only-upgrade -y libimage-exiftool-perl   # update

exiftool -ver         # version number
command -v exiftool    # confirm it is on PATH

Prefer the package manager: it pulls the Perl dependency for you. On Windows, grab the standalone build; it ships as exiftool(-k).exe, so rename it to exiftool.exe on your PATH. New releases add tag and format definitions, so an up-to-date binary reads more obscure fields correctly.

Flags you’ll actually use#

Skim these first; the cheat sheet below is these flags combined.

FlagDoesFlagDoes
(none)Read all tags-TAG=valWrite a tag
-G1Show group of each tag-TAG=Delete a tag
-sShort tag names-all=Strip all metadata
-a -uDuplicate + unknown tags-overwrite_originalNo _original backup
-c "%.6f" / -nGPS as decimal-tagsFromFileCopy tags from another file
-bRaw binary value of a tag-rRecurse into directories
-if 'COND'Filter files by a tag-j / -csvJSON / CSV output

Cheat sheet#

The Read block builds up one flag at a time; stop at the line that answers your question.

# Read: start bare, add one flag at a time
exiftool FILE                          # 1. every tag (the right first move)
exiftool -G1 FILE                      # 2. + which group each tag lives in
exiftool -s FILE                       # 3. + exact short tag names (to write)
exiftool -a -u -G1 FILE                # 4. + duplicate and unknown tags (CTF)
exiftool -Comment -Author -Software FILE   # just the high-signal fields

# Location (GPS)
exiftool -c "%.6f" -GPSPosition FILE   # coords as decimal degrees
exiftool -n -GPSPosition FILE          # signed decimal, map-ready
exiftool -r -if '$GPSLatitude' -filename -gpsposition FILE_DIR   # only geotagged files

# Hunt for hidden text
exiftool FILE | grep -iE 'comment|flag|note|description|copyright'

# Extract embedded data
exiftool -b -ThumbnailImage FILE > thumb.jpg     # the EXIF thumbnail
exiftool -b -PreviewImage FILE > preview.jpg     # larger embedded preview
exiftool -htmlDump FILE > dump.html              # annotated hex map (trailing data)

# Documents
exiftool -Author -Creator -Producer -CreateDate -ModifyDate FILE.pdf

# Write / delete (keeps FILE_original unless -overwrite_original)
exiftool -Comment="lab note" FILE      # set a tag
exiftool -GPS:all= FILE                # drop only GPS tags
exiftool -all= -overwrite_original FILE   # strip everything, no backup
exiftool -tagsFromFile SRC -all:all FILE  # copy every tag from another file

# Timestamps
exiftool "-AllDates+=0:0:0 1:0:0" FILE   # add one hour to all dates
exiftool '-FileName<CreateDate' -d '%Y%m%d_%H%M%S%%-c.%%e' FILE_DIR   # rename by date

# Batch + machine-readable
exiftool -r FILE_DIR                   # recurse a whole tree
exiftool -j FILE | jq .                # JSON for automation
exiftool -csv -Make -Model -CreateDate FILE_DIR/*.jpg   # table of a folder

Command breakdowns#

Each block below explains one situation, the exact command, and what to expect back. TARGET_FILE is one authorized file, TARGET_DIR a folder of them.

Dump every tag in a file#

exiftool TARGET_FILE

A two-column report of tag names and values. Skim for Comment, Author, GPS, and date fields. This is the right first move on any unknown artifact.

See which group each tag lives in#

exiftool -G1 TARGET_FILE

Prefixes like [EXIF], [XMP], [IPTC], [PDF] so duplicate-looking fields make sense and you know the group to target on a write.

Surface hidden or unknown tags#

exiftool -a -u -G1 TARGET_FILE

-a keeps duplicate tags, -u extracts unknown or undecoded ones, exactly where CTF authors stash a flag the default view drops.

Grep the metadata for a flag#

exiftool TARGET_FILE | grep -iE 'comment|flag|note|description|copyright'

Comment, Description, UserComment, and Copyright are the usual hiding spots. Piping to grep beats scrolling a long report by hand.

Pull GPS coordinates as decimal for a map#

exiftool -c "%.6f" -GPSPosition TARGET_FILE   # 40.446200 N, 79.982000 W
exiftool -n -GPSPosition TARGET_FILE          # 40.446200 -79.982000

Empty output means no GPS was stored. The -n (signed) form pastes straight into a maps search.

Find every file in a folder that has GPS#

exiftool -r -if '$GPSLatitude' -filename -gpsposition TARGET_DIR

-if filters to files where the tag exists; you get a short list of only the geotagged ones instead of wading through the whole tree.

Extract the embedded thumbnail or preview#

exiftool -b -ThumbnailImage TARGET_FILE > thumb.jpg
exiftool -b -PreviewImage TARGET_FILE > preview.jpg

-b dumps the raw tag value. The thumbnail is often the un-edited original, a classic reveal when someone cropped or painted over the full image but left the EXIF preview behind. PreviewImage is the larger sibling some cameras embed.

Read a PDF’s author, creator, and dates#

exiftool -Author -Creator -Producer -CreateDate -ModifyDate TARGET_FILE.pdf

Producer and Creator name the software (and often its version); a create date that disagrees with the modify date is itself a lead.

Write or change a tag#

exiftool -Comment="checked $(date -I)" TARGET_FILE

Prints 1 image files updated and saves the original as TARGET_FILE_original. Confirm the exact tag name with -s first if you are unsure it will land.

Strip all metadata before publishing#

exiftool -all= -overwrite_original TARGET_FILE

Rewrites the file with metadata removed. Re-read it to verify nothing survived: this is the defensive move against your own files leaking author names, paths, and GPS.

Strip only GPS, keep the rest#

exiftool -GPS:all= TARGET_FILE

Removes location without touching camera or timestamp data. Useful when the capture context is fine to share but the coordinates are not.

Copy metadata from one file to another#

exiftool -tagsFromFile SOURCE_FILE -all:all TARGET_FILE

Clones every tag onto TARGET_FILE, useful for restoring metadata after a lossy re-encode stripped it.

Batch a folder into a spreadsheet#

exiftool -csv -Make -Model -CreateDate -GPSPosition -r TARGET_DIR > report.csv

One row per file; open in a spreadsheet or diff against a suspected source device.

Rename photos by their capture date#

exiftool '-FileName<CreateDate' -d '%Y%m%d_%H%M%S%%-c.%%e' TARGET_DIR

Renames using each file’s own CreateDate. %%e keeps the extension, %%-c appends a copy number to avoid collisions.

Shift wrong timestamps#

exiftool "-AllDates+=0:0:0 1:0:0" TARGET_FILE

Adds one hour to DateTimeOriginal, CreateDate, and ModifyDate at once. Shift format is Y:M:D h:m:s; use -= to subtract, for a camera stuck on the wrong timezone.

Dump the raw file structure#

exiftool -htmlDump TARGET_FILE > dump.html

An annotated hex map of the file, the fast way to spot trailing or appended data hiding after the image’s real end.

Reading the output#

FieldWhy it matters
Comment / Description / UserCommentThe most common CTF hiding spot, read first
GPSPosition / GPSLatitude/LongitudeStrong OSINT lead, but trivially forged
Author / Creator / SoftwareWho made it and with what tool (often a version)
CreateDate vs ModifyDate vs file datesDisagreement between them is itself a finding
Same field across EXIF / XMP / IPTCNormal duplication, use -G1 to tell them apart
Empty value for a tagThe tag is absent, not an error

Troubleshooting#

ProblemCauseFix
command not foundNot installed / stale PATHReinstall; open a fresh shell
Error: File not foundWrong path or nameCheck the path; quote names with spaces
Warning: ... not supportedFormat is read-onlyReading works; that format cannot be written
Tag write does nothingWrong tag name or groupConfirm with -s; prefix the group (-EXIF:...)
Edit corrupts the fileUnsupported write targetRestore the _original; work on a copy
No metadata at allFile already strippedExpected for sanitized files; try carving tools
GPS reads back as DMS, not decimalDefault print conversionAdd -c "%.6f" or -n

Gotchas#

  • Editing writes in place. exiftool saves FILE_original by default, but -overwrite_original discards it silently. Keep source files read-only and edit copies.
  • -all= on a directory strips the whole tree. Test the write on one file before pointing it at TARGET_DIR.
  • A composite tag cannot be written. GPSPosition, ImageSize, and friends are derived from other tags; set the underlying GPSLatitude/GPSLongitude instead.
  • Stripping metadata drops the Orientation tag too. A phone photo that relied on EXIF orientation can render sideways in viewers after -all=; re-check rotation before you ship.
  • The same text hides under different names. Comment, UserComment, and XMP:Description are separate tags, so clearing one can leave a copy behind; re-read (or grep) before you trust a scrub.

Pairs with#

file gives a fast type guess before exiftool digs in, and strings pulls the printable text exiftool’s parsers skip. When a comment or odd tag hints the data is inside the image, hand off to steghide or binwalk to carve it out, and jq filters the -j JSON into exactly the fields you want. For sanitization-only jobs across many formats, mat2 is purpose-built and exiv2 is a lighter EXIF/IPTC/XMP reader, but exiftool wins on format breadth and batch editing.

Find us elsewhere

Merch, stickers, and moreSupport the work at the Solvere Labs shop