<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: performing-metadata-extraction
description: >-
  Extract metadata from documents, images, and files to reveal author names,
  software versions, GPS coordinates, internal paths, and organizational
  intelligence for OSINT investigations.
domain: cybersecurity
subdomain: osint-recon
tags:
  - metadata
  - exiftool
  - foca
  - document-analysis
  - geolocation
version: "1.0"
author: defconxt
license: AGPL-3.0
compatibility: >-
  exiftool, mat2, foca, metagoofil, pdfinfo, python-docx,
  Pillow (PIL).
metadata:
  mitre-attack:
    - "T1592.004"  # Gather Victim Host Information: Client Configurations
    - "T1589"      # Gather Victim Identity Information
    - "T1591"      # Gather Victim Org Information
---

# Performing Metadata Extraction

## Overview

Metadata embedded in documents, images, and files reveals information that
authors never intended to publish — usernames, software versions, internal
file paths, GPS coordinates, printer names, and revision history. Techniques
include EXIF extraction from images, document property analysis, PDF metadata
parsing, and bulk metadata harvesting from publicly accessible files.

## Prerequisites

- exiftool (comprehensive metadata extraction)
- mat2 (metadata removal/analysis)
- metagoofil for automated document harvesting
- Python 3.10+ with `Pillow`, `python-docx`, `PyPDF2`
- pdfinfo from poppler-utils

```bash
sudo apt install libimage-exiftool-perl mat2 poppler-utils
pip install Pillow python-docx PyPDF2 requests
```

## Quick Reference

| Task | Command |
|------|---------|
| All metadata | `exiftool file.pdf` |
| Recursive scan | `exiftool -r -csv ./documents/ > metadata.csv` |
| GPS from image | `exiftool -gps* image.jpg` |
| Strip metadata | `mat2 file.pdf` |
| PDF info | `pdfinfo document.pdf` |
| Metagoofil | `metagoofil -d example.com -t pdf,docx -l 100 -o files/` |
| Bulk extract | `exiftool -r -csv -Author -Creator -Producer -Software ./files/` |

## Workflow

### Step 1: Harvest Public Documents

```bash
# Metagoofil — automated document download and analysis
metagoofil -d example.com -t pdf,docx,xlsx,pptx -l 200 -o harvested/

# Manual Google dork + wget
# Find PDFs on target domain, then download
wget -q -r -l 1 -nd -A pdf "https://example.com/documents/"
```

### Step 2: Extract Metadata

```bash
# Comprehensive extraction for a single file
exiftool -a -u -g1 document.pdf

# Bulk CSV export — key fields
exiftool -r -csv -Author -Creator -Producer -Software -CreateDate \
  -ModifyDate -Company -LastModifiedBy ./harvested/ > metadata_report.csv

# Image EXIF with GPS
exiftool -gps* -DateTimeOriginal -Make -Model -Software photo.jpg

# PDF-specific metadata
pdfinfo document.pdf
```

### Step 3: Intelligence Extraction

Key metadata fields and their intelligence value:
- **Author/Creator**: Employee names, usernames
- **Company**: Organization name confirmation
- **Software/Producer**: Technology stack (MS Office version, Adobe, LibreOffice)
- **Internal paths**: `C:\Users\jdoe\Documents\` reveals usernames and OS
- **GPS coordinates**: Physical locations of photos
- **Printer name**: Internal infrastructure details
- **Revision count**: Document maturity and editing history

### Step 4: Automated Analysis

```python
from pathlib import Path
import subprocess
import json

def extract_metadata(filepath: str) -> dict:
    """Extract metadata using exiftool."""
    proc = subprocess.run(
        ["exiftool", "-j", filepath],
        capture_output=True, text=True, timeout=30,
    )
    if proc.returncode == 0:
        data = json.loads(proc.stdout)
        return data[0] if data else {}
    return {"error": proc.stderr}

def bulk_extract(directory: str) -> list[dict]:
    """Extract metadata from all files in a directory."""
    results = []
    for path in Path(directory).rglob("*"):
        if path.is_file() and path.suffix.lower() in {".pdf", ".docx", ".xlsx", ".jpg", ".png"}:
            meta = extract_metadata(str(path))
            results.append({"file": str(path), "metadata": meta})
    return results
```

### Step 5: Metadata Sanitization Check

```bash
# Check if metadata was stripped (defensive verification)
mat2 --show document.pdf

# Strip all metadata
mat2 document.pdf
# Creates document.cleaned.pdf
```

## Detection Opportunities

- Document downloads from web servers appear in access logs
- Metagoofil uses identifiable user-agent strings
- Bulk document access patterns indicate OSINT activity

## Verification

- [ ] Public documents harvested from target domain
- [ ] Metadata extracted with exiftool in structured format
- [ ] Author names and usernames catalogued
- [ ] Software versions and internal paths documented
- [ ] GPS coordinates extracted from images when present
- [ ] Results aggregated into intelligence report

## References

- [ExifTool](https://exiftool.org/)
- [mat2](https://0xacab.org/jvoisin/mat2)
- [Metagoofil](https://github.com/laramies/metagoofil)
- [FOCA](https://github.com/ElevenPaths/FOCA)

---
v1.0 | Validated: 2026-03-17
