Social Media-to-Map-to-Stego-to-Chat Pivot: Multi-Modal OSINT Chain Across Four Data Domains
Theory
Why This Matters
In 2022, Bellingcat and the New York Times used image geolocation to trace the source of artillery strikes in Ukraine to within metres, comparing crater angles, soil composition, tree species, and distant landmarks visible in geotagged photos shared to Telegram. The same multi-discipline approach — extracting GPS data from EXIF, cross-referencing visual landmarks against satellite imagery, and pivoting from a geolocation to a chat platform account — is used by fraud analysts to confirm the physical location of scam call centres, by law enforcement to identify the origin of CSAM images, and by corporate investigators to verify that a remote employee is actually operating from the country they claim. In CTF intelligence challenges, the fusion of geolocation, steganography, and chat platform analysis into a single chain tests the analyst's ability to pivot across technical disciplines without losing the investigative thread.
Core Concept
EXIF (Exchangeable Image File Format) metadata is embedded in JPEG, TIFF, and many RAW image files by the capturing device. The GPS fields — GPSLatitude, GPSLongitude, GPSAltitude, GPSDateStamp — directly encode where and when the photo was taken. The Make, Model, and Software fields identify the camera or phone. DateTimeOriginal records the capture time. Many social platforms strip EXIF on upload (Facebook, Twitter, Instagram), but Telegram, Discord (direct file attachments), and many forums preserve it. exiftool is the canonical command-line tool for reading and writing EXIF across hundreds of file formats.
Visual geolocation (the methodology used by Bellingcat and GeoGuessr professionals) does not require GPS metadata. It instead matches visual clues in an image against satellite and street-level imagery: sun angle and shadow direction (indicating time of day and compass direction), visible signage and language, architectural style, vegetation species, road marking conventions, vehicle licence plate formats, and distant landmarks. Geospy.ai applies machine-learning-based geolocation to images without EXIF, producing a likely country and region. Google Earth and Bing Maps aerial/street views are used to confirm specific sites.
Steganography is the concealment of data within an innocuous carrier. In image steganography, the most common method is LSB (Least Significant Bit) substitution: the lowest-order bit of each pixel's colour channel is replaced with a payload bit, creating changes invisible to the human eye. steghide embeds and extracts data in JPEG files with optional passphrase protection. zsteg detects LSB steganography in PNG and BMP files by analysing the statistical distribution of bit planes. stegsolve provides a GUI for examining bit planes visually.
Chat platform metadata includes message timestamps (timezone inference from UTC offset patterns), user join dates, server/channel creation dates, user ID numbers (Discord user IDs encode a creation timestamp via the Snowflake ID format), and any linked accounts in user bios. A Discord user ID can be decoded to a precise creation datetime, and a Telegram forwarded message retains the original sender's account ID even if they have since deleted their account.
The intelligence value of this chain lies in fusion: a photo with stripped EXIF may still contain steganographic data pinpointing a location, and a chat message timestamp combined with the geolocation may confirm a suspect was at a specific place at a specific time.
Technical Deep-Dive
# Phase 1: EXIF extraction with exiftool
exiftool suspect_image.jpg
# Key fields:
# GPS Latitude : 51 deg 30' 26.40" N
# GPS Longitude : 0 deg 7' 39.60" W
# GPS Altitude : 12 m Above Sea Level
# Date/Time Original : 2024:03:15 14:22:07
# Make : Apple
# Model : iPhone 14 Pro
# Software : 17.2.1
# Convert GPS to decimal degrees (for map lookup):
python3 -c "
lat_d, lat_m, lat_s = 51, 30, 26.40
lon_d, lon_m, lon_s = 0, 7, 39.60
lat = lat_d + lat_m/60 + lat_s/3600
lon = -(lon_d + lon_m/60 + lon_s/3600) # West = negative
print(f'{lat:.6f}, {lon:.6f}')
"
# Output: 51.507333, -0.127667 => Central London (Trafalgar Square area)
# Phase 2: Steganography detection
# LSB detection in PNG/BMP:
zsteg suspect_image.png
# b1,rgb,lsb,xy .. text: "hidden message here"
# b2,r,lsb,xy .. <binary data>
# steghide extraction (JPEG, requires passphrase or brute force):
steghide extract -sf suspect_image.jpg -p "" # try empty passphrase
steghide extract -sf suspect_image.jpg -p "password" # known passphrase
# stegseek — fast steghide brute force with wordlist:
stegseek suspect_image.jpg /usr/share/wordlists/rockyou.txt
# Phase 3: Discord Snowflake ID timestamp decode
python3 -c "
snowflake = 1234567890123456789
timestamp_ms = (snowflake >> 22) + 1420070400000 # Discord epoch
import datetime
dt = datetime.datetime.fromtimestamp(timestamp_ms / 1000, tz=datetime.timezone.utc)
print(dt.isoformat())
"
# Reveals: account creation datetime from any Discord user/message/server ID
# Phase 4: Image geolocation pipeline (when EXIF is stripped)
# 1. Submit to geospy.ai via browser upload
# 2. Cross-reference predicted location in Google Earth (street view)
# 3. Identify landmarks: use Overpass Turbo (overpass-api.de) to query OSM features
curl -s "https://overpass-api.de/api/interpreter"
--data '[out:json];node(around:500,51.507333,-0.127667)[amenity=pub];out;'
| python3 -m json.tool | grep '"name"'
# Batch EXIF extractor and coordinate mapper
import subprocess, json, re
def extract_gps(filepath):
"""Return (lat, lon) as decimals, or None if no GPS data."""
result = subprocess.run(
["exiftool", "-json", "-GPSLatitude", "-GPSLongitude",
"-GPSLatitudeRef", "-GPSLongitudeRef", filepath],
capture_output=True, text=True
)
data = json.loads(result.stdout)
if not data:
return None
d = data[0]
if "GPSLatitude" not in d:
return None
def dms_to_dec(dms_str, ref):
nums = re.findall(r"[d.]+", dms_str)
dec = float(nums[0]) + float(nums[1])/60 + float(nums[2])/3600
return -dec if ref in ("S", "W") else dec
lat = dms_to_dec(str(d["GPSLatitude"]), d.get("GPSLatitudeRef","N"))
lon = dms_to_dec(str(d["GPSLongitude"]), d.get("GPSLongitudeRef","E"))
return (lat, lon)
coords = extract_gps("suspect_image.jpg")
if coords:
print(f"https://maps.google.com/maps?q={coords[0]},{coords[1]}")
Intelligence Collection Methodology
- Acquire and preserve all image files from the chat platform or forum without modification. Hash each file immediately (
sha256sum image.jpg) to establish a forensic baseline before any analysis tools are run. - Run exiftool on every image:
exiftool -all suspect_image.jpg. Record GPS coordinates, timestamps, device information, and any custom metadata fields. Convert GPS coordinates from degrees-minutes-seconds to decimal format for map lookup. - Confirm the geolocation by opening the decimal coordinates in Google Earth. Cross-reference with street view and satellite imagery to identify specific buildings, intersections, or landmarks visible in the image.
- Check for steganographic content: run
zsteg(PNG/BMP) andsteghide extractwith empty passphrase (JPEG). If protected, runstegseekwith rockyou.txt. Note any extracted payloads for further analysis. - Analyse chat platform metadata: decode any Discord Snowflake IDs (user, message, server IDs) to recover creation timestamps. Note message UTC timestamps and infer subject timezone from posting patterns over multiple messages.
- Cross-reference the geolocation with the chat account: if the image GPS places the subject in a specific city, search the chat platform for the same account's bio, linked social profiles, or self-reported location for corroboration or contradiction.
- Pivot from the image to the chat account: reverse image search the profile photo across Google Images, TinEye, and Yandex. Correlate the geolocation data with any other known indicators of the subject's physical location from other intelligence threads.
- Compile the fusion picture: document the chain — image source → EXIF GPS → map confirmation → steganographic payload (if any) → chat account metadata → cross-platform corroboration — with evidence at each step.
Common Intelligence Collection Errors
- Assuming EXIF is always present or always absent: Some platforms strip EXIF; others preserve it selectively (Telegram preserves EXIF on direct file sends but strips it from the "Send as Photo" compressed mode). Always test both send modes; never assume.
- Misinterpreting GPS degree-minute-second format as decimal:
51 deg 30' 26.40" Nis NOT51.3026in decimal degrees. Converting incorrectly places the location thousands of kilometres from the actual site. Always use the proper DMS-to-decimal formula. - Running only one steganography tool and concluding no hidden content: steghide, zsteg, and stegsolve detect different encoding methods. A file clean in steghide may contain zsteg-detectable LSB payload. Always run the full steganography detection suite.
- Ignoring the timezone implied by Snowflake ID timestamps: Discord Snowflake timestamps are UTC. If a message was sent at UTC 03:00, the subject's local time depends on their timezone, which may be inferred from their other posting patterns. Failing to account for UTC versus local time produces incorrect timeline reconstructions.
- Using only Google Images for reverse image search and missing Yandex hits: Yandex Images uses a different facial recognition and perceptual hashing algorithm that frequently surfaces Eastern European platform profiles, older cached pages, and social network images that Google misses. Always run all three (Google, TinEye, Yandex) before concluding no reverse-image match exists.
- Treating a visual geolocation estimate as precise coordinates: GeoSpy and manual visual geolocation produce an estimated area, not a precise GPS fix. The confidence interval may span a city block or an entire neighbourhood. Do not present visual geolocation as GPS-precision evidence without explicit uncertainty quantification.
NICE Framework Alignment
| Code | Knowledge/Skill/Task Statement | How This Card Develops It |
|---|---|---|
| K0058 | Knowledge of network protocols | Understanding how chat platforms transmit and store image metadata, and how Discord's Snowflake ID encodes timestamps within its API response structure |
| K0145 | Knowledge of security assessment approaches | Applying the multi-discipline OSINT fusion chain — EXIF extraction, visual geolocation, steganography detection, chat metadata analysis — as a structured intelligence collection workflow |
| K0272 | Knowledge of network security architecture | Recognising how image metadata and chat platform identifier structures create unintended location and temporal intelligence exposure |
| K0427 | Knowledge of encryption algorithms | Understanding steghide's passphrase-based AES encryption of hidden payloads and how stegseek performs wordlist-based key recovery |
| S0040 | Skill in identifying and extracting data of interest | Extracting GPS coordinates, device fingerprints, creation timestamps, and steganographic payloads from image and chat metadata |
| T0569 | Apply and utilize authorized cyber capabilities to achieve objectives | Executing the EXIF-geolocation-steganography-chat fusion chain using exiftool, zsteg, steghide, stegseek, and Discord Snowflake decoding within an authorised collection mandate |
Further Reading
- An Introduction to Digital Image Steganography — Neil F. Johnson & Sushil Jajodia (IEEE Multimedia, 1998)
- Geolocation for Journalists and Investigators — Bellingcat, bellingcat.com/resources (Eliot Higgins)
- Exiftool Documentation — Phil Harvey, exiftool.org (comprehensive EXIF tag reference)
Challenge Lab
Reinforce your learning with a hands-on generated challenge based on this card's competency.