Description
The judge for these pictures is a real fan of antiques. Can you age this photo to the specifications? Set the timestamps on this picture to 1970:01:01 00:00:00.001+00:00 with as much precision as possible for each timestamp. In this example, +00:00 is a timezone adjustment. Any timezone is acceptable as long as the time is equivalent. As an example, this timestamp is acceptable as well: 1969:12:31 19:00:00.001-05:00. For timestamps without a timezone adjustment, put them in GMT time (+00:00). The checker program provides the timestamp needed for each.
Setup
Download original.jpg, rename it to original_modified.jpg, and keep a backup.
Install exiftool and a hex editor (Bless works well on Linux).
wget https://artifacts.picoctf.net/c_mimas/91/original.jpg -O original_modified.jpgSolution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1Set EXIF sub-second fields
ObservationThe checker wants millisecond precision, the .001 part, in every timestamp. exiftool's -AllDates does not reach that, so set the SubSec tags explicitly.Use exiftool to set SubSecCreateDate, SubSecDateTimeOriginal, and SubSecModifyDate to 1970:01:01 00:00:00.001. The checker verifies each field independently.bashexiftool -SubSecCreateDate='1970:01:01 00:00:00.001' \ -SubSecDateTimeOriginal='1970:01:01 00:00:00.001' \ -SubSecModifyDate='1970:01:01 00:00:00.001' original_modified.jpgWhat didn't work first
Tried: Use exiftool -AllDates='1970:01:01 00:00:00.001' to set all timestamps in one flag.
-AllDates writes only the three standard EXIF fields and skips the sub-second tags entirely. The checker validates each SubSec field separately, so they keep their original values and every one of them fails.
Tried: Set the timestamp without the millisecond component: exiftool -SubSecCreateDate='1970:01:01 00:00:00' .
Sub-seconds are stored as a fractional suffix on the time string. Leave off the .001 and the field ends up blank or zero, which the checker reports as unset or mismatched even though the date itself is right.
Learn more
EXIF (Exchangeable Image File Format) embeds metadata inside JPEG, TIFF, and other image formats. Every camera and smartphone writes dozens of fields (shutter speed, GPS, camera model, multiple timestamps) into the file before the pixel data.
Timestamps live in several fields:
DateTimeOriginal(when the shutter fired),CreateDate(file creation), andModifyDate(last edit). The-AllDatesflag covers these standard EXIF fields in one shot, but it skips Samsung-proprietary blocks likeImage_UTC_Data, which is why hex editing is needed in the next step.In digital forensics, timestamps are crucial evidence. Investigators compare EXIF timestamps against file-system timestamps (
mtime,atime,ctime) and network logs to build timelines. Knowing how to manipulate (and detect manipulation of) these fields is a core skill on both sides.Step 2Patch Samsung:TimeStamp
ObservationOne timestamp still fails after every standard SubSec field is set. A vendor block outside the EXIF IFD, Samsung's Image_UTC_Data, holds its own millisecond Unix timestamp, and only a hex editor reaches it.Open the JPEG in Bless. Search for the ASCII string Image_UTC_Data; the 13-digit number that follows it (e.g. 1700513181420) is the millisecond timestamp. Replace the digits with 0000000000001 (epoch + 1 ms), keeping the byte length identical.Learn more
Many Android manufacturers embed proprietary metadata blocks in JPEG files that sit outside the standard EXIF IFD structure. Samsung's
Image_UTC_Datablock stores a Unix timestamp in milliseconds as a plain decimal ASCII string embedded in the file's bytes.To find the field in a hex editor, search for the ASCII string
Image_UTC_Data. The 13-digit decimal number immediately after the label is the millisecond timestamp. Overwrite just those digits in place so the file size stays identical; otherwise the JPEG offsets shift and the structure breaks.The target value
0000000000001is 1 millisecond past Unix epoch (1970-01-01 00:00:00.001 UTC), matching the EXIF fields you set in the previous step. Tools likegrep -b(byte-offset grep) or Python'sbytes.find()can locate the pattern programmatically if you prefer scripting to a GUI hex editor.Step 3Submit and verify
ObservationThere are two ports, one for upload and one for the checker. Pipe the raw file bytes to the upload port with netcat, then connect separately to the checker to see whether every timestamp matched.Pipe the modified file to the uploader port, then connect to the checker. Once every timestamp reads 1970:01:01 00:00:00.001, the checker prints the flag.bashnc -w 2 mimas.picoctf.net <UPLOAD_PORT_FROM_INSTANCE> < original_modified.jpg \ && nc -d mimas.picoctf.net <CHECKER_PORT_FROM_INSTANCE>Expected output
picoCTF{71m3_7r4v311ng_p1c7ur3_12e0...}What didn't work first
Tried: Upload the original.jpg file directly to the checker port instead of original_modified.jpg.
The checker reads timestamps from whichever file you send it. Send the untouched original and every field still holds the camera's shoot date, so all of them come back wrong. Apply the rename and the edits to the file you actually pipe over.
Tried: Connect to the upload port and the checker port simultaneously in one netcat command using a pipe.
The upload port takes raw file bytes; the checker port is a separate service that reports back afterwards. Chain them with a pipe and the checker's response bytes flow back into the upload socket and corrupt it. Run two netcat calls instead, one redirecting the file in, then a read-only connection to the checker.
Learn more
netcat (
nc) is the Swiss army knife of networking. The<redirection feeds the file's raw bytes directly into the TCP stream, which is how binary upload services typically work over a raw socket.-w 2sets a 2-second idle timeout so netcat doesn't hang after the server stops sending data.-don the checker connection disables stdin entirely from the outset, so netcat does not block waiting for terminal input that will never come.Using two separate netcat connections (one to upload, one to check) is a common CTF pattern where submission and verification run on different ports. The same raw socket pattern shows up in real assessments when probing custom protocols or pushing files to embedded devices.
Interactive tools
- Image Metadata ViewerRead EXIF, XMP, JPEG comments, and PNG tEXt / iTXt / zTXt chunks from images entirely in the browser. Highlights flag-like values.
Flag
Reveal flag
picoCTF{71m3_7r4v311ng_p1c7ur3_12e0...}
Once every timestamp reads 1970:01:01 00:00:00.001, the checker returns the flag above.