ExifTool Forum

ExifTool => Bug Reports / Feature Requests => Topic started by: PoP on November 04, 2022, 10:48:08 AM

Title: Feature Request: Further decode "Zone Identifier" streams
Post by: PoP on November 04, 2022, 10:48:08 AM
When most Browsers download an image from the Internet they create a Zone Identifier which might be useful to identify the source of the download.

Currently Exiftool only displays Exists on such files.
QuoteH:\z>exiftool -S image.jpg
ExifToolVersion: 12.49
FileName: image.jpg
Directory: .
FileSize: 39 kB
ZoneIdentifier: Exists
FileModifyDate: 2022:11:04 09:38:34-04:00
FileAccessDate: 2022:11:04 10:08:45-04:00
FileCreateDate: 2022:11:04 09:38:34-04:00
FilePermissions: -rw-rw-rw-
FileType: JPEG
FileTypeExtension: jpg
MIMEType: image/jpeg
JFIFVersion: 1.01
ResolutionUnit: None
XResolution: 1
YResolution: 1
ImageWidth: 736
ImageHeight: 736
EncodingProcess: Progressive DCT, Huffman coding
BitsPerSample: 8
ColorComponents: 3
YCbCrSubSampling: YCbCr4:2:0 (2 2)
ImageSize: 736x736
Megapixels: 0.542

H:\z>


Would it be possible to further decode this additional stream (similarly to the following Microsoft Power Shell decode):

QuotePS H:\z> Get-Item -path image.jpg -stream *


PSPath        : Microsoft.PowerShell.Core\FileSystem::H:\z\image.jpg::$DATA
PSParentPath  : Microsoft.PowerShell.Core\FileSystem::H:\z
PSChildName   : image.jpg::$DATA
PSDrive       : H
PSProvider    : Microsoft.PowerShell.Core\FileSystem
PSIsContainer : False
FileName      : H:\z\image.jpg
Stream        : :$DATA
Length        : 38936

PSPath        : Microsoft.PowerShell.Core\FileSystem::H:\z\image.jpg:Zone.Identifier
PSParentPath  : Microsoft.PowerShell.Core\FileSystem::H:\z
PSChildName   : image.jpg:Zone.Identifier
PSDrive       : H
PSProvider    : Microsoft.PowerShell.Core\FileSystem
PSIsContainer : False
FileName      : H:\z\image.jpg
Stream        : Zone.Identifier
Length        : 230



PS H:\z> Get-Content -path image.jpg -stream Zone.Identifier
[ZoneTransfer]
ZoneId=3
ReferrerUrl=https://i.pinimg.com/736x/1a/7b/80/1a7b805cb7b704cf30418acf71c38ab1--funny-coffee-mugs.jpg
HostUrl=https://i.pinimg.com/736x/1a/7b/80/1a7b805cb7b704cf30418acf71c38ab1--funny-coffee-mugs.jpg
PS H:\z>

For reference:

Sample Image downloaded from https://i.pinimg.com/736x/1a/7b/80/1a7b805cb7b704cf30418acf71c38ab1--funny-coffee-mugs.jpg

Explanation & field format from https://www.digital-detective.net/forensic-analysis-of-zone-identifier-stream/




Title: Re: Feature Request: Further decode "Zone Identifier" streams
Post by: StarGeek on November 04, 2022, 08:37:06 PM
You got me curious and I was able to throw a quick config file to read these values.
%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        ZoneIDReferrerUrl => {
Require => {
0 => 'Directory',
1 => 'FileName',
2 => 'ZoneIdentifier',
},
ValueConv => q{
my $pathToZone = "$val[0]/$val[1]:Zone.Identifier";
if (open my $fh, "<", $pathToZone) {
read $fh, my $file_content, -s $fh;
return $1 if ($file_content=~m/ReferrerUrl=(.*)\r?\n/);
}
return undef;
},
},
ZoneIDHostUrl => {
Require => {
0 => 'Directory',
1 => 'FileName',
2 => 'ZoneIdentifier',
},
ValueConv => q{
my $pathToZone = "$val[0]/$val[1]:Zone.Identifier";
if (open my $fh, "<", $pathToZone) {
read $fh, my $file_content, -s $fh;
return $1 if ($file_content=~m/HostUrl=(.*)\r?\n/);
}
return undef;
},
},
},
);
#------------------------------------------------------------------------------

Example output:
C:\>type Y:\!temp\bbb\1a7b805cb7b704cf30418acf71c38ab1--funny-coffee-mugs.jpg:Zone.Identifier
[ZoneTransfer]
ZoneId=3
ReferrerUrl=https://i.pinimg.com/736x/1a/7b/80/1a7b805cb7b704cf30418acf71c38ab1--funny-coffee-mugs.jpg
HostUrl=https://i.pinimg.com/736x/1a/7b/80/1a7b805cb7b704cf30418acf71c38ab1--funny-coffee-mugs.jpg

C:\>exiftool -config zone_Identifier.config -G1 -a -s -ZoneIDReferrerUrl -ZoneIDHostUrl Y:\!temp\bbb\1a7b805cb7b704cf30418acf71c38ab1--funny-coffee-mugs.jpg
[Composite]     ZoneIDReferrerUrl               : https://i.pinimg.com/736x/1a/7b/80/1a7b805cb7b704cf30418acf71c38ab1--funny-coffee-mugs.jpg
[Composite]     ZoneIDHostUrl                   : https://i.pinimg.com/736x/1a/7b/80/1a7b805cb7b704cf30418acf71c38ab1--funny-coffee-mugs.jpg

Haven't tested it much, so there may be issues.

Title: Re: Feature Request: Further decode "Zone Identifier" streams
Post by: PoP on November 05, 2022, 08:18:39 AM
Thank you StarGeek. Simple extract... Excellent!

ZoneId Number interpretation, etc. will just be easy additions to your receipe now.
Title: Re: Feature Request: Further decode "Zone Identifier" streams
Post by: StarGeek on November 05, 2022, 12:36:16 PM
Quote from: PoP on November 05, 2022, 08:18:39 AMZoneId Number interpretation, etc. will just be easy additions to your receipe now.

Ah.  I didn't think that was important.  The link you gave doesn't seem to have any actual translation from the number into an name.  Reading the article a bit, it looks like ZoneId=3 means URLZONE_INTERNET, but nothing else for the others except -1, 0, 999, 1000, 10000.
Title: Re: Feature Request: Further decode "Zone Identifier" streams
Post by: PoP on November 05, 2022, 02:49:56 PM
Don't sweat it. I meant I would do myself the receipe changes (after digging MicroSoft documentation). Thanks again.
Title: Re: Feature Request: Further decode "Zone Identifier" streams
Post by: StarGeek on November 05, 2022, 10:32:02 PM
Let me know what you end up with, so this config file can be updated.
Title: Re: Feature Request: Further decode "Zone Identifier" streams
Post by: PoP on November 06, 2022, 10:52:13 AM
Quote from: PoP on November 05, 2022, 02:49:56 PMI meant I would do myself the receipe changes

Sorry I lied   ;)   I only added ZoneId:

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        ZoneID => {
            Require => {
                0 => 'Directory',
                1 => 'FileName',
                2 => 'ZoneIdentifier',
            },
            ValueConv => q{
                my $pathToZone = "$val[0]/$val[1]:Zone.Identifier";
                if (open my $fh, "<", $pathToZone) {
                    read $fh, my $file_content, -s $fh;
                    return $1 if ($file_content=~m/ZoneId=(.*)\r?\n/);
                }
                return undef;
            },
        },
        ZoneIDReferrerUrl => {
            Require => {
                0 => 'Directory',
                1 => 'FileName',
                2 => 'ZoneIdentifier',
            },
            ValueConv => q{
                my $pathToZone = "$val[0]/$val[1]:Zone.Identifier";
                if (open my $fh, "<", $pathToZone) {
                    read $fh, my $file_content, -s $fh;
                    return $1 if ($file_content=~m/ReferrerUrl=(.*)\r?\n/);
                }
                return undef;
            },
        },
        ZoneIDHostUrl => {
            Require => {
                0 => 'Directory',
                1 => 'FileName',
                2 => 'ZoneIdentifier',
            },
            ValueConv => q{
                my $pathToZone = "$val[0]/$val[1]:Zone.Identifier";
                if (open my $fh, "<", $pathToZone) {
                    read $fh, my $file_content, -s $fh;
                    return $1 if ($file_content=~m/HostUrl=(.*)\r?\n/);
                }
                return undef;
            },
        },
    },
);
#------------------------------------------------------------------------------

On a doctored file local on my computer:

H:\z\AYBABTU>exiftool -config zone_Identifier.config -G1 -a -s -ZoneID -ZoneIDReferrerUrl -ZoneIDHostUrl AYBABTU.png
[Composite]     ZoneID                          : 4
[Composite]     ZoneIDReferrerUrl               : https://CATS.html
[Composite]     ZoneIDHostUrl                   : https://ZeroWing.html

I would have liked to convert ZoneId->URLZONE for the following Ids
0->LOCAL
1->INTRANET
2->TRUSTED
3->INTERNET
4->UNTRUSTED
Which I am fairly confident from inspecting the Windows registry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones but I was intimidated by Image::ExifTool coding. That will do for now.





Title: Re: Feature Request: Further decode "Zone Identifier" streams
Post by: StarGeek on November 06, 2022, 11:46:01 AM
Quote from: PoP on November 06, 2022, 10:52:13 AMI would have liked to convert ZoneId->URLZONE for the following Ids
0->LOCAL
1->INTRANET
2->TRUSTED
3->INTERNET
4->UNTRUSTED
Which I am fairly confident from inspecting the Windows registry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones but I was intimidated by Image::ExifTool coding. That will do for now.

Ok, try this config.  I used exiftool's PrintConv function so that you can either get a text value or if you use the -n (--printConv) option (https://exiftool.org/exiftool_pod.html#n---printConv) (# shortcut in this example), you can get the raw value.

zone_Identifier.config
%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        ZoneID => {
            Require => {
                0 => 'Directory',
                1 => 'FileName',
                2 => 'ZoneIdentifier',
            },
            ValueConv => q{
                my $pathToZone = "$val[0]/$val[1]:Zone.Identifier";
                if (open my $fh, "<", $pathToZone) {
                    read $fh, my $file_content, -s $fh;
                    return $1 if ($file_content=~m/ZoneId=(.*)\r?\n/);
                }
                return undef;
            },
            PrintConv => {
                0 => 'LOCAL',
                1 => 'INTRANET',
                2 => 'TRUSTED',
                3 => 'INTERNET',
                4 => 'UNTRUSTED',
                -1 => 'URLZONE_INVALID',
                999 => 'URLZONE_PREDEFINED_MAX',
                1000 => 'URLZONE_USER_MIN',
                10000 => 'URLZONE_USER_MAX',
            },
        },
        ZoneIDReferrerUrl => {
            Require => {
                0 => 'Directory',
                1 => 'FileName',
                2 => 'ZoneIdentifier',
            },
            ValueConv => q{
                my $pathToZone = "$val[0]/$val[1]:Zone.Identifier";
                if (open my $fh, "<", $pathToZone) {
                    read $fh, my $file_content, -s $fh;
                    return $1 if ($file_content=~m/ReferrerUrl=(.*)\r?\n/);
                }
                return undef;
            },
        },
        ZoneIDHostUrl => {
            Require => {
                0 => 'Directory',
                1 => 'FileName',
                2 => 'ZoneIdentifier',
            },
            ValueConv => q{
                my $pathToZone = "$val[0]/$val[1]:Zone.Identifier";
                if (open my $fh, "<", $pathToZone) {
                    read $fh, my $file_content, -s $fh;
                    return $1 if ($file_content=~m/HostUrl=(.*)\r?\n/);
                }
                return undef;
            },
        },
    },
);
#------------------------------------------------------------------------------

Example output:
C:\>exiftool -config zone_Identifier.config -G1 -a -s -zone* -ZoneID# Y:\!temp\bbb\1a7b805cb7b704cf30418acf71c38ab1--funny-coffee-mugs.jpg
[System]        ZoneIdentifier                  : Exists
[Composite]    ZoneID                          : INTERNET
[Composite]    ZoneIDHostUrl                  : https://i.pinimg.com/736x/1a/7b/80/1a7b805cb7b704cf30418acf71c38ab1--funny-coffee-mugs.jpg
[Composite]    ZoneIDReferrerUrl              : https://i.pinimg.com/736x/1a/7b/80/1a7b805cb7b704cf30418acf71c38ab1--funny-coffee-mugs.jpg
[Composite]    ZoneID                          : 3
Title: Re: Feature Request: Further decode "Zone Identifier" streams
Post by: PoP on November 06, 2022, 12:40:16 PM
^ Perfect. Many Thanks.