Skip to main content

A static analysis file format checker.

Project description

@sebdroid/pure-checker

Build

pure-checker is a Python3 port of the following npm package:

@ronomon/pure

Pure is a static analysis file format checker that checks ZIP files for dangerous compression ratios, spec deviations, malicious archive signatures, mismatching local and central directory headers, ambiguous UTF-8 filenames, directory and symlink traversals, invalid MS-DOS dates, overlapping headers, overflow, underflow, sparseness, accidental buffer bleeds etc.

Pure's goal is to narrow the semantic gap available to attackers attempting to exploit vulnerable software, and to reduce the probability of zero-days, for example David Fifield's A better zip bomb, which was detected by an early version of Pure as a zero-day.

Acknowledgements

Pure was commissioned and sponsored by the Product Release And Security Team at Microsoft.

A special thanks to Maxim Vainstein and his team at Microsoft for their vision and encouragement.

Looking to the future, we want to add support for more archive containers (GZ, TAR, RAR etc.) and other file formats (MS-CFBF or OOXML Office files, RTF, PDF, image formats etc.). Please contact Joran Dirk Greef if you want to support new file formats in Pure.

Files

  • pure.h: C interface to library source code.

  • pure: CLI script for development testing. Usage: ./pure <file>.

  • test.js: Node.js test runner to run Pure against all test files in ./tests.

  • binding.c: Node.js binding used by CLI and test runner.

  • make-errors.js: Script to recreate C error enums, error codes and error strings dynamically.

  • make-signatures.js: Script to recreate C signature strings dynamically.

  • make-tests.js: Script to recreate test files dynamically.

Installation

npm install @ronomon/pure

Usage

At the command line, you can run Pure on any zip file:

$ ./pure <file.zip>

For example:

$ ./pure samples/zbsm.zip
PURE_E_ZIP_BOMB_FIFIELD: zip bomb: local file header overlap (see research by David Fifield)

As an embedded C library, pure.h provides:

int pure_zip(
  const uint8_t* buffer, // Zip file buffer
  const uint64_t size,   // Size of zip file buffer in bytes
  const uint64_t flags   // Bit flags (optional)
)

int pure_zip_bomb(const int error)

const char* pure_error_code(const int error)

const char* pure_error_string(const int error)
  • pure_zip() returns a non-zero error return code, or a zero return code if the zip file is clean and has no file format anomalies. A buffer instead of a path is passed to pure_zip() for portability, for reduced surface area for bugs, and to avoid forcing unnecessary IO if file contents are already in memory.

  • pure_zip_bomb() returns 1 if the error return code indicates a zip bomb, otherwise 0.

  • pure_error_code() returns the constant name of the error return code.

  • pure_error_string() returns the error message string corresponding the error return code.

File Format Anomalies

Pure detects more than 150 zip file format anomalies.

Pure provides defenses against directory and symlink traversal exploits, dangerous unix mode permissions, parser ambiguity, and many other defenses against known (and unknown) exploits, including zip bombs and buffer overflows.

For example, Pure detects all variants of known (and unknown) zip bombs:

  1. Overlapping local file headers (cf. David Fifield).
  2. Quines (cf. Russ Cox).
  3. Dangerous compression ratios for individual files and across an archive.
  4. "Lying" zip metadata vs actual compressed data.
  5. Excessive archive recursion.
  6. Excessive number of files.

As a static analysis file format checker, Pure reduces the surface area for zero-day exploits by orders of magnitude. If a file can get past Pure, it's "pure"... or at least 99% pure.

Here is the exhaustive list of what Pure can already detect:

  • PURE_E_SIZE_MAX
  • PURE_E_MALLOC
  • PURE_E_STRING_NOT_FOUND
  • PURE_E_UINT64_OVERFLOW
  • PURE_E_ZIP_BOMB_ARCHIVES
  • PURE_E_ZIP_BOMB_DEPTH
  • PURE_E_ZIP_BOMB_FIFIELD
  • PURE_E_ZIP_BOMB_FILES
  • PURE_E_ZIP_BOMB_RATIO
  • PURE_E_ZIP_BOMB_INFLATE_COMPRESSED_OVERFLOW
  • PURE_E_ZIP_BOMB_INFLATE_UNCOMPRESSED_OVERFLOW
  • PURE_E_ZIP_TOO_SMALL
  • PURE_E_ZIP_SIZE_4GB
  • PURE_E_ZIP_RAR
  • PURE_E_ZIP_TAR
  • PURE_E_ZIP_XAR
  • PURE_E_ZIP_SIGNATURE
  • PURE_E_ZIP_EOCDR_NOT_FOUND
  • PURE_E_ZIP_EOCDR_OVERFLOW
  • PURE_E_ZIP_EOCDR_COMMENT_OVERFLOW
  • PURE_E_ZIP_EOCDR_SIGNATURE
  • PURE_E_ZIP_EOCDR_RECORDS
  • PURE_E_ZIP_EOCDR_SIZE_OVERFLOW
  • PURE_E_ZIP_EOCDR_SIZE_UNDERFLOW
  • PURE_E_ZIP_MULTIPLE_DISKS
  • PURE_E_ZIP_APPENDED_DATA_ZEROED
  • PURE_E_ZIP_APPENDED_DATA_BUFFER_BLEED
  • PURE_E_ZIP_PREPENDED_DATA
  • PURE_E_ZIP_PREPENDED_DATA_ZEROED
  • PURE_E_ZIP_PREPENDED_DATA_BUFFER_BLEED
  • PURE_E_ZIP_CDH_OVERFLOW
  • PURE_E_ZIP_CDH_SIGNATURE
  • PURE_E_ZIP_CDH_RELATIVE_OFFSET_OVERFLOW
  • PURE_E_ZIP_CDH_RELATIVE_OFFSET_OVERLAP
  • PURE_E_ZIP_CDH_FILE_NAME_OVERFLOW
  • PURE_E_ZIP_CDH_EXTRA_FIELD_OVERFLOW
  • PURE_E_ZIP_CDH_FILE_COMMENT_OVERFLOW
  • PURE_E_ZIP_LFH_OVERFLOW
  • PURE_E_ZIP_LFH_SIGNATURE
  • PURE_E_ZIP_LFH_FILE_NAME_OVERFLOW
  • PURE_E_ZIP_LFH_EXTRA_FIELD_OVERFLOW
  • PURE_E_ZIP_LFH_UNDERFLOW_ZEROED
  • PURE_E_ZIP_LFH_UNDERFLOW_BUFFER_BLEED
  • PURE_E_ZIP_LFH_DATA_OVERFLOW
  • PURE_E_ZIP_DDR_OVERFLOW
  • PURE_E_ZIP_LF_OVERFLOW
  • PURE_E_ZIP_LF_UNDERFLOW_ZEROED
  • PURE_E_ZIP_LF_UNDERFLOW_BUFFER_BLEED
  • PURE_E_ZIP_CD_OVERFLOW
  • PURE_E_ZIP_CD_UNDERFLOW_ZEROED
  • PURE_E_ZIP_CD_UNDERFLOW_BUFFER_BLEED
  • PURE_E_ZIP_CD_EOCDR_OVERFLOW
  • PURE_E_ZIP_CD_EOCDR_UNDERFLOW_ZEROED
  • PURE_E_ZIP_CD_EOCDR_UNDERFLOW_BUFFER_BLEED
  • PURE_E_ZIP_DIFF_LFH_GENERAL_PURPOSE_BIT_FLAG
  • PURE_E_ZIP_DIFF_LFH_COMPRESSION_METHOD
  • PURE_E_ZIP_DIFF_LFH_LAST_MOD_FILE_TIME
  • PURE_E_ZIP_DIFF_LFH_LAST_MOD_FILE_DATE
  • PURE_E_ZIP_DIFF_LFH_CRC32
  • PURE_E_ZIP_DIFF_LFH_COMPRESSED_SIZE
  • PURE_E_ZIP_DIFF_LFH_UNCOMPRESSED_SIZE
  • PURE_E_ZIP_DIFF_LFH_FILE_NAME_LENGTH
  • PURE_E_ZIP_DIFF_LFH_FILE_NAME
  • PURE_E_ZIP_DIFF_LFH_DDR_CRC32
  • PURE_E_ZIP_DIFF_LFH_DDR_COMPRESSED_SIZE
  • PURE_E_ZIP_DIFF_LFH_DDR_UNCOMPRESSED_SIZE
  • PURE_E_ZIP_DIFF_DDR_CRC32
  • PURE_E_ZIP_DIFF_DDR_COMPRESSED_SIZE
  • PURE_E_ZIP_DIFF_DDR_UNCOMPRESSED_SIZE
  • PURE_E_ZIP_FLAG_OVERFLOW
  • PURE_E_ZIP_FLAG_TRADITIONAL_ENCRYPTION
  • PURE_E_ZIP_FLAG_ENHANCED_DEFLATE
  • PURE_E_ZIP_FLAG_COMPRESSED_PATCHED_DATA
  • PURE_E_ZIP_FLAG_STRONG_ENCRYPTION
  • PURE_E_ZIP_FLAG_UNUSED_BIT_7
  • PURE_E_ZIP_FLAG_UNUSED_BIT_8
  • PURE_E_ZIP_FLAG_UNUSED_BIT_9
  • PURE_E_ZIP_FLAG_UNUSED_BIT_10
  • PURE_E_ZIP_FLAG_ENHANCED_COMPRESSION
  • PURE_E_ZIP_FLAG_MASKED_LOCAL_HEADERS
  • PURE_E_ZIP_FLAG_RESERVED_BIT_14
  • PURE_E_ZIP_FLAG_RESERVED_BIT_15
  • PURE_E_ZIP_COMPRESSION_METHOD_DANGEROUS
  • PURE_E_ZIP_COMPRESSION_METHOD_ENCRYPTED
  • PURE_E_ZIP_COMPRESSION_METHOD_UNSUPPORTED
  • PURE_E_ZIP_STORED_COMPRESSION_SIZE_MISMATCH
  • PURE_E_ZIP_DANGEROUS_NEGATIVE_COMPRESSION_RATIO
  • PURE_E_ZIP_TIME_OVERFLOW
  • PURE_E_ZIP_TIME_HOUR_OVERFLOW
  • PURE_E_ZIP_TIME_MINUTE_OVERFLOW
  • PURE_E_ZIP_TIME_SECOND_OVERFLOW
  • PURE_E_ZIP_DATE_OVERFLOW
  • PURE_E_ZIP_DATE_YEAR_OVERFLOW
  • PURE_E_ZIP_DATE_MONTH_OVERFLOW
  • PURE_E_ZIP_DATE_DAY_OVERFLOW
  • PURE_E_ZIP_FILE_NAME_LENGTH
  • PURE_E_ZIP_FILE_NAME_CONTROL_CHARACTERS
  • PURE_E_ZIP_FILE_NAME_TRAVERSAL_DRIVE_PATH
  • PURE_E_ZIP_FILE_NAME_TRAVERSAL_RELATIVE_PATH
  • PURE_E_ZIP_FILE_NAME_TRAVERSAL_DOUBLE_DOTS
  • PURE_E_ZIP_FILE_NAME_COMPONENT_OVERFLOW
  • PURE_E_ZIP_FILE_NAME_BACKSLASH
  • PURE_E_ZIP_EXTRA_FIELD_MAX
  • PURE_E_ZIP_EXTRA_FIELD_MIN
  • PURE_E_ZIP_EXTRA_FIELD_ATTRIBUTE_OVERFLOW
  • PURE_E_ZIP_EXTRA_FIELD_OVERFLOW
  • PURE_E_ZIP_EXTRA_FIELD_UNDERFLOW_ZEROED
  • PURE_E_ZIP_EXTRA_FIELD_UNDERFLOW_BUFFER_BLEED
  • PURE_E_ZIP_EXTRA_FIELD_UNICODE_PATH_OVERFLOW
  • PURE_E_ZIP_EXTRA_FIELD_UNICODE_PATH_VERSION
  • PURE_E_ZIP_EXTRA_FIELD_UNICODE_PATH_DIFF
  • PURE_E_ZIP_UNIX_MODE_OVERFLOW
  • PURE_E_ZIP_UNIX_MODE_BLOCK_DEVICE
  • PURE_E_ZIP_UNIX_MODE_CHARACTER_DEVICE
  • PURE_E_ZIP_UNIX_MODE_FIFO
  • PURE_E_ZIP_UNIX_MODE_SOCKET
  • PURE_E_ZIP_UNIX_MODE_PERMISSIONS_STICKY
  • PURE_E_ZIP_UNIX_MODE_PERMISSIONS_SETGID
  • PURE_E_ZIP_UNIX_MODE_PERMISSIONS_SETUID
  • PURE_E_ZIP_DIRECTORY_COMPRESSED
  • PURE_E_ZIP_DIRECTORY_UNCOMPRESSED
  • PURE_E_ZIP_SYMLINK_COMPRESSED
  • PURE_E_ZIP_SYMLINK_LENGTH
  • PURE_E_ZIP_SYMLINK_CONTROL_CHARACTERS
  • PURE_E_ZIP_SYMLINK_TRAVERSAL_DRIVE_PATH
  • PURE_E_ZIP_SYMLINK_TRAVERSAL_RELATIVE_PATH
  • PURE_E_ZIP_SYMLINK_TRAVERSAL_DOUBLE_DOTS
  • PURE_E_ZIP_SYMLINK_COMPONENT_OVERFLOW
  • PURE_E_ZIP_STRING_MAX
  • PURE_E_ZIP_STRING_NULL_BYTE
  • PURE_E_ZIP_INFLATE
  • PURE_E_ZIP_INFLATE_DICTIONARY
  • PURE_E_ZIP_INFLATE_STREAM
  • PURE_E_ZIP_INFLATE_DATA
  • PURE_E_ZIP_INFLATE_MEMORY
  • PURE_E_ZIP_INFLATE_COMPRESSED_UNDERFLOW
  • PURE_E_ZIP_INFLATE_UNCOMPRESSED_UNDERFLOW
  • PURE_E_ZIP_AD_NIHILO
  • PURE_E_ZIP_EX_NIHILO
  • PURE_E_ZIP_CRC32
  • PURE_E_ZIP_EOCDL_64_OVERFLOW
  • PURE_E_ZIP_EOCDL_64_SIGNATURE
  • PURE_E_ZIP_EOCDL_64_NEGATIVE_OFFSET
  • PURE_E_ZIP_EOCDL_64_DISK
  • PURE_E_ZIP_EOCDL_64_DISKS
  • PURE_E_ZIP_EOCDR_64_OVERFLOW
  • PURE_E_ZIP_EOCDR_64_SIGNATURE
  • PURE_E_ZIP_EOCDR_EOCDL_64_OVERFLOW
  • PURE_E_ZIP_EOCDR_EOCDL_64_UNDERFLOW_ZEROED
  • PURE_E_ZIP_EOCDR_EOCDL_64_UNDERFLOW_BUFFER_BLEED
  • PURE_E_ZIP_DIFF_EOCDR_DISK
  • PURE_E_ZIP_DIFF_EOCDR_CD_DISK
  • PURE_E_ZIP_DIFF_EOCDR_CD_DISK_RECORDS
  • PURE_E_ZIP_DIFF_EOCDR_CD_RECORDS
  • PURE_E_ZIP_DIFF_EOCDR_CD_SIZE
  • PURE_E_ZIP_DIFF_EOCDR_CD_OFFSET
  • PURE_E_ZIP_EIEF_64_COMPRESSED_SIZE
  • PURE_E_ZIP_EIEF_64_DISK
  • PURE_E_ZIP_EIEF_64_RELATIVE_OFFSET
  • PURE_E_ZIP_EIEF_64_UNCOMPRESSED_SIZE
  • PURE_E_ZIP_EIEF_64_UNDERFLOW_ZEROED
  • PURE_E_ZIP_EIEF_64_UNDERFLOW_BUFFER_BLEED
  • PURE_E_ZIP_EIEF_64_LFH
  • PURE_E_ZIP_DIRECTORY_HAS_NO_LFH

...and this is only for zip files, we want to add static analysis for more file formats, please consider asking your company to sponsor open-source work on Pure.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pure-checker-2.1.tar.gz (36.5 kB view details)

Uploaded Source

Built Distributions

pure_checker-2.1-pp39-pypy39_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (28.6 kB view details)

Uploaded PyPy manylinux: glibc 2.27+ x86-64 manylinux: glibc 2.28+ x86-64

pure_checker-2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl (23.4 kB view details)

Uploaded PyPy macOS 10.9+ x86-64

pure_checker-2.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (59.2 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.27+ x86-64 manylinux: glibc 2.28+ x86-64

pure_checker-2.1-cp311-cp311-macosx_10_9_x86_64.whl (24.9 kB view details)

Uploaded CPython 3.11 macOS 10.9+ x86-64

pure_checker-2.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (59.2 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.27+ x86-64 manylinux: glibc 2.28+ x86-64

pure_checker-2.1-cp310-cp310-macosx_10_9_x86_64.whl (24.9 kB view details)

Uploaded CPython 3.10 macOS 10.9+ x86-64

pure_checker-2.1-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (59.1 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.27+ x86-64 manylinux: glibc 2.28+ x86-64

pure_checker-2.1-cp39-cp39-macosx_10_9_x86_64.whl (24.9 kB view details)

Uploaded CPython 3.9 macOS 10.9+ x86-64

File details

Details for the file pure-checker-2.1.tar.gz.

File metadata

  • Download URL: pure-checker-2.1.tar.gz
  • Upload date:
  • Size: 36.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.2

File hashes

Hashes for pure-checker-2.1.tar.gz
Algorithm Hash digest
SHA256 f691a68c978b77ee8aff34c28f6275b83f84f3db05c903771ff3122dc56c6b65
MD5 20819954b86dd3734762eed11ac57edc
BLAKE2b-256 31b7033a4f1d30ba9c39239d759dbea4bbfe2447579461b314836b04a5c3d721

See more details on using hashes here.

File details

Details for the file pure_checker-2.1-pp39-pypy39_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pure_checker-2.1-pp39-pypy39_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1599178da280d39da159ea8954971f49f6186147bba5d35d2f24bbf36c408f85
MD5 f2fa8cc5c99f8debb1ed99f76b1d53c9
BLAKE2b-256 3609415903a50d4814e24cc44d25860bb52a21b658a31de399b8d007aac0f24d

See more details on using hashes here.

File details

Details for the file pure_checker-2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for pure_checker-2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 635ac6d1b20e1983d6985ebfed011a381a9eb083d8b379b06c869e043ff6e024
MD5 3d026251fd6947191bb2811985693d09
BLAKE2b-256 e7db05e9f2123788560ab1a80979a105b29527838384b76473a66592e3f284bd

See more details on using hashes here.

File details

Details for the file pure_checker-2.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pure_checker-2.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c5aebef623cb5d76c2d0ce777b602aba6c360d2ee00a5c9bffb6ec09a8d2e0a8
MD5 b309717aa16f6ba79e39f6d9c6de8799
BLAKE2b-256 fd85447a946da0ba79e017fd75259655389f2e42c40b619d4831bd71862a69ee

See more details on using hashes here.

File details

Details for the file pure_checker-2.1-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for pure_checker-2.1-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 abd7866dbceaaa91108a513dd5b8ec3a1ec03cddf17f4de87cd3e7891f43b457
MD5 937fb059b3e37375bbdb8a4dd64e75e8
BLAKE2b-256 987ac8e99117e4c582a6c01b4285a5e14e4ad07631f5099be6986617ea9baa55

See more details on using hashes here.

File details

Details for the file pure_checker-2.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pure_checker-2.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f28c97223a4d357d5c281e2e1d5c3a28e0f4d7df3a59772b7128ab27c91481f5
MD5 7f79b7015214cd391b3ffad67309c923
BLAKE2b-256 dcd3921d4494cd8b2a4ef48cc04b7a74465deec2ab520bde725486922d07f235

See more details on using hashes here.

File details

Details for the file pure_checker-2.1-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for pure_checker-2.1-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 ec8d6054448ac8768d39a7b3011b91f0dbbf8a38f70a41f49c159454d6e68297
MD5 1c99ed5ee9be2be819bf6fd52ad9be2c
BLAKE2b-256 bdc065350c5d9641326c7bc1c39417a0c3663bb747e18f91e3ebf80ca6c37fc0

See more details on using hashes here.

File details

Details for the file pure_checker-2.1-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pure_checker-2.1-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 048b591b284930b4193b4bca6cf942e06c0a74f15636da8449968b2f8bece9e7
MD5 5c24196b6330022b0740749ece870fa5
BLAKE2b-256 1bf1bc20563c8fb91ee394ba99629396716fe3131203fba89c38510e4f5fff7d

See more details on using hashes here.

File details

Details for the file pure_checker-2.1-cp39-cp39-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for pure_checker-2.1-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 c8744a64587924608411d2188211bea348950b0e73c8899d907ad50e58bca3c4
MD5 875d629b49d61599d5a2b9f0bc2f938c
BLAKE2b-256 433df6bd4b3d20cd5793bc62ab2d23d034656bff10ab17bc44e32c7c480df213

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page