Skip to content

Commit

Permalink
Detect and reject a zip bomb using overlapped entries.
Browse files Browse the repository at this point in the history
This detects an invalid zip file that has at least one entry that
overlaps with another entry or with the central directory to the
end of the file. A Fifield zip bomb uses overlapped local entries
to vastly increase the potential inflation ratio. Such an invalid
zip file is rejected.

See https://www.bamsoftware.com/hacks/zipbomb/ for David Fifield's
analysis, construction, and examples of such zip bombs.

The detection maintains a list of covered spans of the zip files
so far, where the central directory to the end of the file and any
bytes preceding the first entry at zip file offset zero are
considered covered initially. Then as each entry is decompressed
or tested, it is considered covered. When a new entry is about to
be processed, its initial offset is checked to see if it is
contained by a covered span. If so, the zip file is rejected as
invalid.

This commit depends on a preceding commit: "Fix bug in
undefer_input() that misplaced the input state."
  • Loading branch information
madler committed Jun 12, 2019
1 parent 41beb47 commit 47b3cea
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 1 deletion.
190 changes: 189 additions & 1 deletion extract.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,125 @@ static ZCONST char Far UnsupportedExtraField[] =
"\nerror: unsupported extra-field compression type (%u)--skipping\n";
static ZCONST char Far BadExtraFieldCRC[] =
"error [%s]: bad extra-field CRC %08lx (should be %08lx)\n";
static ZCONST char Far NotEnoughMemCover[] =
"error: not enough memory for bomb detection\n";
static ZCONST char Far OverlappedComponents[] =
"error: invalid zip file with overlapped components (possible zip bomb)\n";





/* A growable list of spans. */
typedef zoff_t bound_t;
typedef struct {
bound_t beg; /* start of the span */
bound_t end; /* one past the end of the span */
} span_t;
typedef struct {
span_t *span; /* allocated, distinct, and sorted list of spans */
size_t num; /* number of spans in the list */
size_t max; /* allocated number of spans (num <= max) */
} cover_t;

/*
* Return the index of the first span in cover whose beg is greater than val.
* If there is no such span, then cover->num is returned.
*/
static size_t cover_find(cover, val)
cover_t *cover;
bound_t val;
{
size_t lo = 0, hi = cover->num;
while (lo < hi) {
size_t mid = (lo + hi) >> 1;
if (val < cover->span[mid].beg)
hi = mid;
else
lo = mid + 1;
}
return hi;
}

/* Return true if val lies within any one of the spans in cover. */
static int cover_within(cover, val)
cover_t *cover;
bound_t val;
{
size_t pos = cover_find(cover, val);
return pos > 0 && val < cover->span[pos - 1].end;
}

/*
* Add a new span to the list, but only if the new span does not overlap any
* spans already in the list. The new span covers the values beg..end-1. beg
* must be less than end.
*
* Keep the list sorted and merge adjacent spans. Grow the allocated space for
* the list as needed. On success, 0 is returned. If the new span overlaps any
* existing spans, then 1 is returned and the new span is not added to the
* list. If the new span is invalid because beg is greater than or equal to
* end, then -1 is returned. If the list needs to be grown but the memory
* allocation fails, then -2 is returned.
*/
static int cover_add(cover, beg, end)
cover_t *cover;
bound_t beg;
bound_t end;
{
size_t pos;
int prec, foll;

if (beg >= end)
/* The new span is invalid. */
return -1;

/* Find where the new span should go, and make sure that it does not
overlap with any existing spans. */
pos = cover_find(cover, beg);
if ((pos > 0 && beg < cover->span[pos - 1].end) ||
(pos < cover->num && end > cover->span[pos].beg))
return 1;

/* Check for adjacencies. */
prec = pos > 0 && beg == cover->span[pos - 1].end;
foll = pos < cover->num && end == cover->span[pos].beg;
if (prec && foll) {
/* The new span connects the preceding and following spans. Merge the
following span into the preceding span, and delete the following
span. */
cover->span[pos - 1].end = cover->span[pos].end;
cover->num--;
memmove(cover->span + pos, cover->span + pos + 1,
(cover->num - pos) * sizeof(span_t));
}
else if (prec)
/* The new span is adjacent only to the preceding span. Extend the end
of the preceding span. */
cover->span[pos - 1].end = end;
else if (foll)
/* The new span is adjacent only to the following span. Extend the
beginning of the following span. */
cover->span[pos].beg = beg;
else {
/* The new span has gaps between both the preceding and the following
spans. Assure that there is room and insert the span. */
if (cover->num == cover->max) {
size_t max = cover->max == 0 ? 16 : cover->max << 1;
span_t *span = realloc(cover->span, max * sizeof(span_t));
if (span == NULL)
return -2;
cover->span = span;
cover->max = max;
}
memmove(cover->span + pos + 1, cover->span + pos,
(cover->num - pos) * sizeof(span_t));
cover->num++;
cover->span[pos].beg = beg;
cover->span[pos].end = end;
}
return 0;
}



Expand Down Expand Up @@ -374,6 +493,29 @@ int extract_or_test_files(__G) /* return PK-type error code */
}
#endif /* !SFX || SFX_EXDIR */

/* One more: initialize cover structure for bomb detection. Start with a
span that covers the central directory though the end of the file. */
if (G.cover == NULL) {
G.cover = malloc(sizeof(cover_t));
if (G.cover == NULL) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(NotEnoughMemCover)));
return PK_MEM;
}
((cover_t *)G.cover)->span = NULL;
((cover_t *)G.cover)->max = 0;
}
((cover_t *)G.cover)->num = 0;
if ((G.extra_bytes != 0 &&
cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
cover_add((cover_t *)G.cover,
G.extra_bytes + G.ecrec.offset_start_central_directory,
G.ziplen) != 0) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(NotEnoughMemCover)));
return PK_MEM;
}

/*---------------------------------------------------------------------------
The basic idea of this function is as follows. Since the central di-
rectory lies at the end of the zipfile and the member files lie at the
Expand Down Expand Up @@ -591,7 +733,8 @@ int extract_or_test_files(__G) /* return PK-type error code */
if (error > error_in_archive)
error_in_archive = error;
/* ...and keep going (unless disk full or user break) */
if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
if (G.disk_full > 1 || error_in_archive == IZ_CTRLC ||
error == PK_BOMB) {
/* clear reached_end to signal premature stop ... */
reached_end = FALSE;
/* ... and cancel scanning the central directory */
Expand Down Expand Up @@ -1060,6 +1203,11 @@ static int extract_or_test_entrylist(__G__ numchunk,

/* seek_zipf(__G__ pInfo->offset); */
request = G.pInfo->offset + G.extra_bytes;
if (cover_within((cover_t *)G.cover, request)) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(OverlappedComponents)));
return PK_BOMB;
}
inbuf_offset = request % INBUFSIZ;
bufstart = request - inbuf_offset;

Expand Down Expand Up @@ -1591,6 +1739,18 @@ static int extract_or_test_entrylist(__G__ numchunk,
return IZ_CTRLC; /* cancel operation by user request */
}
#endif
error = cover_add((cover_t *)G.cover, request,
G.cur_zipfile_bufstart + (G.inptr - G.inbuf));
if (error < 0) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(NotEnoughMemCover)));
return PK_MEM;
}
if (error != 0) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(OverlappedComponents)));
return PK_BOMB;
}
#ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */
UserStop();
#endif
Expand Down Expand Up @@ -1992,6 +2152,34 @@ static int extract_or_test_member(__G) /* return PK-type error code */
}

undefer_input(__G);

if ((G.lrec.general_purpose_bit_flag & 8) != 0) {
/* skip over data descriptor (harder than it sounds, due to signature
* ambiguity)
*/
# define SIG 0x08074b50
# define LOW 0xffffffff
uch buf[12];
unsigned shy = 12 - readbuf((char *)buf, 12);
ulg crc = shy ? 0 : makelong(buf);
ulg clen = shy ? 0 : makelong(buf + 4);
ulg ulen = shy ? 0 : makelong(buf + 8); /* or high clen if ZIP64 */
if (crc == SIG && /* if not SIG, no signature */
(G.lrec.crc32 != SIG || /* if not SIG, have signature */
(clen == SIG && /* if not SIG, no signature */
((G.lrec.csize & LOW) != SIG || /* if not SIG, have signature */
(ulen == SIG && /* if not SIG, no signature */
(G.zip64 ? G.lrec.csize >> 32 : G.lrec.ucsize) != SIG
/* if not SIG, have signature */
)))))
/* skip four more bytes to account for signature */
shy += 4 - readbuf((char *)buf, 4);
if (G.zip64)
shy += 8 - readbuf((char *)buf, 8); /* skip eight more for ZIP64 */
if (shy)
error = PK_ERR;
}

return error;

} /* end function extract_or_test_member() */
Expand Down
1 change: 1 addition & 0 deletions globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ Uz_Globs *globalsCtor()
# if (!defined(NO_TIMESTAMPS))
uO.D_flag=1; /* default to '-D', no restoration of dir timestamps */
# endif
G.cover = NULL; /* not allocated yet */
#endif

uO.lflag=(-1);
Expand Down
3 changes: 3 additions & 0 deletions globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,15 @@ typedef struct Globals {
ecdir_rec ecrec; /* used in unzip.c, extract.c */
z_stat statbuf; /* used by main, mapname, check_for_newer */

int zip64; /* true if Zip64 info in extra field */

int mem_mode;
uch *outbufptr; /* extract.c static */
ulg outsize; /* extract.c static */
int reported_backslash; /* extract.c static */
int disk_full;
int newfile;
void **cover; /* used in extract.c for bomb detection */

int didCRlast; /* fileio static */
ulg numlines; /* fileio static: number of lines printed */
Expand Down
11 changes: 11 additions & 0 deletions process.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,13 @@ void free_G_buffers(__G) /* releases all memory allocated in global vars */
}
#endif

/* Free the cover span list and the cover structure. */
if (G.cover != NULL) {
free(*(G.cover));
free(G.cover);
G.cover = NULL;
}

} /* end function free_G_buffers() */


Expand Down Expand Up @@ -1890,6 +1897,8 @@ int getZip64Data(__G__ ef_buf, ef_len)
but it means that this procedure is only called in one place.
---------------------------------------------------------------------------*/

G.zip64 = FALSE;

if (ef_len == 0 || ef_buf == NULL)
return PK_COOL;

Expand Down Expand Up @@ -1927,6 +1936,8 @@ int getZip64Data(__G__ ef_buf, ef_len)
G.crec.disk_number_start = (zuvl_t)makelong(offset + ef_buf);
offset += sizeof(G.crec.disk_number_start);
}

G.zip64 = TRUE;
}

/* Skip this extra field block */
Expand Down
1 change: 1 addition & 0 deletions unzip.h
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,7 @@ typedef struct _Uzp_cdir_Rec {
#define PK_NOZIP 9 /* zipfile not found */
#define PK_PARAM 10 /* bad or illegal parameters specified */
#define PK_FIND 11 /* no files found */
#define PK_BOMB 12 /* likely zip bomb */
#define PK_DISK 50 /* disk full */
#define PK_EOF 51 /* unexpected EOF */

Expand Down

19 comments on commit 47b3cea

@madler
Copy link
Owner Author

@madler madler commented on 47b3cea Jul 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note the comment in the commit, that this depends on another commit. You cannot apply this commit in isolation. Also there is a subsequent commit that generalizes the bomb detection to zip-like containers that do not follow the zip standard, putting the central directory at the beginning of the container.

@jamartis
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello,
I am going through the patch, and I am a bit confused by the type of the Globals.cover. Is there any reason for it being the double pointer? Shouldn't it be just void *cover;, or am I missing something?
Thanks,
Jakub

@jamartis
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello,
I am going through the patch, and I am a bit confused by the type of the Globals.cover. Is there any reason for it being the double pointer? Shouldn't it be just void *cover;, or am I missing something?
Thanks,
Jakub

Ok, nevermind, It's a double pointer so you are able to free the span list. Sorry for spam:-)

@cjl20062529
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello
After I merged
41beb47
47b3cea
6d35183
the decompression of my local non-bomb file failed, and the prompt as follows:
[test@localhost /home]# unzip MyTxxx.zip
Archive: MyTxxx.zip
creating: scripts/
creating: scripts/ixx/
inflating: scripts/ixx/change_xxx.sh
error: invalid zip file with overlapped components (possible zip bomb)

But when use the old version to decompress, the decompression was normal.
Will these three patches break the decompression behavior of the original compressed file? Or a new constraint change?
Thanks.

@madler
Copy link
Owner Author

@madler madler commented on 47b3cea Feb 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make the file in question available for me to look at?

@cjl20062529
Copy link

@cjl20062529 cjl20062529 commented on 47b3cea Feb 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make the file in question available for me to look at?

thanks for your reply。
the zip file is compressed by a java program(https://blog.csdn.net/yaohucaizi/article/details/8863823), using the following two libraries:
org.apache.tools.zip.ZipOutputStream;
import org.apache.tools.zip.ZipEntry;
and the zip file is too large (4.5GB), so i cannot upload it.
I added some printing information of the decompression process, as follows:
[root@localhost opt]# unzip MyTxxx.zip
Archive: MyTxxx.zip
cover_add:beg:4793290554,end:4795054264
cover_add:beg:4795054264,end:4795054320
cover_add:beg:4795054320,end:4795054362
cover_within:val:0,ret=0
creating: scripts/
cover_within:val:56,ret=0
creating: scripts/ixx/
cover_within:val:117,ret=0
inflating: scripts/ixx/change_xxx.sh
cover_add:beg:117,end:761
cover_within:val:753,ret=1
error: invalid zip file with overlapped components (possible zip bomb)

btw:
I would like to ask: compressing some files using the zip command, will it produce overlapped entries?

@cjl20062529
Copy link

@cjl20062529 cjl20062529 commented on 47b3cea Feb 7, 2020 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cjl20062529
Copy link

@cjl20062529 cjl20062529 commented on 47b3cea Feb 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hello
“Detect and reject a zip bomb using overlapped entries.”
I didn't figure out whether the overlapping entries refer to the local header or the central directory?

Can I add some parameters to set the number of overlapping entrie allowed, if it exceeds this threshold, it will no longer decompress. If so, please give me some suggestions and guidance.

@madler
Copy link
Owner Author

@madler madler commented on 47b3cea Feb 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4.5GB isn't too large. You could upload it to Google Drive, which is free up to 15 GB. And then share it with me (google at madler dot net).

@madler
Copy link
Owner Author

@madler madler commented on 47b3cea Feb 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And make sure that you have also applied a later commit: 6d35183 that follows this one.

@cjl20062529
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And make sure that you have also applied a later commit: 6d35183 that follows this one.

im sure I applied the commit: 6d35183

@madler
Copy link
Owner Author

@madler madler commented on 47b3cea Feb 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These commits detect any zip file element overlapping with any other zip file element. A valid zip file will have no such overlaps.

Either your zip file is invalid in this way, or there is a bug in my code to detect such overlaps. The only way I can distinguish between these two is to be able to examine your zip file.

@madler
Copy link
Owner Author

@madler madler commented on 47b3cea Feb 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please run unzip -v and provide the output, so I can see the compile options. Thanks.

@cjl20062529
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please run unzip -v and provide the output, so I can see the compile options. Thanks.

[root@localhost test]# ./unzip -v
......
UnZip special compilation options:
COPYRIGHT_CLEAN (PKZIP 0.9x unreducing method not supported)
SET_DIR_ATTRIB
SYMLINKS (symbolic links supported, if RTL and file system permit)
TIMESTAMP
UNIXBACKUP
USE_EF_UT_TIME
USE_UNSHRINK (PKZIP/Zip 1.x unshrinking method supported)
USE_DEFLATE64 (PKZIP 4.x Deflate64(tm) supported)
UNICODE_SUPPORT [wide-chars, char coding: UTF-8] (handle UTF-8 paths)
MBCS-support (multibyte character support, MB_CUR_MAX = 6)
LARGE_FILE_SUPPORT (large files over 2 GiB supported)
ZIP64_SUPPORT (archives using Zip64 for large files supported)
USE_BZIP2 (PKZIP 4.6+, using bzip2 lib version 1.0.6, 6-Sept-2010)
VMS_TEXT_CONV
[decryption, version 2.11 of 05 Jan 2007]

UnZip and ZipInfo environment options:
UNZIP: [none]
UNZIPOPT: [none]
ZIPINFO: [none]
ZIPINFOOPT: [none]

@madler
Copy link
Owner Author

@madler madler commented on 47b3cea Feb 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good. (Was checking for large file and zip64.)

Please do an unzip -Zv MyTxxx.zip and provide the output.

Have you been able to upload the file to google drive?

@cjl20062529
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good. (Was checking for large file and zip64.)

Please do an unzip -Zv MyTxxx.zip and provide the output.

Have you been able to upload the file to google drive?

#unzip -Zv MyTxxx.zip
...
Central directory entry #11618:

There are an extra 16 bytes preceding this file.

mxx/xx/Eqxx_en.xml

offset of local header from start of archive: 4793288797
(000000011DB3C85Dh) bytes
file system or operating system of origin: Unix
version of encoding software: 4.5
minimum file system compatibility required: MS-DOS, OS/2 or NT FAT
minimum software version required to extract: 4.5
compression method: deflated
compression sub-type (deflation): normal
file security status: not encrypted
extended local header: yes
file last modified on (DOS date/time): 2019 Sep 26 20:34:14
32-bit CRC value (hex): 8d367b7f
compressed size: 1667 bytes
uncompressed size: 18092 bytes
length of filename: 44 characters
length of extra field: 12 bytes
length of file comment: 0 characters
disk number on which file begins: disk 1
apparent file type: binary
Unix file attributes (001130 octal): ?--x-wx--T
MS-DOS file attributes (01 hex): read-only

and I run unzip -v xxx.zip, it list all 11618 files info OK.
but for some reason, I can not upload the zip file to google drive.

@madler
Copy link
Owner Author

@madler madler commented on 47b3cea Feb 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you provide all of the output of unzip -Zv? Perhaps you would be able to put at least that on google drive.

@madler
Copy link
Owner Author

@madler madler commented on 47b3cea Feb 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I pushed a few more commits yesterday that you could try. I suspect that those won't make a difference to what you're seeing, but it's worth a try.

@yrkng
Copy link

@yrkng yrkng commented on 47b3cea Mar 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @madler ,
I also recently got this similar issue with https://downloads.rclone.org/rclone-current-linux-amd64.zip over alpine.
output of unzip -Zv:

Archive:  /tmp/rclone-src/rclone.zip
There is no zipfile comment.

End-of-central-directory record:
-------------------------------

  Zip archive file size:                  11913756 (0000000000B5CA1Ch)
  Actual end-cent-dir record offset:      11913734 (0000000000B5CA06h)
  Expected end-cent-dir record offset:    11913734 (0000000000B5CA06h)
  (based on the length of the central directory and its expected offset)

  This zipfile constitutes the sole disk of a single-part archive; its
  central directory contains 6 entries.
  The central directory is 628 (0000000000000274h) bytes long,
  and its (expected) offset in bytes from the beginning of the zipfile
  is 11913106 (0000000000B5C792h).


Central directory entry #1:
---------------------------

  rclone-v1.51.0-linux-amd64/

  offset of local header from start of archive:   0
                                                  (0000000000000000h) bytes
  file system or operating system of origin:      Unix
  version of encoding software:                   3.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   1.0
  compression method:                             none (stored)
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2020 Feb 1 10:49:12
  file last modified on (UT extra field modtime): 2020 Feb 1 10:49:12 local
  file last modified on (UT extra field modtime): 2020 Feb 1 10:49:12 UTC
  32-bit CRC value (hex):                         00000000
  compressed size:                                0 bytes
  uncompressed size:                              0 bytes
  length of filename:                             27 characters
  length of extra field:                          24 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  Unix file attributes (040755 octal):            drwxr-xr-x
  MS-DOS file attributes (10 hex):                dir 

  The central-directory extra field contains:
  - A subfield with ID 0x5455 (universal time) and 5 data bytes.
    The local extra field has UTC/GMT modification/access times.
  - A subfield with ID 0x7875 (Unix UID/GID (any size)) and 11 data bytes:
    01 04 e9 03 00 00 04 73 00 00 00.

  There is no file comment.

Central directory entry #2:
---------------------------

  rclone-v1.51.0-linux-amd64/rclone.1

  offset of local header from start of archive:   85
                                                  (0000000000000055h) bytes
  file system or operating system of origin:      Unix
  version of encoding software:                   3.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   2.0
  compression method:                             deflated
  compression sub-type (deflation):               maximum
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2020 Feb 1 10:45:08
  file last modified on (UT extra field modtime): 2020 Feb 1 10:45:08 local
  file last modified on (UT extra field modtime): 2020 Feb 1 10:45:08 UTC
  32-bit CRC value (hex):                         a97d2419
  compressed size:                                228014 bytes
  uncompressed size:                              943372 bytes
  length of filename:                             35 characters
  length of extra field:                          24 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             text
  Unix file attributes (100644 octal):            -rw-r--r--
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0x5455 (universal time) and 5 data bytes.
    The local extra field has UTC/GMT modification/access times.
  - A subfield with ID 0x7875 (Unix UID/GID (any size)) and 11 data bytes:
    01 04 e9 03 00 00 04 73 00 00 00.

  There is no file comment.

Central directory entry #3:
---------------------------

  rclone-v1.51.0-linux-amd64/README.txt

  offset of local header from start of archive:   228192
                                                  (0000000000037B60h) bytes
  file system or operating system of origin:      Unix
  version of encoding software:                   3.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   2.0
  compression method:                             deflated
  compression sub-type (deflation):               maximum
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2020 Feb 1 10:45:08
  file last modified on (UT extra field modtime): 2020 Feb 1 10:45:08 local
  file last modified on (UT extra field modtime): 2020 Feb 1 10:45:08 UTC
  32-bit CRC value (hex):                         17b053f5
  compressed size:                                215863 bytes
  uncompressed size:                              834407 bytes
  length of filename:                             37 characters
  length of extra field:                          24 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             text
  Unix file attributes (100644 octal):            -rw-r--r--
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0x5455 (universal time) and 5 data bytes.
    The local extra field has UTC/GMT modification/access times.
  - A subfield with ID 0x7875 (Unix UID/GID (any size)) and 11 data bytes:
    01 04 e9 03 00 00 04 73 00 00 00.

  There is no file comment.

Central directory entry #4:
---------------------------

  rclone-v1.51.0-linux-amd64/README.html

  offset of local header from start of archive:   444150
                                                  (000000000006C6F6h) bytes
  file system or operating system of origin:      Unix
  version of encoding software:                   3.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   2.0
  compression method:                             deflated
  compression sub-type (deflation):               maximum
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2020 Feb 1 10:45:08
  file last modified on (UT extra field modtime): 2020 Feb 1 10:45:08 local
  file last modified on (UT extra field modtime): 2020 Feb 1 10:45:08 UTC
  32-bit CRC value (hex):                         69e5f1b6
  compressed size:                                240772 bytes
  uncompressed size:                              1046996 bytes
  length of filename:                             38 characters
  length of extra field:                          24 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             text
  Unix file attributes (100644 octal):            -rw-r--r--
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0x5455 (universal time) and 5 data bytes.
    The local extra field has UTC/GMT modification/access times.
  - A subfield with ID 0x7875 (Unix UID/GID (any size)) and 11 data bytes:
    01 04 e9 03 00 00 04 73 00 00 00.

  There is no file comment.

Central directory entry #5:
---------------------------

  rclone-v1.51.0-linux-amd64/git-log.txt

  offset of local header from start of archive:   685018
                                                  (00000000000A73DAh) bytes
  file system or operating system of origin:      Unix
  version of encoding software:                   3.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   1.0
  compression method:                             none (stored)
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2020 Feb 1 10:48:40
  file last modified on (UT extra field modtime): 2020 Feb 1 10:48:40 local
  file last modified on (UT extra field modtime): 2020 Feb 1 10:48:40 UTC
  32-bit CRC value (hex):                         00000000
  compressed size:                                0 bytes
  uncompressed size:                              0 bytes
  length of filename:                             38 characters
  length of extra field:                          24 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  Unix file attributes (100644 octal):            -rw-r--r--
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0x5455 (universal time) and 5 data bytes.
    The local extra field has UTC/GMT modification/access times.
  - A subfield with ID 0x7875 (Unix UID/GID (any size)) and 11 data bytes:
    01 04 e9 03 00 00 04 73 00 00 00.

  There is no file comment.

Central directory entry #6:
---------------------------

  rclone-v1.51.0-linux-amd64/rclone

  offset of local header from start of archive:   685114
                                                  (00000000000A743Ah) bytes
  file system or operating system of origin:      Unix
  version of encoding software:                   3.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   2.0
  compression method:                             deflated
  compression sub-type (deflation):               maximum
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2020 Feb 1 10:49:12
  file last modified on (UT extra field modtime): 2020 Feb 1 10:49:12 local
  file last modified on (UT extra field modtime): 2020 Feb 1 10:49:12 UTC
  32-bit CRC value (hex):                         601fc097
  compressed size:                                11227901 bytes
  uncompressed size:                              34328576 bytes
  length of filename:                             33 characters
  length of extra field:                          24 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  Unix file attributes (100755 octal):            -rwxr-xr-x
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0x5455 (universal time) and 5 data bytes.
    The local extra field has UTC/GMT modification/access times.
  - A subfield with ID 0x7875 (Unix UID/GID (any size)) and 11 data bytes:
    01 04 e9 03 00 00 04 73 00 00 00.

  There is no file comment.

Please sign in to comment.