Main Menu

Quicktime keys

Started by Titanzi, February 07, 2025, 07:30:25 AM

Previous topic - Next topic

Titanzi

Hi,
Im trying to answer a question from my investigator in an DFIR case. I have a suspicion that the videoclip might have an altered metadata timestamp.
When running exiftool with the handle -k -G1 I get that the file has an create date from [quicktime] that is, lets say 2022-01-01 but the creation date from [keys] is 2021-11-11 (the dates are fake but the situation is the same). My question is if I'm able to say anything from that regarding a modified create date. Or at least which one of the two might be more true than the other?

Kindly
Titanzi

StarGeek

I'm guessing that you might be drag/dropping files on to exiftool icon on the desktop due to the existence of the -k (pause) option. If so, I would suggest renaming the icon to include a few more options
exiftool(-k -a -s -G1).exe
This will show you more information (see FAQ #3)

There really isn't an easy way to tell if one tag is more accurate than the other, especially if the time stamps are that far apart. One thing to remember is that the Quicktime:CreateDate is a UTC time stamp while the Quicktime:CreationDate (aka Keys:CreationDate) is a local time stamp, so the time stamps should differ by the time zone, i.e. a video shot on the West Coast USA would have a CreationDate 7/8 hours different from the CreateDate.

To verify that the metadata was edited for certain, you would have to compare way the data is structured in the file between the questionable file and a file from the same source. Different programs write metadata in different ways, so there might be differences in the order or in the padding between data.

I don't believe that the Quicktime:CreationDate tag will be set in most videos unless it was originally from an Apple product (e.g. iPhone), though @wywh will have to verify. In that case there should probably be some Apple specific tags in the file. Apple specific tags are not editable for the most part as there isn't a tool that will edit them.

What I can tell you is some things to look for to see if the video itself was edited with a program such as ffmpeg. Most modern cameras will insert EXIF data into a video and if the GPS is on, there might be a GPS track embedded as well. Because these are non-standard, any editing of the video will remove them. The command to check would be
exiftool -G1 -a -s -EXIF:All -GPS* file.mp4

The existence of these tags means it is quite unlikely that video itself has been edited, though the metadata might still have been altered. It would take someone with the skill to create tools to copy the data, as tools to do so don't currently exist, AFAIK.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

wywh

#2
All .mp4, .m4v and .mov movies have QuickTime:CreateDate.

iOS (8.4)-9 and newer and iPadOS insert Keys:CreationDate (a.k.a. QuickTime:CreationDate) to its movies and in Apple's apps it overrides all other date tags. It seems Android movies might have UserData:DateTimeOriginal which behaves the same (Photos.app ignores UserData:DateTimeOriginal in .mov).

QuickTime:CreateDate (and TrackCreateDate, MediaCreateDate) is the recording start UTC time. QuickTime:ModifyDate (and TrackModifyDate, MediaModifyDate) is the recording end UTC time.

Keys:CreationDate is the recording start local time which should include a time zone. It usually matches QuickTime:CreateDate or sometimes it might be 1 second earlier.

-> I did a quick test by editing movie dates in iPadOS 18.3 iOS 16.7.10 and exported to macOS 15.3.

a) All metadata edits are ignored with Airdrop export > Options > All Photos Data, or Importing via USB to Image Capture.app or to Photos.app (*).

b) AirDrop default export option exports metadata and pixel edits done in iPhone/iPad Photos:

QuickTime:CreateDate (and TrackCreateDate, MediaCreateDate) and QuickTime:ModifyDate (and TrackModifyDate, MediaModifyDate) are the AirDrop time.
Keys:CreationDate is the edited time.

-> This seems be a moving target because AFAIR a few years ago when I tested this, AirDrop default export option resulted in QuickTime:CreateDate being the edited time and Keys:CreationDate the original time.

(*) If pixel edits are done on iPhone/iPad Photos and the movie is exported with Airdrop's All Photos Data option, then the Mac receives a triplet of original IMG_0001.MOV, edited IMG_E0001.mov and IMG_0001.AAE sidecar describing the edits which Photos.app can import and continue or revert to the original. The .AAE sidecar's AdjustmentTimestamp is the time the user has done the pixel edits in the mobile device:

[XML]           AdjustmentTimestamp             : 2025:02:08 10:44:30Z
...but weirdly the pixel-edited IMG_E0001.mov has the original Keys:CreationDate instead the edited date that I'd expect to be in that version.

AFAIK .AAE comes from "Apple Aperture Edits", "Apple Aperture Extension", or something like that relating to the old Aperture.app.

.AAE sidecars contain edit info base64 encoded and zlib compressed but there seems to be no date info there. FWIW recently a user stumbled on a .AAE generated by 3rd party app, and its presence caused Photos.app silently fail to import images (as an old Photos.app bug .xmp sidecars do the same for imported movies if they happen to be in the same folder <sigh>).

BTW for fun I just made a python script below which should convert .AAE files' adjustmentData section to a more readable .plist format. (The final step to convert .plist to a more readable xml1 .plist format uses macOS /usr/bin/plutil so it does not work in Windows but there might be a built-in python option like plistlib to do that there. My two youngest are having python course in high school math so I try to have some knowledge about it and practiced with that script).
AAE_to_plist.py
- Matti

Phil Harvey

Hi Matti,

Quote from: wywh on February 08, 2025, 07:06:02 AMI just made a python script below which should convert .AAE files' adjustmentData section to a more readable .plist format.

Nice.  But you should let me know if there is something useful ExifTool isn't decoding.  ExifTool 13.19 will decode this.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Titanzi

So if I understand correctly, there are no way for an awerage user to edit/resave the file to edit the meta data timestaps? Nor is there a way to fool the original metadata by adjusting the time manually on the phone and resave the file with the edited timestapms? That would still result in the correct time been shown in the metadata. Albeit the modified time stamp would be the "suspect" timedata?
With this, a) All metadata edits are ignored with Airdrop export > Options > All Photos Data, or Importing via USB to Image Capture.app or to Photos.app (*). would mean that the dates i have gotten from the file are the true dates and are not edited?

wywh

Quote from: Titanzi on February 10, 2025, 12:34:54 AMthere are no way for an awerage user to edit/resave the file to edit the meta data timestaps?
By "average user" do you mean using only the built-in Apple's apps available in an iPhone? I presumed it would be difficult if the movies were then transferred via USB or AirDrop's All Photos Data option (Which transfers also the originals. But how would you know which option was used for the transfer?) but now I remembered yet another option:

c) Change date in iOS Photos > Save to iPhone Files (and delete from Photos) > AirDrop from Files (no extra user options available via this route. The result is the same if the user saves back to iPhone Photos and AirDrops via its Default or All Photos Data option. I.e. via this route Keys:CreationDate is forced to the edited time):

QuickTime:CreateDate (and TrackCreateDate, MediaCreateDate) and QuickTime:ModifyDate (and TrackModifyDate, MediaModifyDate) are the AirDrop time.
Keys:CreationDate is the edited time.

It very much matters which route the movie has gone (USB, AirDrop options, social media) so the time stamps might not be original. And iOS versions also seem to matter how the edited dates behave. On the computer it is very easy to change all movie date tags.

Titanzi

The file was shared via airdrop to the officer and the officer has then transfered the file to me.
I think I'll use the standard legal term "It depends" and call it a day. I don't think I will be able to say either way since I don't have the phone from the person sharing the file and have no way of trying to trace the original.
Thanks for all the input, it was a good learning experience. I bett I'll be back here more, a lot of questions, as you might know, are around creation and modification of files.

wywh

Quote from: Phil Harvey on February 08, 2025, 09:09:51 AM
Quote from: wywh on February 08, 2025, 07:06:02 AMI just made a python script below which should convert .AAE files' adjustmentData section to a more readable .plist format.
ExifTool 13.19 will decode this.

exiftool 13.19 displays the attached .AAE from iPadOS 18.3 Photos like this:

exiftool -a -G1 -s -ee IMG_0798.AAE
[ExifTool]      ExifToolVersion                 : 13.19
[ExifTool]      Warning                         : XMP format error (no closing tag for O??)
[File]          FileType                        : AAE
[File]          FileTypeExtension               : aae
[File]          MIMEType                        : application/vnd.apple.photos
[XML]           AdjustmentBaseVersion           : 0
[XML]           AdjustmentEditorBundleID        : com.apple.camera
[XML]           AdjustmentFormatIdentifier      : com.apple.photo
[XML]           AdjustmentFormatVersion         : 1.5.1
[XML]           AdjustmentRenderTypes           : 16384
[XML]           AdjustmentTimestamp             : 2025:02:07 05:28:21Z

Can it also display Photos adjustmentData from the base64 encoded and zlib compressed section between <data>xVjb...Lw==</data> of the .AAE?

After executing the python script attached in my previous post the decoded .plist additionally displays as (lightMap section is still somehow scrambled, though):

python AAE_to_plist.py
Enter .AAE file name: IMG_0798.AAE
✅ Raw deflate decompression successful using window size -15.
✅ Data saved as IMG_0798.plist
✅ Successfully converted IMG_0798.plist to XML format.

exiftool -a -G1 -s IMG_0798.plist 
[File]          FileType                        : PLIST
[File]          FileTypeExtension               : plist
[File]          MIMEType                        : application/xml
[XML]           AdjustmentsEnabled              : True
[XML]           AdjustmentsFormatIdentifier     : com.apple.photo
[XML]           AdjustmentsFormatVersion        : 1
[XML]           AdjustmentsIdentifier           : WhiteBalance
[XML]           AdjustmentsSettingsAuto         : False
[XML]           AdjustmentsSettingsColorType    : 3
[XML]           AdjustmentsSettingsFaceI        : 0
[XML]           AdjustmentsSettingsFaceQ        : 0
[XML]           AdjustmentsSettingsFaceStrength : 0
[XML]           AdjustmentsSettingsFaceWarmth   : 0
[XML]           AdjustmentsSettingsGrayI        : 0
[XML]           AdjustmentsSettingsGrayQ        : 0
[XML]           AdjustmentsSettingsGrayWarmth   : 0
[XML]           AdjustmentsSettingsGrayY        : 0
[XML]           AdjustmentsSettingsTemperature  : 5000
[XML]           AdjustmentsSettingsTint         : 0
[XML]           AdjustmentsSettingsWarmFace     : False
[XML]           AdjustmentsSettingsWarmTemp     : 0.28611111111111109
[XML]           AdjustmentsSettingsWarmTint     : 1
[XML]           AdjustmentsEnabled              : True
[XML]           AdjustmentsFormatIdentifier     : com.apple.photo
[XML]           AdjustmentsFormatVersion        : 1
[XML]           AdjustmentsIdentifier           : DGVignetteEffectOperation
[XML]           AdjustmentsSettingsAuto         : False
[XML]           AdjustmentsSettingsInputKeysInputFalloff: 0
[XML]           AdjustmentsSettingsInputKeysInputIntensity: 1
[XML]           AdjustmentsSettingsInputKeysInputRadius: 0.40000000000000002
[XML]           AdjustmentsEnabled              : True
[XML]           AdjustmentsFormatIdentifier     : com.apple.photo
[XML]           AdjustmentsFormatVersion        : 1
[XML]           AdjustmentsIdentifier           : DGDefinition2Operation
[XML]           AdjustmentsSettingsAuto         : False
[XML]           AdjustmentsSettingsInputKeysInputIntensity: 0.61111111111111116
[XML]           AdjustmentsEnabled              : True
[XML]           AdjustmentsFormatIdentifier     : com.apple.photo
[XML]           AdjustmentsFormatVersion        : 1
[XML]           AdjustmentsIdentifier           : RKNoiseReductionOperation
[XML]           AdjustmentsSettingsAuto         : False
[XML]           AdjustmentsSettingsInputKeysInputEdgeDetail: 1.5
[XML]           AdjustmentsSettingsInputKeysInputRadius: 2.2333333333333334
[XML]           AdjustmentsEnabled              : True
[XML]           AdjustmentsFormatIdentifier     : com.apple.photo
[XML]           AdjustmentsFormatVersion        : 1
[XML]           AdjustmentsIdentifier           : SmartColor
[XML]           AdjustmentsSettingsAuto         : False
[XML]           AdjustmentsSettingsInputColor   : 0
[XML]           AdjustmentsSettingsOffsetCast   : 0
[XML]           AdjustmentsSettingsOffsetContrast: 0.95555555555555549
[XML]           AdjustmentsSettingsOffsetSaturation: 0.76111111111111107
[XML]           AdjustmentsSettingsStatisticsSatAutoValue: 0.10980391502380371
[XML]           AdjustmentsSettingsStatisticsSatPercentile75: 0.29803922772407532
[XML]           AdjustmentsSettingsStatisticsSatPercentile98: 0.89019608497619629
[XML]           AdjustmentsSettingsStatisticsSatPercentileG98: 0.88627451658248901
[XML]           AdjustmentsEnabled              : True
[XML]           AdjustmentsFormatIdentifier     : com.apple.photo
[XML]           AdjustmentsFormatVersion        : 1
[XML]           AdjustmentsIdentifier           : RKProSharpenOperation
[XML]           AdjustmentsSettingsAuto         : False
[XML]           AdjustmentsSettingsInputKeysInputEdgeScale: 1
[XML]           AdjustmentsSettingsInputKeysInputFalloff: 1
[XML]           AdjustmentsSettingsInputKeysInputSharpness: 0.91666666666666663
[XML]           AdjustmentsEnabled              : True
[XML]           AdjustmentsFormatIdentifier     : com.apple.photo
[XML]           AdjustmentsFormatVersion        : 1
[XML]           AdjustmentsIdentifier           : SmartTone
[XML]           AdjustmentsSettingsAuto         : False
[XML]           AdjustmentsSettingsInputLight   : 0
[XML]           AdjustmentsSettingsOffsetBlackPoint: 0.083333333333333273
[XML]           AdjustmentsSettingsOffsetBrightness: -0.31666666666666665
[XML]           AdjustmentsSettingsOffsetContrast: -0.41111111111111109
[XML]           AdjustmentsSettingsOffsetExposure: 0.38888888888888884
[XML]           AdjustmentsSettingsOffsetHighlights: -0.52500000000000002
[XML]           AdjustmentsSettingsOffsetLocalLight: 0.79722222222222228
[XML]           AdjustmentsSettingsOffsetShadows: 0.45277777777777772
[XML]           AdjustmentsSettingsStatisticsAutoValue: 0.34080000000000005
[XML]           AdjustmentsSettingsStatisticsBlackPoint: 0.0031976514035982188
[XML]           AdjustmentsSettingsStatisticsHighKey: 0.87995215717157216
[XML]           AdjustmentsSettingsStatisticsLightMap: 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
[XML]           AdjustmentsSettingsStatisticsLightMapAvg: HDM=
[XML]           AdjustmentsSettingsStatisticsLightMapHeight: 31
[XML]           AdjustmentsSettingsStatisticsLightMapWidth: 31
[XML]           AdjustmentsSettingsStatisticsLocalAutoValue: 0.36240000000000006
[XML]           AdjustmentsSettingsStatisticsP02: 0.0039215686274509795
[XML]           AdjustmentsSettingsStatisticsP10: 0.0039215686274509795
[XML]           AdjustmentsSettingsStatisticsP25: 0.011764705882352941
[XML]           AdjustmentsSettingsStatisticsP50: 0.031372549019607836
[XML]           AdjustmentsSettingsStatisticsP98: 0.59607843137254901
[XML]           AdjustmentsSettingsStatisticsTonalRange: 0.044890761414808751
[XML]           AdjustmentsSettingsStatisticsWhitePoint: 0.98039215686274506
[XML]           FormatVersion                   : 1
[XML]           MetadataMasterHeight            : 3024
[XML]           MetadataMasterWidth             : 4032
[XML]           MetadataOrientation             : 1
[XML]           VersionInfoAppVersion           : 4026.82.9
[XML]           VersionInfoBuildNumber          : 22D63
[XML]           VersionInfoPlatform             : iOS
[XML]           VersionInfoSchemaRevision       : 0
IMG_0798.AAE
- Matti

Phil Harvey

Hi Matti,

Great, thanks.  I didn't have a sample like this.

I have another sample where the same tag is used to store a Base64-encoded binary PLIST object.  This time it is Base64-encoded Zlib-compressed-with-no-header JSON data.

I'll add the ability to decode this in Version 13.20.  The LightMap will be further Base64-decoded, and left as binary data.

It seems from your python code that PLIST files may also be JSON format? (as well as binary or xml)?  Is this true?  If so, do you have other examples?  I should probably add support.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

wywh

Quote from: Phil Harvey on February 11, 2025, 02:30:02 PMdo you have other examples?
All my current iOS 16.7.10 and iPadOS 18.3 .AAE files are similar to that sample above (I just happened to use plutil to output .plist as xml so json might be a more proper way to do that).

But attached is a different .AAE (and the related .jpg) from Hipstamatic in which the base64 section is not compressed.

The owner of that sample .AAE asked why macOS 12 Photos.app refused to import images and the culprit was .AAE like that. Its presence causes also macOS 15 Photos.app silently fail to import its master .jpg and sometimes other random or even all images in the import folder silently fail to import (as an old bug the same happens if a movie happens to have sidecar .xmp).
MCSN8042.AAE
MCSN8042.jpg
- Matti

Phil Harvey

Hi Matti,

Thanks.  I do have samples of the Base64-encoded, uncompressed binary PLIST AdjustmentData, and ExifTool 13.19 should handle these.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

wywh

#11
Thanks, v13.20 displays both .AAE types OK.

In Apple's .AAE files the adjustmentData section is base64 encoded and zlib compressed JSON.

But in at least that 3rd party .AAE file the adjustmentData section is base64 encoded PLIST with no compression. Maybe the current macOS Photos.app chokes on that and fails to import the relating image.

- Matti